summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2017-04-25 15:06:40 +0200
committerHarald Welte <laforge@gnumonks.org>2017-04-25 15:06:40 +0200
commitcec90c77924e749911ccba6abdd0e4a32b9904e1 (patch)
treef085e8404e07251a05f4d3e56ba9bd4215e5254d
parent37304ea8d7f500aed5d00f47e4af694a42199628 (diff)
osmocon slides update
-rw-r--r--2017/bts_hardware-osmocon2017/bts_hardware.html4270
-rw-r--r--2017/open_source_mobilfunk-clt2017/running-foss-gsm.adoc2
-rw-r--r--2017/path_loss_link_budget-osmocon2017/path_loss_link_budget.html5039
-rw-r--r--2017/roadmap-osmocon2017/roadmap.html4448
-rw-r--r--2017/running_osmo_gsm-osmocon2017/Gsm_structures.svg15874
-rw-r--r--2017/running_osmo_gsm-osmocon2017/arch-sysmobts-allinone.dot27
-rw-r--r--2017/running_osmo_gsm-osmocon2017/arch-sysmobts.dot30
-rw-r--r--2017/running_osmo_gsm-osmocon2017/arch-usrp-allinone.dot30
-rw-r--r--2017/running_osmo_gsm-osmocon2017/arch-usrp.dot31
-rw-r--r--2017/running_osmo_gsm-osmocon2017/gprs_user_stack.svg1357
-rw-r--r--2017/running_osmo_gsm-osmocon2017/osmo-bts.svg342
-rw-r--r--2017/running_osmo_gsm-osmocon2017/osmocom-gprs.svg1191
-rw-r--r--2017/running_osmo_gsm-osmocon2017/osmocom-gsm.svg1980
-rw-r--r--2017/running_osmo_gsm-osmocon2017/running-osmo-gsm.adoc495
-rw-r--r--2017/running_osmo_gsm-osmocon2017/running-osmo-gsm.html5018
-rw-r--r--2017/welcome_intro-osmocon2017/welcome_intro.adoc8
-rw-r--r--2017/welcome_intro-osmocon2017/welcome_intro.html4205
17 files changed, 44344 insertions, 3 deletions
diff --git a/2017/bts_hardware-osmocon2017/bts_hardware.html b/2017/bts_hardware-osmocon2017/bts_hardware.html
new file mode 100644
index 0000000..5f0643f
--- /dev/null
+++ b/2017/bts_hardware-osmocon2017/bts_hardware.html
@@ -0,0 +1,4270 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>Osmocom BTS Hardware Support</title>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="copyright" content="Copyright &#169; 2017 by Harald Welte (License: CC-BY-SA)" />
+<meta name="generator" content="AsciiDoc 8.6.9" />
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+/* slidy.css
+
+ Copyright (c) 2005-2010 W3C (MIT, ERCIM, Keio), All Rights Reserved.
+ W3C liability, trademark, document use and software licensing
+ rules apply, see:
+
+ http://www.w3.org/Consortium/Legal/copyright-documents
+ http://www.w3.org/Consortium/Legal/copyright-software
+*/
+
+/*
+ SJR: 2010-09-29: Modified for AsciiDoc slidy backend.
+ Mostly just commented out stuff that is handled by AsciiDoc's CSS files.
+*/
+
+body
+{
+ margin: 0 0 0 0;
+ padding: 0 0 0 0;
+ width: 100%;
+ height: 100%;
+ color: black;
+ background-color: white;
+/*
+ font-family: "Gill Sans MT", "Gill Sans", GillSans, sans-serif;
+*/
+ font-size: 14pt;
+}
+
+div.toolbar {
+ position: fixed; z-index: 200;
+ top: auto; bottom: 0; left: 0; right: 0;
+ height: 1.2em; text-align: right;
+ padding-left: 1em;
+ padding-right: 1em;
+ font-size: 60%;
+ color: red;
+ background-color: rgb(240,240,240);
+ border-top: solid 1px rgb(180,180,180);
+}
+
+div.toolbar span.copyright {
+ color: black;
+ margin-left: 0.5em;
+}
+
+div.initial_prompt {
+ position: absolute;
+ z-index: 1000;
+ bottom: 1.2em;
+ width: 90%;
+ background-color: rgb(200,200,200);
+ opacity: 0.35;
+ background-color: rgb(200,200,200, 0.35);
+ cursor: pointer;
+}
+
+div.initial_prompt p.help {
+ text-align: center;
+}
+
+div.initial_prompt p.close {
+ text-align: right;
+ font-style: italic;
+}
+
+div.slidy_toc {
+ position: absolute;
+ z-index: 300;
+ width: 60%;
+ max-width: 30em;
+ height: 30em;
+ overflow: auto;
+ top: auto;
+ right: auto;
+ left: 4em;
+ bottom: 4em;
+ padding: 1em;
+ background: rgb(240,240,240);
+ border-style: solid;
+ border-width: 2px;
+ font-size: 60%;
+}
+
+div.slidy_toc .toc_heading {
+ text-align: center;
+ width: 100%;
+ margin: 0;
+ margin-bottom: 1em;
+ border-bottom-style: solid;
+ border-bottom-color: rgb(180,180,180);
+ border-bottom-width: 1px;
+}
+
+div.slide {
+ z-index: 20;
+ margin: 0 0 0 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ padding-left: 20px;
+ padding-right: 20px;
+ border-width: 0;
+ clear: both;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ line-height: 120%;
+ background-color: transparent;
+}
+
+div.background {
+ display: none;
+}
+
+div.handout {
+ margin-left: 20px;
+ margin-right: 20px;
+}
+
+div.slide.titlepage {
+ text-align: center;
+}
+
+div.slide.titlepage.h1 {
+ padding-top: 10%;
+}
+
+div.slide h1 {
+ padding-left: 0;
+ padding-right: 20pt;
+ padding-top: 4pt;
+ padding-bottom: 4pt;
+ margin-top: 0;
+ margin-left: 0;
+ margin-right: 60pt;
+ margin-bottom: 0.5em;
+ display: block;
+ font-size: 160%;
+ line-height: 1.2em;
+ background: transparent;
+}
+
+div.toc {
+ position: absolute;
+ top: auto;
+ bottom: 4em;
+ left: 4em;
+ right: auto;
+ width: 60%;
+ max-width: 30em;
+ height: 30em;
+ border: solid thin black;
+ padding: 1em;
+ background: rgb(240,240,240);
+ color: black;
+ z-index: 300;
+ overflow: auto;
+ display: block;
+ visibility: visible;
+}
+
+div.toc-heading {
+ width: 100%;
+ border-bottom: solid 1px rgb(180,180,180);
+ margin-bottom: 1em;
+ text-align: center;
+}
+
+/*
+pre {
+ font-size: 80%;
+ font-weight: bold;
+ line-height: 120%;
+ padding-top: 0.2em;
+ padding-bottom: 0.2em;
+ padding-left: 1em;
+ padding-right: 1em;
+ border-style: solid;
+ border-left-width: 1em;
+ border-top-width: thin;
+ border-right-width: thin;
+ border-bottom-width: thin;
+ border-color: #95ABD0;
+ color: #00428C;
+ background-color: #E4E5E7;
+}
+*/
+
+/*
+li pre { margin-left: 0; }
+
+blockquote { font-style: italic }
+
+img { background-color: transparent }
+
+p.copyright { font-size: smaller }
+*/
+
+.center { text-align: center }
+.footnote { font-size: smaller; margin-left: 2em; }
+
+/*
+a img { border-width: 0; border-style: none }
+*/
+
+a:visited { color: navy }
+a:link { color: navy }
+a:hover { color: red; text-decoration: underline }
+a:active { color: red; text-decoration: underline }
+
+a {text-decoration: none}
+.navbar a:link {color: white}
+.navbar a:visited {color: yellow}
+.navbar a:active {color: red}
+.navbar a:hover {color: red}
+
+/*
+ul { list-style-type: square; }
+ul ul { list-style-type: disc; }
+ul ul ul { list-style-type: circle; }
+ul ul ul ul { list-style-type: disc; }
+li { margin-left: 0.5em; margin-top: 0.5em; }
+li li { font-size: 85%; font-style: italic }
+li li li { font-size: 85%; font-style: normal }
+*/
+
+div dt
+{
+ margin-left: 0;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+ font-weight: bold;
+}
+div dd
+{
+ margin-left: 2em;
+ margin-bottom: 0.5em;
+}
+
+
+/*
+p,pre,ul,ol,blockquote,h2,h3,h4,h5,h6,dl,table {
+ margin-left: 1em;
+ margin-right: 1em;
+}
+*/
+
+p.subhead { font-weight: bold; margin-top: 2em; }
+
+.smaller { font-size: smaller }
+.bigger { font-size: 130% }
+
+/*
+td,th { padding: 0.2em }
+*/
+
+ul {
+ margin: 0.5em 1.5em 0.5em 1.5em;
+ padding: 0;
+}
+
+ol {
+ margin: 0.5em 1.5em 0.5em 1.5em;
+ padding: 0;
+}
+
+ul { list-style-type: square; }
+ul ul { list-style-type: disc; }
+ul ul ul { list-style-type: circle; }
+ul ul ul ul { list-style-type: disc; }
+
+/*
+ul li {
+ list-style: square;
+ margin: 0.1em 0em 0.6em 0;
+ padding: 0 0 0 0;
+ line-height: 140%;
+}
+
+ol li {
+ margin: 0.1em 0em 0.6em 1.5em;
+ padding: 0 0 0 0px;
+ line-height: 140%;
+ list-style-type: decimal;
+}
+
+li ul li {
+ font-size: 85%;
+ font-style: italic;
+ list-style-type: disc;
+ background: transparent;
+ padding: 0 0 0 0;
+}
+li li ul li {
+ font-size: 85%;
+ font-style: normal;
+ list-style-type: circle;
+ background: transparent;
+ padding: 0 0 0 0;
+}
+li li li ul li {
+ list-style-type: disc;
+ background: transparent;
+ padding: 0 0 0 0;
+}
+
+li ol li {
+ list-style-type: decimal;
+}
+
+
+li li ol li {
+ list-style-type: decimal;
+}
+*/
+
+/*
+ setting class="outline" on ol or ul makes it behave as an
+ ouline list where blocklevel content in li elements is
+ hidden by default and can be expanded or collapsed with
+ mouse click. Set class="expand" on li to override default
+*/
+
+ol.outline li:hover { cursor: pointer }
+ol.outline li.nofold:hover { cursor: default }
+
+ul.outline li:hover { cursor: pointer }
+ul.outline li.nofold:hover { cursor: default }
+
+ol.outline { list-style:decimal; }
+ol.outline ol { list-style-type:lower-alpha }
+
+ol.outline li.nofold {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/nofold-dim.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.unfolded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold-dim.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.folded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold-dim.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.unfolded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.folded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold.gif) no-repeat 0px 0.5em;
+}
+
+ul.outline li.nofold {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/nofold-dim.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.unfolded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold-dim.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.folded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold-dim.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.unfolded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.folded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold.gif) no-repeat 0px 0.5em;
+}
+
+/* for slides with class "title" in table of contents */
+a.titleslide { font-weight: bold; font-style: italic }
+
+/*
+ hide images for work around for save as bug
+ where browsers fail to save images used by CSS
+*/
+img.hidden { display: none; visibility: hidden }
+div.initial_prompt { display: none; visibility: hidden }
+
+ div.slide {
+ visibility: visible;
+ position: inherit;
+ }
+ div.handout {
+ border-top-style: solid;
+ border-top-width: thin;
+ border-top-color: black;
+ }
+
+@media screen {
+ .hidden { display: none; visibility: visible }
+
+ div.slide.hidden { display: block; visibility: visible }
+ div.handout.hidden { display: block; visibility: visible }
+ div.background { display: none; visibility: hidden }
+ body.single_slide div.initial_prompt { display: block; visibility: visible }
+ body.single_slide div.background { display: block; visibility: visible }
+ body.single_slide div.background.hidden { display: none; visibility: hidden }
+ body.single_slide .invisible { visibility: hidden }
+ body.single_slide .hidden { display: none; visibility: hidden }
+ body.single_slide div.slide { position: absolute }
+ body.single_slide div.handout { display: none; visibility: hidden }
+}
+
+@media print {
+ .hidden { display: block; visibility: visible }
+
+/*
+ div.slide pre { font-size: 60%; padding-left: 0.5em; }
+*/
+ div.toolbar { display: none; visibility: hidden; }
+ div.slidy_toc { display: none; visibility: hidden; }
+ div.background { display: none; visibility: hidden; }
+ div.slide { page-break-before: always }
+ /* :first-child isn't reliable for print media */
+ div.slide.first-slide { page-break-before: avoid }
+}
+
+
+/* SJR: AsciiDoc slidy backend tweaks */
+
+ol, ul {
+ margin: 0.8em 1.5em 0.8em 1.8em;
+}
+li > ul, li > ol {
+ margin-top: 0.5em;
+}
+
+.outline > li.folded,
+.outline > li.unfolded {
+ color: #527bbd;
+}
+ul > li{ color: #aaa; }
+ul > li > *, ol > li > * { color: black; }
+
+li {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+
+div.change_topic {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+div.change_topic h1 {
+ text-align: center;
+ border-bottom-width: 0px;
+}
+
+div.gimmick_right img {
+ float: right;
+}
+
+div.qanda ol {
+ list-style-type: none;
+}
+
+.monospaced, code, pre {
+ color: black;
+ font-weight: bold;
+}
+
+div.quoteblock, div.verseblock {
+ color: black;
+}
+
+em {
+ color: black;
+}
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+/* slidy.js
+
+ Copyright (c) 2005-2010 W3C (MIT, ERCIM, Keio), All Rights Reserved.
+ W3C liability, trademark, document use and software licensing
+ rules apply, see:
+
+ http://www.w3.org/Consortium/Legal/copyright-documents
+ http://www.w3.org/Consortium/Legal/copyright-software
+*/
+
+// the slidy object implementation
+var w3c_slidy = {
+ // classify which kind of browser we're running under
+ ns_pos: (typeof window.pageYOffset!='undefined'),
+ khtml: ((navigator.userAgent).indexOf("KHTML") >= 0 ? true : false),
+ opera: ((navigator.userAgent).indexOf("Opera") >= 0 ? true : false),
+ ipad: ((navigator.userAgent).indexOf("iPad") >= 0 ? true : false),
+ iphone: ((navigator.userAgent).indexOf("iPhone") >= 0 ? true : false),
+ ie: (typeof document.all != "undefined" && !this.opera),
+ ie6: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 6") != -1),
+ ie7: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 7") != -1),
+ ie8: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 8") != -1),
+ ie9: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 9") != -1),
+ keyboardless: (this.ipad || this.iphone),
+
+ // are we running as XHTML? (doesn't work on Opera)
+ is_xhtml: /xml/.test(document.contentType),
+
+ slide_number: 0, // integer slide count: 0, 1, 2, ...
+ slide_number_element: null, // element containing slide number
+ slides: [], // set to array of slide div's
+ notes: [], // set to array of handout div's
+ backgrounds: [], // set to array of background div's
+ toolbar: null, // element containing toolbar
+ title: null, // document title
+ last_shown: null, // last incrementally shown item
+ eos: null, // span element for end of slide indicator
+ toc: null, // table of contents
+ outline: null, // outline element with the focus
+ selected_text_len: 0, // length of drag selection on document
+ view_all: 0, // 1 to view all slides + handouts
+ want_toolbar: true, // user preference to show/hide toolbar
+ mouse_click_enabled: true, // enables left click for next slide
+ scroll_hack: 0, // IE work around for position: fixed
+ disable_slide_click: false, // used by clicked anchors
+
+ lang: "en", // updated to language specified by html file
+
+ help_anchor: null, // used for keyboard focus hack in showToolbar()
+ help_page: "http://www.w3.org/Talks/Tools/Slidy2/help/help.html",
+ help_text: "Navigate with mouse click, space bar, Cursor Left/Right, " +
+ "or Pg Up and Pg Dn. Use S and B to change font size.",
+
+ size_index: 0,
+ size_adjustment: 0,
+ sizes: new Array("10pt", "12pt", "14pt", "16pt", "18pt", "20pt",
+ "22pt", "24pt", "26pt", "28pt", "30pt", "32pt"),
+
+ // needed for efficient resizing
+ last_width: 0,
+ last_height: 0,
+
+
+ // Needed for cross browser support for relative width/height on
+ // object elements. The work around is to save width/height attributes
+ // and then to recompute absolute width/height dimensions on resizing
+ objects: [],
+
+ // attach initialiation event handlers
+ set_up: function () {
+ var init = function() { w3c_slidy.init(); };
+ if (typeof window.addEventListener != "undefined")
+ window.addEventListener("load", init, false);
+ else
+ window.attachEvent("onload", init);
+ },
+
+ hide_slides: function () {
+ if (document.body && !w3c_slidy.initialized)
+ document.body.style.visibility = "hidden";
+ else
+ setTimeout(w3c_slidy.hide_slides, 50);
+ },
+
+ // hack to persuade IE to compute correct document height
+ // as needed for simulating fixed positioning of toolbar
+ ie_hack: function () {
+ window.resizeBy(0,-1);
+ window.resizeBy(0, 1);
+ },
+
+ init: function () {
+ //alert("slidy starting test 10");
+ document.body.style.visibility = "visible";
+ w3c_slidy_i18n.init();
+ this.add_toolbar();
+ this.wrap_implicit_slides();
+ this.collect_slides();
+ this.collect_notes();
+ this.collect_backgrounds();
+ this.objects = document.body.getElementsByTagName("object");
+ this.patch_anchors();
+ this.slide_number = this.find_slide_number(location.href);
+ window.offscreenbuffering = true;
+ this.size_adjustment = this.find_size_adjust();
+ this.time_left = this.find_duration();
+ this.hide_image_toolbar(); // suppress IE image toolbar popup
+ this.init_outliner(); // activate fold/unfold support
+ this.title = document.title;
+
+ // work around for opera bug
+ this.is_xhtml = (document.body.tagName == "BODY" ? false : true);
+
+ if (this.slides.length > 0)
+ {
+ var slide = this.slides[this.slide_number];
+
+ if (this.slide_number > 0)
+ {
+ this.set_visibility_all_incremental("visible");
+ this.last_shown = this.previous_incremental_item(null);
+ this.set_eos_status(true);
+ }
+ else
+ {
+ this.last_shown = null;
+ this.set_visibility_all_incremental("hidden");
+ this.set_eos_status(!this.next_incremental_item(this.last_shown));
+ }
+
+ this.set_location();
+ this.add_class(this.slides[0], "first-slide");
+ w3c_slidy.show_slide(slide);
+ }
+
+ this.toc = this.table_of_contents();
+
+ this.add_initial_prompt();
+
+ // bind event handlers without interfering with custom page scripts
+ // Tap events behave too weirdly to support clicks reliably on
+ // iPhone and iPad, so exclude these from click handler
+
+ if (!this.keyboardless)
+ this.add_listener(document.body, "click", this.mouse_button_click);
+
+ this.add_listener(document, "keydown", this.key_down);
+ this.add_listener(document, "keypress", this.key_press);
+ this.add_listener(window, "resize", this.resized);
+ this.add_listener(window, "scroll", this.scrolled);
+ this.add_listener(window, "unload", this.unloaded);
+
+ if (!document.body.onclick)
+ document.body.onclick = function () { };
+
+ this.single_slide_view();
+
+ //this.set_location();
+
+ this.resized();
+
+ if (this.ie7)
+ setTimeout(w3c_slidy.ie_hack, 100);
+
+ this.show_toolbar();
+
+ // for back button detection
+ setInterval(function () { w3c_slidy.check_location(); }, 200);
+ w3c_slidy.initialized = true;
+ },
+
+ // create div element with links to each slide
+ table_of_contents: function () {
+ var toc = this.create_element("div");
+ this.add_class(toc, "slidy_toc hidden");
+ //toc.setAttribute("tabindex", "0");
+
+ var heading = this.create_element("div");
+ this.add_class(heading, "toc-heading");
+ heading.innerHTML = "Table of Contents".localize();
+
+ toc.appendChild(heading);
+ var previous = null;
+
+ for (var i = 0; i < this.slides.length; ++i)
+ {
+ var title = this.has_class(this.slides[i], "title");
+ var num = document.createTextNode((i + 1) + ". ");
+
+ toc.appendChild(num);
+
+ var a = this.create_element("a");
+ a.setAttribute("href", "#(" + (i+1) + ")");
+
+ if (title)
+ this.add_class(a, "titleslide");
+
+ var name = document.createTextNode(this.slide_name(i));
+ a.appendChild(name);
+ a.onclick = w3c_slidy.toc_click;
+ a.onkeydown = w3c_slidy.toc_keydown;
+ a.previous = previous;
+
+ if (previous)
+ previous.next = a;
+
+ toc.appendChild(a);
+
+ if (i == 0)
+ toc.first = a;
+
+ if (i < this.slides.length - 1)
+ {
+ var br = this.create_element("br");
+ toc.appendChild(br);
+ }
+
+ previous = a;
+ }
+
+ toc.focus = function () {
+ if (this.first)
+ this.first.focus();
+ }
+
+ toc.onmouseup = w3c_slidy.mouse_button_up;
+
+ toc.onclick = function (e) {
+ e||(e=window.event);
+
+ if (w3c_slidy.selected_text_len <= 0)
+ w3c_slidy.hide_table_of_contents();
+
+ w3c_slidy.stop_propagation(e);
+
+ if (e.cancel != undefined)
+ e.cancel = true;
+
+ if (e.returnValue != undefined)
+ e.returnValue = false;
+
+ return false;
+ };
+
+ document.body.insertBefore(toc, document.body.firstChild);
+ return toc;
+ },
+
+ is_shown_toc: function () {
+ return !w3c_slidy.has_class(w3c_slidy.toc, "hidden");
+ },
+
+ show_table_of_contents: function () {
+ w3c_slidy.remove_class(w3c_slidy.toc, "hidden");
+ var toc = w3c_slidy.toc;
+ toc.focus();
+
+ if (w3c_slidy.ie7 && w3c_slidy.slide_number == 0)
+ setTimeout(w3c_slidy.ie_hack, 100);
+ },
+
+ hide_table_of_contents: function () {
+ w3c_slidy.add_class(w3c_slidy.toc, "hidden");
+
+ if (!w3c_slidy.opera)
+ w3c_slidy.help_anchor.focus();
+ },
+
+ toggle_table_of_contents: function () {
+ if (w3c_slidy.is_shown_toc())
+ w3c_slidy.hide_table_of_contents();
+ else
+ w3c_slidy.show_table_of_contents();
+ },
+
+ // called on clicking toc entry
+ toc_click: function (e) {
+ if (!e)
+ e = window.event;
+
+ var target = w3c_slidy.get_target(e);
+
+ if (target && target.nodeType == 1)
+ {
+ var uri = target.getAttribute("href");
+
+ if (uri)
+ {
+ //alert("going to " + uri);
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.slide_number = w3c_slidy.find_slide_number(uri);
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_location();
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+ w3c_slidy.show_slide(slide);
+ //target.focus();
+
+ try
+ {
+ if (!w3c_slidy.opera)
+ w3c_slidy.help_anchor.focus();
+ }
+ catch (e)
+ {
+ }
+ }
+ }
+
+ w3c_slidy.hide_table_of_contents(e);
+ if (w3c_slidy.ie7) w3c_slidy.ie_hack();
+ w3c_slidy.stop_propagation(e);
+ return w3c_slidy.cancel(e);
+ },
+
+ // called onkeydown for toc entry
+ toc_keydown: function (event) {
+ var key;
+
+ if (!event)
+ var event = window.event;
+
+ // kludge around NS/IE differences
+ if (window.event)
+ key = window.event.keyCode;
+ else if (event.which)
+ key = event.which;
+ else
+ return true; // Yikes! unknown browser
+
+ // ignore event if key value is zero
+ // as for alt on Opera and Konqueror
+ if (!key)
+ return true;
+
+ // check for concurrent control/command/alt key
+ // but are these only present on mouse events?
+
+ if (event.ctrlKey || event.altKey)
+ return true;
+
+ if (key == 13)
+ {
+ var uri = this.getAttribute("href");
+
+ if (uri)
+ {
+ //alert("going to " + uri);
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.slide_number = w3c_slidy.find_slide_number(uri);
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_location();
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+ w3c_slidy.show_slide(slide);
+ //target.focus();
+
+ try
+ {
+ if (!w3c_slidy.opera)
+ w3c_slidy.help_anchor.focus();
+ }
+ catch (e)
+ {
+ }
+ }
+
+ w3c_slidy.hide_table_of_contents();
+
+ if (self.ie7)
+ w3c_slidy.ie_hack();
+
+ return w3c_slidy.cancel(event);
+ }
+
+ if (key == 40 && this.next)
+ {
+ this.next.focus();
+ return w3c_slidy.cancel(event);
+ }
+
+ if (key == 38 && this.previous)
+ {
+ this.previous.focus();
+ return w3c_slidy.cancel(event);
+ }
+
+ return true;
+ },
+
+
+ // ### OBSOLETE ###
+ before_print: function () {
+ this.show_all_slides();
+ this.hide_toolbar();
+ alert("before print");
+ },
+
+ // ### OBSOLETE ###
+ after_print: function () {
+ if (!this.view_all)
+ {
+ this.single_slide_view();
+ this.show_toolbar();
+ }
+ alert("after print");
+ },
+
+ // ### OBSOLETE ###
+ print_slides: function () {
+ this.before_print();
+ window.print();
+ this.after_print();
+ },
+
+ // ### OBSOLETE ?? ###
+ toggle_view: function () {
+ if (this.view_all)
+ {
+ this.single_slide_view();
+ this.show_toolbar();
+ this.view_all = 0;
+ }
+ else
+ {
+ this.show_all_slides();
+ this.hide_toolbar();
+ this.view_all = 1;
+ }
+ },
+
+ // prepare for printing ### OBSOLETE ###
+ show_all_slides: function () {
+ this.remove_class(document.body, "single_slide");
+ this.set_visibility_all_incremental("visible");
+ },
+
+ // restore after printing ### OBSOLETE ###
+ single_slide_view: function () {
+ this.add_class(document.body, "single_slide");
+ this.set_visibility_all_incremental("visible");
+ this.last_shown = this.previous_incremental_item(null);
+ },
+
+ // suppress IE's image toolbar pop up
+ hide_image_toolbar: function () {
+ if (!this.ns_pos)
+ {
+ var images = document.getElementsByTagName("IMG");
+
+ for (var i = 0; i < images.length; ++i)
+ images[i].setAttribute("galleryimg", "no");
+ }
+ },
+
+ unloaded: function (e) {
+ //alert("unloaded");
+ },
+
+ // Safari and Konqueror don't yet support getComputedStyle()
+ // and they always reload page when location.href is updated
+ is_KHTML: function () {
+ var agent = navigator.userAgent;
+ return (agent.indexOf("KHTML") >= 0 ? true : false);
+ },
+
+ // find slide name from first h1 element
+ // default to document title + slide number
+ slide_name: function (index) {
+ var name = null;
+ var slide = this.slides[index];
+
+ var heading = this.find_heading(slide);
+
+ if (heading)
+ name = this.extract_text(heading);
+
+ if (!name)
+ name = this.title + "(" + (index + 1) + ")";
+
+ name.replace(/\&/g, "&amp;");
+ name.replace(/\</g, "&lt;");
+ name.replace(/\>/g, "&gt;");
+
+ return name;
+ },
+
+ // find first h1 element in DOM tree
+ find_heading: function (node) {
+ if (!node || node.nodeType != 1)
+ return null;
+
+ if (node.nodeName == "H1" || node.nodeName == "h1")
+ return node;
+
+ var child = node.firstChild;
+
+ while (child)
+ {
+ node = this.find_heading(child);
+
+ if (node)
+ return node;
+
+ child = child.nextSibling;
+ }
+
+ return null;
+ },
+
+ // recursively extract text from DOM tree
+ extract_text: function (node) {
+ if (!node)
+ return "";
+
+ // text nodes
+ if (node.nodeType == 3)
+ return node.nodeValue;
+
+ // elements
+ if (node.nodeType == 1)
+ {
+ node = node.firstChild;
+ var text = "";
+
+ while (node)
+ {
+ text = text + this.extract_text(node);
+ node = node.nextSibling;
+ }
+
+ return text;
+ }
+
+ return "";
+ },
+
+ // find copyright text from meta element
+ find_copyright: function () {
+ var name, content;
+ var meta = document.getElementsByTagName("meta");
+
+ for (var i = 0; i < meta.length; ++i)
+ {
+ name = meta[i].getAttribute("name");
+ content = meta[i].getAttribute("content");
+
+ if (name == "copyright")
+ return content;
+ }
+
+ return null;
+ },
+
+ find_size_adjust: function () {
+ var name, content, offset;
+ var meta = document.getElementsByTagName("meta");
+
+ for (var i = 0; i < meta.length; ++i)
+ {
+ name = meta[i].getAttribute("name");
+ content = meta[i].getAttribute("content");
+
+ if (name == "font-size-adjustment")
+ return 1 * content;
+ }
+
+ return 1;
+ },
+
+ // <meta name="duration" content="20" /> for 20 minutes
+ find_duration: function () {
+ var name, content, offset;
+ var meta = document.getElementsByTagName("meta");
+
+ for (var i = 0; i < meta.length; ++i)
+ {
+ name = meta[i].getAttribute("name");
+ content = meta[i].getAttribute("content");
+
+ if (name == "duration")
+ return 60000 * content;
+ }
+
+ return null;
+ },
+
+ replace_by_non_breaking_space: function (str) {
+ for (var i = 0; i < str.length; ++i)
+ str[i] = 160;
+ },
+
+ // ### CHECK ME ### is use of "li" okay for text/html?
+ // for XHTML do we also need to specify namespace?
+ init_outliner: function () {
+ var items = document.getElementsByTagName("li");
+
+ for (var i = 0; i < items.length; ++i)
+ {
+ var target = items[i];
+
+ if (!this.has_class(target.parentNode, "outline"))
+ continue;
+
+ target.onclick = this.outline_click;
+/* ### more work needed for IE6
+ if (!this.ns_pos)
+ {
+ target.onmouseover = this.hover_outline;
+ target.onmouseout = this.unhover_outline;
+ }
+*/
+ if (this.foldable(target))
+ {
+ target.foldable = true;
+ target.onfocus = function () {w3c_slidy.outline = this;};
+ target.onblur = function () {w3c_slidy.outline = null;};
+
+ if (!target.getAttribute("tabindex"))
+ target.setAttribute("tabindex", "0");
+
+ if (this.has_class(target, "expand"))
+ this.unfold(target);
+ else
+ this.fold(target);
+ }
+ else
+ {
+ this.add_class(target, "nofold");
+ target.visible = true;
+ target.foldable = false;
+ }
+ }
+ },
+
+ foldable: function (item) {
+ if (!item || item.nodeType != 1)
+ return false;
+
+ var node = item.firstChild;
+
+ while (node)
+ {
+ if (node.nodeType == 1 && this.is_block(node))
+ return true;
+
+ node = node.nextSibling;
+ }
+
+ return false;
+ },
+
+ // ### CHECK ME ### switch to add/remove "hidden" class
+ fold: function (item) {
+ if (item)
+ {
+ this.remove_class(item, "unfolded");
+ this.add_class(item, "folded");
+ }
+
+ var node = item ? item.firstChild : null;
+
+ while (node)
+ {
+ if (node.nodeType == 1 && this.is_block(node)) // element
+ {
+ w3c_slidy.add_class(node, "hidden");
+ }
+
+ node = node.nextSibling;
+ }
+
+ item.visible = false;
+ },
+
+ // ### CHECK ME ### switch to add/remove "hidden" class
+ unfold: function (item) {
+ if (item)
+ {
+ this.add_class(item, "unfolded");
+ this.remove_class(item, "folded");
+ }
+
+ var node = item ? item.firstChild : null;
+
+ while (node)
+ {
+ if (node.nodeType == 1 && this.is_block(node)) // element
+ {
+ w3c_slidy.remove_class(node, "hidden");
+ }
+
+ node = node.nextSibling;
+ }
+
+ item.visible = true;
+ },
+
+ outline_click: function (e) {
+ if (!e)
+ e = window.event;
+
+ var rightclick = false;
+ var target = w3c_slidy.get_target(e);
+
+ while (target && target.visible == undefined)
+ target = target.parentNode;
+
+ if (!target)
+ return true;
+
+ if (e.which)
+ rightclick = (e.which == 3);
+ else if (e.button)
+ rightclick = (e.button == 2);
+
+ if (!rightclick && target.visible != undefined)
+ {
+ if (target.foldable)
+ {
+ if (target.visible)
+ w3c_slidy.fold(target);
+ else
+ w3c_slidy.unfold(target);
+ }
+
+ w3c_slidy.stop_propagation(e);
+ e.cancel = true;
+ e.returnValue = false;
+ }
+
+ return false;
+ },
+
+ add_initial_prompt: function () {
+ var prompt = this.create_element("div");
+ prompt.setAttribute("class", "initial_prompt");
+
+ var p1 = this.create_element("p");
+ prompt.appendChild(p1);
+ p1.setAttribute("class", "help");
+
+ if (this.keyboardless)
+ p1.innerHTML = "Tap footer to move to next slide";
+ else
+ p1.innerHTML = "Space or Right Arrow to move to next " +
+ "slide, click help below for more details";
+
+ this.add_listener(prompt, "click", function (e) {
+ document.body.removeChild(prompt);
+ w3c_slidy.stop_propagation(e);
+
+ if (e.cancel != undefined)
+ e.cancel = true;
+
+ if (e.returnValue != undefined)
+ e.returnValue = false;
+
+ return false;
+ });
+
+ document.body.appendChild(prompt);
+ this.initial_prompt = prompt;
+ setTimeout(function() {document.body.removeChild(prompt);}, 5000);
+ },
+
+ add_toolbar: function () {
+ var counter, page;
+
+ this.toolbar = this.create_element("div");
+ this.toolbar.setAttribute("class", "toolbar");
+
+ // a reasonably behaved browser
+ if (this.ns_pos || !this.ie6)
+ {
+ var right = this.create_element("div");
+ right.setAttribute("style", "float: right; text-align: right");
+
+ counter = this.create_element("span")
+ counter.innerHTML = "slide".localize() + " n/m";
+ right.appendChild(counter);
+ this.toolbar.appendChild(right);
+
+ var left = this.create_element("div");
+ left.setAttribute("style", "text-align: left");
+
+ // global end of slide indicator
+ this.eos = this.create_element("span");
+ this.eos.innerHTML = "* ";
+ left.appendChild(this.eos);
+
+ var help = this.create_element("a");
+ help.setAttribute("href", this.help_page);
+ help.setAttribute("title", this.help_text.localize());
+ help.innerHTML = "help?".localize();
+ left.appendChild(help);
+ this.help_anchor = help; // save for focus hack
+
+ var gap1 = document.createTextNode(" ");
+ left.appendChild(gap1);
+
+ var contents = this.create_element("a");
+ contents.setAttribute("href", "javascript:w3c_slidy.toggle_table_of_contents()");
+ contents.setAttribute("title", "table of contents".localize());
+ contents.innerHTML = "contents?".localize();
+ left.appendChild(contents);
+
+ var gap2 = document.createTextNode(" ");
+ left.appendChild(gap2);
+
+ var copyright = this.find_copyright();
+
+ if (copyright)
+ {
+ var span = this.create_element("span");
+ span.className = "copyright";
+ span.innerHTML = copyright;
+ left.appendChild(span);
+ }
+
+ this.toolbar.setAttribute("tabindex", "0");
+ this.toolbar.appendChild(left);
+ }
+ else // IE6 so need to work around its poor CSS support
+ {
+ this.toolbar.style.position = (this.ie7 ? "fixed" : "absolute");
+ this.toolbar.style.zIndex = "200";
+ this.toolbar.style.width = "99.9%";
+ this.toolbar.style.height = "1.2em";
+ this.toolbar.style.top = "auto";
+ this.toolbar.style.bottom = "0";
+ this.toolbar.style.left = "0";
+ this.toolbar.style.right = "0";
+ this.toolbar.style.textAlign = "left";
+ this.toolbar.style.fontSize = "60%";
+ this.toolbar.style.color = "red";
+ this.toolbar.borderWidth = 0;
+ this.toolbar.className = "toolbar";
+ this.toolbar.style.background = "rgb(240,240,240)";
+
+ // would like to have help text left aligned
+ // and page counter right aligned, floating
+ // div's don't work, so instead use nested
+ // absolutely positioned div's.
+
+ var sp = this.create_element("span");
+ sp.innerHTML = "&nbsp;&nbsp;*&nbsp;";
+ this.toolbar.appendChild(sp);
+ this.eos = sp; // end of slide indicator
+
+ var help = this.create_element("a");
+ help.setAttribute("href", this.help_page);
+ help.setAttribute("title", this.help_text.localize());
+ help.innerHTML = "help?".localize();
+ this.toolbar.appendChild(help);
+ this.help_anchor = help; // save for focus hack
+
+ var gap1 = document.createTextNode(" ");
+ this.toolbar.appendChild(gap1);
+
+ var contents = this.create_element("a");
+ contents.setAttribute("href", "javascript:toggleTableOfContents()");
+ contents.setAttribute("title", "table of contents".localize());
+ contents.innerHTML = "contents?".localize();
+ this.toolbar.appendChild(contents);
+
+ var gap2 = document.createTextNode(" ");
+ this.toolbar.appendChild(gap2);
+
+ var copyright = this.find_copyright();
+
+ if (copyright)
+ {
+ var span = this.create_element("span");
+ span.innerHTML = copyright;
+ span.style.color = "black";
+ span.style.marginLeft = "0.5em";
+ this.toolbar.appendChild(span);
+ }
+
+ counter = this.create_element("div")
+ counter.style.position = "absolute";
+ counter.style.width = "auto"; //"20%";
+ counter.style.height = "1.2em";
+ counter.style.top = "auto";
+ counter.style.bottom = 0;
+ counter.style.right = "0";
+ counter.style.textAlign = "right";
+ counter.style.color = "red";
+ counter.style.background = "rgb(240,240,240)";
+
+ counter.innerHTML = "slide".localize() + " n/m";
+ this.toolbar.appendChild(counter);
+ }
+
+ // ensure that click isn't passed through to the page
+ this.toolbar.onclick =
+ function (e) {
+ if (!e)
+ e = window.event;
+
+ var target = e.target;
+
+ if (!target && e.srcElement)
+ target = e.srcElement;
+
+ // work around Safari bug
+ if (target && target.nodeType == 3)
+ target = target.parentNode;
+
+ w3c_slidy.stop_propagation(e);
+
+ if (target && target.nodeName.toLowerCase() != "a")
+ w3c_slidy.mouse_button_click(e);
+ };
+
+ this.slide_number_element = counter;
+ this.set_eos_status(false);
+ document.body.appendChild(this.toolbar);
+ },
+
+ // wysiwyg editors make it hard to use div elements
+ // e.g. amaya loses the div when you copy and paste
+ // this function wraps div elements around implicit
+ // slides which start with an h1 element and continue
+ // up to the next heading or div element
+ wrap_implicit_slides: function () {
+ var i, heading, node, next, div;
+ var headings = document.getElementsByTagName("h1");
+
+ if (!headings)
+ return;
+
+ for (i = 0; i < headings.length; ++i)
+ {
+ heading = headings[i];
+
+ if (heading.parentNode != document.body)
+ continue;
+
+ node = heading.nextSibling;
+
+ div = document.createElement("div");
+ this.add_class(div, "slide");
+ document.body.replaceChild(div, heading);
+ div.appendChild(heading);
+
+ while (node)
+ {
+ if (node.nodeType == 1 && // an element
+ (node.nodeName == "H1" ||
+ node.nodeName == "h1" ||
+ node.nodeName == "DIV" ||
+ node.nodeName == "div"))
+ break;
+
+ next = node.nextSibling;
+ node = document.body.removeChild(node);
+ div.appendChild(node);
+ node = next;
+ }
+ }
+ },
+
+// return new array of all slides
+ collect_slides: function () {
+ var slides = new Array();
+ var divs = document.body.getElementsByTagName("div");
+
+ for (var i = 0; i < divs.length; ++i)
+ {
+ div = divs.item(i);
+
+ if (this.has_class(div, "slide"))
+ {
+ // add slide to collection
+ slides[slides.length] = div;
+
+ // hide each slide as it is found
+ this.add_class(div, "hidden");
+
+ // add dummy <br/> at end for scrolling hack
+ var node1 = document.createElement("br");
+ div.appendChild(node1);
+ var node2 = document.createElement("br");
+ div.appendChild(node2);
+ }
+ else if (this.has_class(div, "background"))
+ { // work around for Firefox SVG reload bug
+ // which otherwise replaces 1st SVG graphic with 2nd
+ div.style.display = "block";
+ }
+ }
+
+ this.slides = slides;
+ },
+
+ // return new array of all <div class="handout">
+ collect_notes: function () {
+ var notes = new Array();
+ var divs = document.body.getElementsByTagName("div");
+
+ for (var i = 0; i < divs.length; ++i)
+ {
+ div = divs.item(i);
+
+ if (this.has_class(div, "handout"))
+ {
+ // add note to collection
+ notes[notes.length] = div;
+
+ // and hide it
+ this.add_class(div, "hidden");
+ }
+ }
+
+ this.notes = notes;
+ },
+
+ // return new array of all <div class="background">
+ // including named backgrounds e.g. class="background titlepage"
+ collect_backgrounds: function () {
+ var backgrounds = new Array();
+ var divs = document.body.getElementsByTagName("div");
+
+ for (var i = 0; i < divs.length; ++i)
+ {
+ div = divs.item(i);
+
+ if (this.has_class(div, "background"))
+ {
+ // add background to collection
+ backgrounds[backgrounds.length] = div;
+
+ // and hide it
+ this.add_class(div, "hidden");
+ }
+ }
+
+ this.backgrounds = backgrounds;
+ },
+
+ // set click handlers on all anchors
+ patch_anchors: function () {
+ var self = w3c_slidy;
+ var handler = function (event) {
+ // compare this.href with location.href
+ // for link to another slide in this doc
+
+ if (self.page_address(this.href) == self.page_address(location.href))
+ {
+ // yes, so find new slide number
+ var newslidenum = self.find_slide_number(this.href);
+
+ if (newslidenum != self.slide_number)
+ {
+ var slide = self.slides[self.slide_number];
+ self.hide_slide(slide);
+ self.slide_number = newslidenum;
+ slide = self.slides[self.slide_number];
+ self.show_slide(slide);
+ self.set_location();
+ }
+ }
+ else if (this.target == null)
+ location.href = this.href;
+
+ this.blur();
+ self.disable_slide_click = true;
+ };
+
+ var anchors = document.body.getElementsByTagName("a");
+
+ for (var i = 0; i < anchors.length; ++i)
+ {
+ if (window.addEventListener)
+ anchors[i].addEventListener("click", handler, false);
+ else
+ anchors[i].attachEvent("onclick", handler);
+ }
+ },
+
+ // ### CHECK ME ### see which functions are invoked via setTimeout
+ // either directly or indirectly for use of w3c_slidy vs this
+ show_slide_number: function () {
+ var timer = w3c_slidy.get_timer();
+ w3c_slidy.slide_number_element.innerHTML = timer + "slide".localize() + " " +
+ (w3c_slidy.slide_number + 1) + "/" + w3c_slidy.slides.length;
+ },
+
+ // every 200mS check if the location has been changed as a
+ // result of the user activating the Back button/menu item
+ // doesn't work for Opera < 9.5
+ check_location: function () {
+ var hash = location.hash;
+
+ if (w3c_slidy.slide_number > 0 && (hash == "" || hash == "#"))
+ w3c_slidy.goto_slide(0);
+ else if (hash.length > 2 && hash != "#("+(w3c_slidy.slide_number+1)+")")
+ {
+ var num = parseInt(location.hash.substr(2));
+
+ if (!isNaN(num))
+ w3c_slidy.goto_slide(num-1);
+ }
+
+ if (w3c_slidy.time_left && w3c_slidy.slide_number > 0)
+ {
+ w3c_slidy.show_slide_number();
+
+ if (w3c_slidy.time_left > 0)
+ w3c_slidy.time_left -= 200;
+ }
+ },
+
+ get_timer: function () {
+ var timer = "";
+ if (w3c_slidy.time_left)
+ {
+ var mins, secs;
+ secs = Math.floor(w3c_slidy.time_left/1000);
+ mins = Math.floor(secs / 60);
+ secs = secs % 60;
+ timer = (mins ? mins+"m" : "") + secs + "s ";
+ }
+
+ return timer;
+ },
+
+ // this doesn't push location onto history stack for IE
+ // for which a hidden iframe hack is needed: load page into
+ // the iframe with script that set's parent's location.hash
+ // but that won't work for standalone use unless we can
+ // create the page dynamically via a javascript: URL
+ set_location: function () {
+ var uri = w3c_slidy.page_address(location.href);
+ var hash = "#(" + (w3c_slidy.slide_number+1) + ")";
+
+ if (w3c_slidy.slide_number >= 0)
+ uri = uri + hash;
+
+ if (w3c_slidy.ie && !w3c_slidy.ie8)
+ w3c_slidy.push_hash(hash);
+
+ if (uri != location.href) // && !khtml
+ location.href = uri;
+
+ if (this.khtml)
+ hash = "(" + (w3c_slidy.slide_number+1) + ")";
+
+ if (!this.ie && location.hash != hash && location.hash != "")
+ location.hash = hash;
+
+ document.title = w3c_slidy.title + " (" + (w3c_slidy.slide_number+1) + ")";
+ w3c_slidy.show_slide_number();
+ },
+
+ page_address: function (uri) {
+ var i = uri.indexOf("#");
+
+ if (i < 0)
+ i = uri.indexOf("%23");
+
+ // check if anchor is entire page
+
+ if (i < 0)
+ return uri; // yes
+
+ return uri.substr(0, i);
+ },
+
+ // only used for IE6 and IE7
+ on_frame_loaded: function (hash) {
+ location.hash = hash;
+ var uri = w3c_slidy.page_address(location.href);
+ location.href = uri + hash;
+ },
+
+ // history hack with thanks to Bertrand Le Roy
+ push_hash: function (hash) {
+ if (hash == "") hash = "#(1)";
+ window.location.hash = hash;
+
+ var doc = document.getElementById("historyFrame").contentWindow.document;
+ doc.open("javascript:'<html></html>'");
+ // PWL modified this string literal to break the close script tag
+ // which otherwise gets parsed when incorporated
+ doc.write("<html><head><script type=\"text/javascript\">window.parent.w3c_slidy.on_frame_loaded('"+
+ (hash) + "');</" + "script></head><body>hello mum</body></html>");
+ doc.close();
+ },
+
+ // find current slide based upon location
+ // first find target anchor and then look
+ // for associated div element enclosing it
+ // finally map that to slide number
+ find_slide_number: function (uri) {
+ // first get anchor from page location
+
+ var i = uri.indexOf("#");
+
+ // check if anchor is entire page
+ if (i < 0)
+ return 0; // yes
+
+ var anchor = unescape(uri.substr(i+1));
+
+ // now use anchor as XML ID to find target
+ var target = document.getElementById(anchor);
+
+ if (!target)
+ {
+ // does anchor look like "(2)" for slide 2 ??
+ // where first slide is (1)
+ var re = /\((\d)+\)/;
+
+ if (anchor.match(re))
+ {
+ var num = parseInt(anchor.substring(1, anchor.length-1));
+
+ if (num > this.slides.length)
+ num = 1;
+
+ if (--num < 0)
+ num = 0;
+
+ return num;
+ }
+
+ // accept [2] for backwards compatibility
+ re = /\[(\d)+\]/;
+
+ if (anchor.match(re))
+ {
+ var num = parseInt(anchor.substring(1, anchor.length-1));
+
+ if (num > this.slides.length)
+ num = 1;
+
+ if (--num < 0)
+ num = 0;
+
+ return num;
+ }
+
+ // oh dear unknown anchor
+ return 0;
+ }
+
+ // search for enclosing slide
+
+ while (true)
+ {
+ // browser coerces html elements to uppercase!
+ if (target.nodeName.toLowerCase() == "div" &&
+ this.has_class(target, "slide"))
+ {
+ // found the slide element
+ break;
+ }
+
+ // otherwise try parent element if any
+
+ target = target.parentNode;
+
+ if (!target)
+ {
+ return 0; // no luck!
+ }
+ };
+
+ for (i = 0; i < slides.length; ++i)
+ {
+ if (slides[i] == target)
+ return i; // success
+ }
+
+ // oh dear still no luck
+ return 0;
+ },
+
+ previous_slide: function (incremental) {
+ if (!w3c_slidy.view_all)
+ {
+ var slide;
+
+ if ((incremental || w3c_slidy.slide_number == 0) && w3c_slidy.last_shown != null)
+ {
+ w3c_slidy.last_shown = w3c_slidy.hide_previous_item(w3c_slidy.last_shown);
+ w3c_slidy.set_eos_status(false);
+ }
+ else if (w3c_slidy.slide_number > 0)
+ {
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+
+ w3c_slidy.slide_number = w3c_slidy.slide_number - 1;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.set_visibility_all_incremental("visible");
+ w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null);
+ w3c_slidy.set_eos_status(true);
+ w3c_slidy.show_slide(slide);
+ }
+
+ w3c_slidy.set_location();
+
+ if (!w3c_slidy.ns_pos)
+ w3c_slidy.refresh_toolbar(200);
+ }
+ },
+
+ next_slide: function (incremental) {
+ if (!w3c_slidy.view_all)
+ {
+ var slide, last = w3c_slidy.last_shown;
+
+ if (incremental || w3c_slidy.slide_number == w3c_slidy.slides.length - 1)
+ w3c_slidy.last_shown = w3c_slidy.reveal_next_item(w3c_slidy.last_shown);
+
+ if ((!incremental || w3c_slidy.last_shown == null) &&
+ w3c_slidy.slide_number < w3c_slidy.slides.length - 1)
+ {
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+
+ w3c_slidy.slide_number = w3c_slidy.slide_number + 1;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.show_slide(slide);
+ }
+ else if (!w3c_slidy.last_shown)
+ {
+ if (last && incremental)
+ w3c_slidy.last_shown = last;
+ }
+
+ w3c_slidy.set_location();
+
+ w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+
+ if (!w3c_slidy.ns_pos)
+ w3c_slidy.refresh_toolbar(200);
+ }
+ },
+
+ // to first slide with nothing revealed
+ // i.e. state at start of presentation
+ first_slide: function () {
+ if (!w3c_slidy.view_all)
+ {
+ var slide;
+
+ if (w3c_slidy.slide_number != 0)
+ {
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+
+ w3c_slidy.slide_number = 0;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.show_slide(slide);
+ }
+
+ w3c_slidy.set_eos_status(
+ !w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+ w3c_slidy.set_location();
+ }
+ },
+
+ // goto last slide with everything revealed
+ // i.e. state at end of presentation
+ last_slide: function () {
+ if (!w3c_slidy.view_all)
+ {
+ var slide;
+
+ w3c_slidy.last_shown = null; //revealNextItem(lastShown);
+
+ if (w3c_slidy.last_shown == null &&
+ w3c_slidy.slide_number < w3c_slidy.slides.length - 1)
+ {
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.slide_number = w3c_slidy.slides.length - 1;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.set_visibility_all_incremental("visible");
+ w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null);
+
+ w3c_slidy.show_slide(slide);
+ }
+ else
+ {
+ w3c_slidy.set_visibility_all_incremental("visible");
+ w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null);
+ }
+
+ w3c_slidy.set_eos_status(true);
+ w3c_slidy.set_location();
+ }
+ },
+
+
+ // ### check this and consider add/remove class
+ set_eos_status: function (state) {
+ if (this.eos)
+ this.eos.style.color = (state ? "rgb(240,240,240)" : "red");
+ },
+
+ // first slide is 0
+ goto_slide: function (num) {
+ //alert("going to slide " + (num+1));
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.slide_number = num;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+ document.title = w3c_slidy.title + " (" + (w3c_slidy.slide_number+1) + ")";
+ w3c_slidy.show_slide(slide);
+ w3c_slidy.show_slide_number();
+ },
+
+
+ show_slide: function (slide) {
+ this.sync_background(slide);
+ window.scrollTo(0,0);
+ this.remove_class(slide, "hidden");
+ },
+
+ hide_slide: function (slide) {
+ this.add_class(slide, "hidden");
+ },
+
+ // show just the backgrounds pertinent to this slide
+ // when slide background-color is transparent
+ // this should now work with rgba color values
+ sync_background: function (slide) {
+ var background;
+ var bgColor;
+
+ if (slide.currentStyle)
+ bgColor = slide.currentStyle["backgroundColor"];
+ else if (document.defaultView)
+ {
+ var styles = document.defaultView.getComputedStyle(slide,null);
+
+ if (styles)
+ bgColor = styles.getPropertyValue("background-color");
+ else // broken implementation probably due Safari or Konqueror
+ {
+ //alert("defective implementation of getComputedStyle()");
+ bgColor = "transparent";
+ }
+ }
+ else
+ bgColor == "transparent";
+
+ if (bgColor == "transparent" ||
+ bgColor.indexOf("rgba") >= 0 ||
+ bgColor.indexOf("opacity") >= 0)
+ {
+ var slideClass = this.get_class_list(slide);
+
+ for (var i = 0; i < this.backgrounds.length; i++)
+ {
+ background = this.backgrounds[i];
+
+ var bgClass = this.get_class_list(background);
+
+ if (this.matching_background(slideClass, bgClass))
+ this.remove_class(background, "hidden");
+ else
+ this.add_class(background, "hidden");
+ }
+ }
+ else // forcibly hide all backgrounds
+ this.hide_backgrounds();
+ },
+
+ hide_backgrounds: function () {
+ for (var i = 0; i < this.backgrounds.length; i++)
+ {
+ background = this.backgrounds[i];
+ this.add_class(background, "hidden");
+ }
+ },
+
+ // compare classes for slide and background
+ matching_background: function (slideClass, bgClass) {
+ var i, count, pattern, result;
+
+ // define pattern as regular expression
+ pattern = /\w+/g;
+
+ // check background class names
+ result = bgClass.match(pattern);
+
+ for (i = count = 0; i < result.length; i++)
+ {
+ if (result[i] == "hidden")
+ continue;
+
+ if (result[i] == "background")
+ continue;
+
+ ++count;
+ }
+
+ if (count == 0) // default match
+ return true;
+
+ // check for matches and place result in array
+ result = slideClass.match(pattern);
+
+ // now check if desired name is present for background
+ for (i = count = 0; i < result.length; i++)
+ {
+ if (result[i] == "hidden")
+ continue;
+
+ if (this.has_token(bgClass, result[i]))
+ return true;
+ }
+
+ return false;
+ },
+
+ resized: function () {
+ var width = 0;
+
+ if ( typeof( window.innerWidth ) == 'number' )
+ width = window.innerWidth; // Non IE browser
+ else if (document.documentElement && document.documentElement.clientWidth)
+ width = document.documentElement.clientWidth; // IE6
+ else if (document.body && document.body.clientWidth)
+ width = document.body.clientWidth; // IE4
+
+ var height = 0;
+
+ if ( typeof( window.innerHeight ) == 'number' )
+ height = window.innerHeight; // Non IE browser
+ else if (document.documentElement && document.documentElement.clientHeight)
+ height = document.documentElement.clientHeight; // IE6
+ else if (document.body && document.body.clientHeight)
+ height = document.body.clientHeight; // IE4
+
+ if (height && (width/height > 1.05*1024/768))
+ {
+ width = height * 1024.0/768;
+ }
+
+ // IE fires onresize even when only font size is changed!
+ // so we do a check to avoid blocking < and > actions
+ if (width != w3c_slidy.last_width || height != w3c_slidy.last_height)
+ {
+ if (width >= 1100)
+ w3c_slidy.size_index = 5; // 4
+ else if (width >= 1000)
+ w3c_slidy.size_index = 4; // 3
+ else if (width >= 800)
+ w3c_slidy.size_index = 3; // 2
+ else if (width >= 600)
+ w3c_slidy.size_index = 2; // 1
+ else if (width)
+ w3c_slidy.size_index = 0;
+
+ // add in font size adjustment from meta element e.g.
+ // <meta name="font-size-adjustment" content="-2" />
+ // useful when slides have too much content ;-)
+
+ if (0 <= w3c_slidy.size_index + w3c_slidy.size_adjustment &&
+ w3c_slidy.size_index + w3c_slidy.size_adjustment < w3c_slidy.sizes.length)
+ w3c_slidy.size_index = w3c_slidy.size_index + w3c_slidy.size_adjustment;
+
+ // enables cross browser use of relative width/height
+ // on object elements for use with SVG and Flash media
+ w3c_slidy.adjust_object_dimensions(width, height);
+
+ if (document.body.style.fontSize != w3c_slidy.sizes[w3c_slidy.size_index])
+ {
+ document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index];
+ }
+
+ w3c_slidy.last_width = width;
+ w3c_slidy.last_height = height;
+
+ // force reflow to work around Mozilla bug
+ if (w3c_slidy.ns_pos)
+ {
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.show_slide(slide);
+ }
+
+ // force correct positioning of toolbar
+ w3c_slidy.refresh_toolbar(200);
+ }
+ },
+
+ scrolled: function () {
+ if (w3c_slidy.toolbar && !w3c_slidy.ns_pos && !w3c_slidy.ie7)
+ {
+ w3c_slidy.hack_offset = w3c_slidy.scroll_x_offset();
+ // hide toolbar
+ w3c_slidy.toolbar.style.display = "none";
+
+ // make it reappear later
+ if (w3c_slidy.scrollhack == 0 && !w3c_slidy.view_all)
+ {
+ setTimeout(function () {w3c_slidy.show_toolbar(); }, 1000);
+ w3c_slidy.scrollhack = 1;
+ }
+ }
+ },
+
+ hide_toolbar: function () {
+ w3c_slidy.add_class(w3c_slidy.toolbar, "hidden");
+ window.focus();
+ },
+
+ // used to ensure IE refreshes toolbar in correct position
+ refresh_toolbar: function (interval) {
+ if (!w3c_slidy.ns_pos && !w3c_slidy.ie7)
+ {
+ w3c_slidy.hide_toolbar();
+ setTimeout(function () {w3c_slidy.show_toolbar(); }, interval);
+ }
+ },
+
+ // restores toolbar after short delay
+ show_toolbar: function () {
+ if (w3c_slidy.want_toolbar)
+ {
+ w3c_slidy.toolbar.style.display = "block";
+
+ if (!w3c_slidy.ns_pos)
+ {
+ // adjust position to allow for scrolling
+ var xoffset = w3c_slidy.scroll_x_offset();
+ w3c_slidy.toolbar.style.left = xoffset;
+ w3c_slidy.toolbar.style.right = xoffset;
+
+ // determine vertical scroll offset
+ //var yoffset = scrollYOffset();
+
+ // bottom is doc height - window height - scroll offset
+ //var bottom = documentHeight() - lastHeight - yoffset
+
+ //if (yoffset > 0 || documentHeight() > lastHeight)
+ // bottom += 16; // allow for height of scrollbar
+
+ w3c_slidy.toolbar.style.bottom = 0; //bottom;
+ }
+
+ w3c_slidy.remove_class(w3c_slidy.toolbar, "hidden");
+ }
+
+ w3c_slidy.scrollhack = 0;
+
+
+ // set the keyboard focus to the help link on the
+ // toolbar to ensure that document has the focus
+ // IE doesn't always work with window.focus()
+ // and this hack has benefit of Enter for help
+
+ try
+ {
+ if (!w3c_slidy.opera)
+ w3c_slidy.help_anchor.focus();
+ }
+ catch (e)
+ {
+ }
+ },
+
+// invoked via F key
+ toggle_toolbar: function () {
+ if (!w3c_slidy.view_all)
+ {
+ if (w3c_slidy.has_class(w3c_slidy.toolbar, "hidden"))
+ {
+ w3c_slidy.remove_class(w3c_slidy.toolbar, "hidden")
+ w3c_slidy.want_toolbar = 1;
+ }
+ else
+ {
+ w3c_slidy.add_class(w3c_slidy.toolbar, "hidden")
+ w3c_slidy.want_toolbar = 0;
+ }
+ }
+ },
+
+ scroll_x_offset: function () {
+ if (window.pageXOffset)
+ return self.pageXOffset;
+
+ if (document.documentElement &&
+ document.documentElement.scrollLeft)
+ return document.documentElement.scrollLeft;
+
+ if (document.body)
+ return document.body.scrollLeft;
+
+ return 0;
+ },
+
+ scroll_y_offset: function () {
+ if (window.pageYOffset)
+ return self.pageYOffset;
+
+ if (document.documentElement &&
+ document.documentElement.scrollTop)
+ return document.documentElement.scrollTop;
+
+ if (document.body)
+ return document.body.scrollTop;
+
+ return 0;
+ },
+
+ // looking for a way to determine height of slide content
+ // the slide itself is set to the height of the window
+ optimize_font_size: function () {
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+
+ //var dh = documentHeight(); //getDocHeight(document);
+ var dh = slide.scrollHeight;
+ var wh = getWindowHeight();
+ var u = 100 * dh / wh;
+
+ alert("window utilization = " + u + "% (doc "
+ + dh + " win " + wh + ")");
+ },
+
+ // from document object
+ get_doc_height: function (doc) {
+ if (!doc)
+ doc = document;
+
+ if (doc && doc.body && doc.body.offsetHeight)
+ return doc.body.offsetHeight; // ns/gecko syntax
+
+ if (doc && doc.body && doc.body.scrollHeight)
+ return doc.body.scrollHeight;
+
+ alert("couldn't determine document height");
+ },
+
+ get_window_height: function () {
+ if ( typeof( window.innerHeight ) == 'number' )
+ return window.innerHeight; // Non IE browser
+
+ if (document.documentElement && document.documentElement.clientHeight)
+ return document.documentElement.clientHeight; // IE6
+
+ if (document.body && document.body.clientHeight)
+ return document.body.clientHeight; // IE4
+ },
+
+ document_height: function () {
+ var sh, oh;
+
+ sh = document.body.scrollHeight;
+ oh = document.body.offsetHeight;
+
+ if (sh && oh)
+ {
+ return (sh > oh ? sh : oh);
+ }
+
+ // no idea!
+ return 0;
+ },
+
+ smaller: function () {
+ if (w3c_slidy.size_index > 0)
+ {
+ --w3c_slidy.size_index;
+ }
+
+ w3c_slidy.toolbar.style.display = "none";
+ document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index];
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.show_slide(slide);
+ setTimeout(function () {w3c_slidy.show_toolbar(); }, 50);
+ },
+
+ bigger: function () {
+ if (w3c_slidy.size_index < w3c_slidy.sizes.length - 1)
+ {
+ ++w3c_slidy.size_index;
+ }
+
+ w3c_slidy.toolbar.style.display = "none";
+ document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index];
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.show_slide(slide);
+ setTimeout(function () {w3c_slidy.show_toolbar(); }, 50);
+ },
+
+ // enables cross browser use of relative width/height
+ // on object elements for use with SVG and Flash media
+ // with thanks to Ivan Herman for the suggestion
+ adjust_object_dimensions: function (width, height) {
+ for( var i = 0; i < w3c_slidy.objects.length; i++ )
+ {
+ var obj = this.objects[i];
+ var mimeType = obj.getAttribute("type");
+
+ if (mimeType == "image/svg+xml" || mimeType == "application/x-shockwave-flash")
+ {
+ if ( !obj.initialWidth )
+ obj.initialWidth = obj.getAttribute("width");
+
+ if ( !obj.initialHeight )
+ obj.initialHeight = obj.getAttribute("height");
+
+ if ( obj.initialWidth && obj.initialWidth.charAt(obj.initialWidth.length-1) == "%" )
+ {
+ var w = parseInt(obj.initialWidth.slice(0, obj.initialWidth.length-1));
+ var newW = width * (w/100.0);
+ obj.setAttribute("width",newW);
+ }
+
+ if ( obj.initialHeight &&
+ obj.initialHeight.charAt(obj.initialHeight.length-1) == "%" )
+ {
+ var h = parseInt(obj.initialHeight.slice(0, obj.initialHeight.length-1));
+ var newH = height * (h/100.0);
+ obj.setAttribute("height", newH);
+ }
+ }
+ }
+ },
+
+ // needed for Opera to inhibit default behavior
+ // since Opera delivers keyPress even if keyDown
+ // was cancelled
+ key_press: function (event) {
+ if (!event)
+ event = window.event;
+
+ if (!w3c_slidy.key_wanted)
+ return w3c_slidy.cancel(event);
+
+ return true;
+ },
+
+ // See e.g. http://www.quirksmode.org/js/events/keys.html for keycodes
+ key_down: function (event) {
+ var key;
+
+ w3c_slidy.key_wanted = true;
+
+ if (!event)
+ event = window.event;
+
+ // kludge around NS/IE differences
+ if (window.event)
+ key = window.event.keyCode;
+ else if (event.which)
+ key = event.which;
+ else
+ return true; // Yikes! unknown browser
+
+ // ignore event if key value is zero
+ // as for alt on Opera and Konqueror
+ if (!key)
+ return true;
+
+ // check for concurrent control/command/alt key
+ // but are these only present on mouse events?
+
+ if (event.ctrlKey || event.altKey || event.metaKey)
+ return true;
+
+ // dismiss table of contents if visible
+ if (w3c_slidy.is_shown_toc() && key != 9 && key != 16 && key != 38 && key != 40)
+ {
+ w3c_slidy.hide_table_of_contents();
+
+ if (key == 27 || key == 84 || key == 67)
+ return w3c_slidy.cancel(event);
+ }
+
+ if (key == 34) // Page Down
+ {
+ if (w3c_slidy.view_all)
+ return true;
+
+ w3c_slidy.next_slide(false);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 33) // Page Up
+ {
+ if (w3c_slidy.view_all)
+ return true;
+
+ w3c_slidy.previous_slide(false);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 32) // space bar
+ {
+ w3c_slidy.next_slide(true);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 37) // Left arrow
+ {
+ w3c_slidy.previous_slide(!event.shiftKey);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 36) // Home
+ {
+ w3c_slidy.first_slide();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 35) // End
+ {
+ w3c_slidy.last_slide();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 39) // Right arrow
+ {
+ w3c_slidy.next_slide(!event.shiftKey);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 13) // Enter
+ {
+ if (w3c_slidy.outline)
+ {
+ if (w3c_slidy.outline.visible)
+ w3c_slidy.fold(w3c_slidy.outline);
+ else
+ w3c_slidy.unfold(w3c_slidy.outline);
+
+ return w3c_slidy.cancel(event);
+ }
+ }
+ else if (key == 188) // < for smaller fonts
+ {
+ w3c_slidy.smaller();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 190) // > for larger fonts
+ {
+ w3c_slidy.bigger();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 189 || key == 109) // - for smaller fonts
+ {
+ w3c_slidy.smaller();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 187 || key == 191 || key == 107) // = + for larger fonts
+ {
+ w3c_slidy.bigger();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 83) // S for smaller fonts
+ {
+ w3c_slidy.smaller();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 66) // B for larger fonts
+ {
+ w3c_slidy.bigger();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 90) // Z for last slide
+ {
+ w3c_slidy.last_slide();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 70) // F for toggle toolbar
+ {
+ w3c_slidy.toggle_toolbar();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 65) // A for toggle view single/all slides
+ {
+ w3c_slidy.toggle_view();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 75) // toggle action of left click for next page
+ {
+ w3c_slidy.mouse_click_enabled = !w3c_slidy.mouse_click_enabled;
+ var alert_msg = (w3c_slidy.mouse_click_enabled ?
+ "enabled" : "disabled") + " mouse click advance";
+
+ alert(alert_msg.localize());
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 84 || key == 67) // T or C for table of contents
+ {
+ if (w3c_slidy.toc)
+ w3c_slidy.toggle_table_of_contents();
+
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 72) // H for help
+ {
+ window.location = w3c_slidy.help_page;
+ return w3c_slidy.cancel(event);
+ }
+ //else alert("key code is "+ key);
+
+ return true;
+ },
+
+ // safe for both text/html and application/xhtml+xml
+ create_element: function (name) {
+ if (this.xhtml && (typeof document.createElementNS != 'undefined'))
+ return document.createElementNS("http://www.w3.org/1999/xhtml", name)
+
+ return document.createElement(name);
+ },
+
+ get_element_style: function (elem, IEStyleProp, CSSStyleProp) {
+ if (elem.currentStyle)
+ {
+ return elem.currentStyle[IEStyleProp];
+ }
+ else if (window.getComputedStyle)
+ {
+ var compStyle = window.getComputedStyle(elem, "");
+ return compStyle.getPropertyValue(CSSStyleProp);
+ }
+ return "";
+ },
+
+ // the string str is a whitespace separated list of tokens
+ // test if str contains a particular token, e.g. "slide"
+ has_token: function (str, token) {
+ if (str)
+ {
+ // define pattern as regular expression
+ var pattern = /\w+/g;
+
+ // check for matches
+ // place result in array
+ var result = str.match(pattern);
+
+ // now check if desired token is present
+ for (var i = 0; i < result.length; i++)
+ {
+ if (result[i] == token)
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ get_class_list: function (element) {
+ if (typeof element.className != 'undefined')
+ return element.className;
+
+ return element.getAttribute("class");
+ },
+
+ has_class: function (element, name) {
+ if (element.nodeType != 1)
+ return false;
+
+ var regexp = new RegExp("(^| )" + name + "\W*");
+
+ if (typeof element.className != 'undefined')
+ return regexp.test(element.className);
+
+ return regexp.test(element.getAttribute("class"));
+ },
+
+ remove_class: function (element, name) {
+ var regexp = new RegExp("(^| )" + name + "\W*");
+ var clsval = "";
+
+ if (typeof element.className != 'undefined')
+ {
+ clsval = element.className;
+
+ if (clsval)
+ {
+ clsval = clsval.replace(regexp, "");
+ element.className = clsval;
+ }
+ }
+ else
+ {
+ clsval = element.getAttribute("class");
+
+ if (clsval)
+ {
+ clsval = clsval.replace(regexp, "");
+ element.setAttribute("class", clsval);
+ }
+ }
+ },
+
+ add_class: function (element, name) {
+ if (!this.has_class(element, name))
+ {
+ if (typeof element.className != 'undefined')
+ element.className += " " + name;
+ else
+ {
+ var clsval = element.getAttribute("class");
+ clsval = clsval ? clsval + " " + name : name;
+ element.setAttribute("class", clsval);
+ }
+ }
+ },
+
+ // HTML elements that can be used with class="incremental"
+ // note that you can also put the class on containers like
+ // up, ol, dl, and div to make their contents appear
+ // incrementally. Upper case is used since this is what
+ // browsers report for HTML node names (text/html).
+ incremental_elements: null,
+ okay_for_incremental: function (name) {
+ if (!this.incremental_elements)
+ {
+ var inclist = new Array();
+ inclist["p"] = true;
+ inclist["pre"] = true;
+ inclist["li"] = true;
+ inclist["blockquote"] = true;
+ inclist["dt"] = true;
+ inclist["dd"] = true;
+ inclist["h2"] = true;
+ inclist["h3"] = true;
+ inclist["h4"] = true;
+ inclist["h5"] = true;
+ inclist["h6"] = true;
+ inclist["span"] = true;
+ inclist["address"] = true;
+ inclist["table"] = true;
+ inclist["tr"] = true;
+ inclist["th"] = true;
+ inclist["td"] = true;
+ inclist["img"] = true;
+ inclist["object"] = true;
+ this.incremental_elements = inclist;
+ }
+ return this.incremental_elements[name.toLowerCase()];
+ },
+
+ next_incremental_item: function (node) {
+ var br = this.is_xhtml ? "br" : "BR";
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+
+ for (;;)
+ {
+ node = w3c_slidy.next_node(slide, node);
+
+ if (node == null || node.parentNode == null)
+ break;
+
+ if (node.nodeType == 1) // ELEMENT
+ {
+ if (node.nodeName == br)
+ continue;
+
+ if (w3c_slidy.has_class(node, "incremental")
+ && w3c_slidy.okay_for_incremental(node.nodeName))
+ return node;
+
+ if (w3c_slidy.has_class(node.parentNode, "incremental")
+ && !w3c_slidy.has_class(node, "non-incremental"))
+ return node;
+ }
+ }
+
+ return node;
+ },
+
+ previous_incremental_item: function (node) {
+ var br = this.is_xhtml ? "br" : "BR";
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+
+ for (;;)
+ {
+ node = w3c_slidy.previous_node(slide, node);
+
+ if (node == null || node.parentNode == null)
+ break;
+
+ if (node.nodeType == 1)
+ {
+ if (node.nodeName == br)
+ continue;
+
+ if (w3c_slidy.has_class(node, "incremental")
+ && w3c_slidy.okay_for_incremental(node.nodeName))
+ return node;
+
+ if (w3c_slidy.has_class(node.parentNode, "incremental")
+ && !w3c_slidy.has_class(node, "non-incremental"))
+ return node;
+ }
+ }
+
+ return node;
+ },
+
+ // set visibility for all elements on current slide with
+ // a parent element with attribute class="incremental"
+ set_visibility_all_incremental: function (value) {
+ var node = this.next_incremental_item(null);
+
+ if (value == "hidden")
+ {
+ while (node)
+ {
+ w3c_slidy.add_class(node, "invisible");
+ node = w3c_slidy.next_incremental_item(node);
+ }
+ }
+ else // value == "visible"
+ {
+ while (node)
+ {
+ w3c_slidy.remove_class(node, "invisible");
+ node = w3c_slidy.next_incremental_item(node);
+ }
+ }
+ },
+
+ // reveal the next hidden item on the slide
+ // node is null or the node that was last revealed
+ reveal_next_item: function (node) {
+ node = w3c_slidy.next_incremental_item(node);
+
+ if (node && node.nodeType == 1) // an element
+ w3c_slidy.remove_class(node, "invisible");
+
+ return node;
+ },
+
+ // exact inverse of revealNextItem(node)
+ hide_previous_item: function (node) {
+ if (node && node.nodeType == 1) // an element
+ w3c_slidy.add_class(node, "invisible");
+
+ return this.previous_incremental_item(node);
+ },
+
+ // left to right traversal of root's content
+ next_node: function (root, node) {
+ if (node == null)
+ return root.firstChild;
+
+ if (node.firstChild)
+ return node.firstChild;
+
+ if (node.nextSibling)
+ return node.nextSibling;
+
+ for (;;)
+ {
+ node = node.parentNode;
+
+ if (!node || node == root)
+ break;
+
+ if (node && node.nextSibling)
+ return node.nextSibling;
+ }
+
+ return null;
+ },
+
+ // right to left traversal of root's content
+ previous_node: function (root, node) {
+ if (node == null)
+ {
+ node = root.lastChild;
+
+ if (node)
+ {
+ while (node.lastChild)
+ node = node.lastChild;
+ }
+
+ return node;
+ }
+
+ if (node.previousSibling)
+ {
+ node = node.previousSibling;
+
+ while (node.lastChild)
+ node = node.lastChild;
+
+ return node;
+ }
+
+ if (node.parentNode != root)
+ return node.parentNode;
+
+ return null;
+ },
+
+ previous_sibling_element: function (el) {
+ el = el.previousSibling;
+
+ while (el && el.nodeType != 1)
+ el = el.previousSibling;
+
+ return el;
+ },
+
+ next_sibling_element: function (el) {
+ el = el.nextSibling;
+
+ while (el && el.nodeType != 1)
+ el = el.nextSibling;
+
+ return el;
+ },
+
+ first_child_element: function (el) {
+ var node;
+
+ for (node = el.firstChild; node; node = node.nextSibling)
+ {
+ if (node.nodeType == 1)
+ break;
+ }
+
+ return node;
+ },
+
+ first_tag: function (element, tag) {
+ var node;
+
+ if (!this.is_xhtml)
+ tag = tag.toUpperCase();
+
+ for (node = element.firstChild; node; node = node.nextSibling)
+ {
+ if (node.nodeType == 1 && node.nodeName == tag)
+ break;
+ }
+
+ return node;
+ },
+
+ hide_selection: function () {
+ if (window.getSelection) // Firefox, Chromium, Safari, Opera
+ {
+ var selection = window.getSelection();
+
+ if (selection.rangeCount > 0)
+ {
+ var range = selection.getRangeAt(0);
+ range.collapse (false);
+ }
+ }
+ else // Internet Explorer
+ {
+ var textRange = document.selection.createRange ();
+ textRange.collapse (false);
+ }
+ },
+
+ get_selected_text: function () {
+ try
+ {
+ if (window.getSelection)
+ return window.getSelection().toString();
+
+ if (document.getSelection)
+ return document.getSelection().toString();
+
+ if (document.selection)
+ return document.selection.createRange().text;
+ }
+ catch (e)
+ {
+ }
+
+ return "";
+ },
+
+ // make note of length of selected text
+ // as this evaluates to zero in click event
+ mouse_button_up: function (e) {
+ w3c_slidy.selected_text_len = w3c_slidy.get_selected_text().length;
+ },
+
+ // right mouse button click is reserved for context menus
+ // it is more reliable to detect rightclick than leftclick
+ mouse_button_click: function (e) {
+ var rightclick = false;
+ var leftclick = false;
+ var middleclick = false;
+ var target;
+
+ if (!e)
+ var e = window.event;
+
+ if (e.target)
+ target = e.target;
+ else if (e.srcElement)
+ target = e.srcElement;
+
+ // work around Safari bug
+ if (target.nodeType == 3)
+ target = target.parentNode;
+
+ if (e.which) // all browsers except IE
+ {
+ leftclick = (e.which == 1);
+ middleclick = (e.which == 2);
+ rightclick = (e.which == 3);
+ }
+ else if (e.button)
+ {
+ // Konqueror gives 1 for left, 4 for middle
+ // IE6 gives 0 for left and not 1 as I expected
+
+ if (e.button == 4)
+ middleclick = true;
+
+ // all browsers agree on 2 for right button
+ rightclick = (e.button == 2);
+ }
+ else leftclick = true;
+/*
+ alert("you clicked over a " + target.nodeName + " element\n" +
+ "w3c_slidy.mouse_click_enabled = " + w3c_slidy.mouse_click_enabled + "\n" +
+ "leftclick = " + leftclick + "\n" +
+ "selected text length = " + w3c_slidy.selected_text_len);
+ //alert("selected text length = " + w3c_slidy.selected_text_len);
+*/
+ if (w3c_slidy.selected_text_len > 0)
+ {
+ w3c_slidy.stop_propagation(e);
+ e.cancel = true;
+ e.returnValue = false;
+ return false;
+ }
+
+ // dismiss table of contents
+ w3c_slidy.hide_table_of_contents();
+
+ // check if target is something that probably want's clicks
+ // e.g. a, embed, object, input, textarea, select, option
+ var tag = target.nodeName.toLowerCase();
+
+ if (w3c_slidy.mouse_click_enabled && leftclick &&
+ tag != "a" &&
+ tag != "embed" &&
+ tag != "object" &&
+ tag != "video" &&
+ tag != "input" &&
+ tag != "textarea" &&
+ tag != "select" &&
+ tag != "option" &&
+ !target.onclick)
+ {
+ w3c_slidy.next_slide(true);
+ w3c_slidy.stop_propagation(e);
+ e.cancel = true;
+ e.returnValue = false;
+ return false;
+ }
+ },
+
+ get_key: function (e)
+ {
+ var key;
+
+ // kludge around NS/IE differences
+ if (typeof window.event != "undefined")
+ key = window.event.keyCode;
+ else if (e.which)
+ key = e.which;
+
+ return key;
+ },
+
+ get_target: function (e) {
+ var target;
+
+ if (!e)
+ e = window.event;
+
+ if (e.target)
+ target = e.target;
+ else if (e.srcElement)
+ target = e.srcElement;
+
+ if (target.nodeType != 1)
+ target = target.parentNode;
+
+ return target;
+ },
+
+ // does display property provide correct defaults?
+ is_block: function (elem) {
+ var tag = elem.nodeName.toLowerCase();
+
+ return tag == "ol" || tag == "ul" || tag == "p" ||
+ tag == "li" || tag == "table" || tag == "pre" ||
+ tag == "h1" || tag == "h2" || tag == "h3" ||
+ tag == "h4" || tag == "h5" || tag == "h6" ||
+ tag == "blockquote" || tag == "address";
+ },
+
+ add_listener: function (element, event, handler) {
+ if (window.addEventListener)
+ element.addEventListener(event, handler, false);
+ else
+ element.attachEvent("on"+event, handler);
+ },
+
+ // used to prevent event propagation from field controls
+ stop_propagation: function (event) {
+ event = event ? event : window.event;
+ event.cancelBubble = true; // for IE
+
+ if (event.stopPropagation)
+ event.stopPropagation();
+
+ return true;
+ },
+
+ cancel: function (event) {
+ if (event)
+ {
+ event.cancel = true;
+ event.returnValue = false;
+
+ if (event.preventDefault)
+ event.preventDefault();
+ }
+
+ w3c_slidy.key_wanted = false;
+ return false;
+ }
+};
+
+// for each language define an associative array
+// and also the help text which is longer
+
+var w3c_slidy_i18n = {
+ strings_es: {
+ "slide":"pág.",
+ "help?":"Ayuda",
+ "contents?":"Índice",
+ "table of contents":"tabla de contenidos",
+ "Table of Contents":"Tabla de Contenidos",
+ "restart presentation":"Reiniciar presentación",
+ "restart?":"Inicio"
+ },
+ help_es:
+ "Utilice el ratón, barra espaciadora, teclas Izda/Dcha, " +
+ "o Re pág y Av pág. Use S y B para cambiar el tamaño de fuente.",
+
+ strings_ca: {
+ "slide":"pàg..",
+ "help?":"Ajuda",
+ "contents?":"Índex",
+ "table of contents":"taula de continguts",
+ "Table of Contents":"Taula de Continguts",
+ "restart presentation":"Reiniciar presentació",
+ "restart?":"Inici"
+ },
+ help_ca:
+ "Utilitzi el ratolí, barra espaiadora, tecles Esq./Dta. " +
+ "o Re pàg y Av pàg. Usi S i B per canviar grandària de font.",
+
+ strings_cs: {
+ "slide":"snímek",
+ "help?":"nápověda",
+ "contents?":"obsah",
+ "table of contents":"obsah prezentace",
+ "Table of Contents":"Obsah prezentace",
+ "restart presentation":"znovu spustit prezentaci",
+ "restart?":"restart"
+ },
+ help_cs:
+ "Prezentaci můžete procházet pomocí kliknutí myši, mezerníku, " +
+ "šipek vlevo a vpravo nebo kláves PageUp a PageDown. Písmo se " +
+ "dá zvětšit a zmenšit pomocí kláves B a S.",
+
+ strings_nl: {
+ "slide":"pagina",
+ "help?":"Help?",
+ "contents?":"Inhoud?",
+ "table of contents":"inhoudsopgave",
+ "Table of Contents":"Inhoudsopgave",
+ "restart presentation":"herstart presentatie",
+ "restart?":"Herstart?"
+ },
+ help_nl:
+ "Navigeer d.m.v. het muis, spatiebar, Links/Rechts toetsen, " +
+ "of PgUp en PgDn. Gebruik S en B om de karaktergrootte te veranderen.",
+
+ strings_de: {
+ "slide":"Seite",
+ "help?":"Hilfe",
+ "contents?":"Übersicht",
+ "table of contents":"Inhaltsverzeichnis",
+ "Table of Contents":"Inhaltsverzeichnis",
+ "restart presentation":"Präsentation neu starten",
+ "restart?":"Neustart"
+ },
+ help_de:
+ "Benutzen Sie die Maus, Leerschlag, die Cursortasten links/rechts oder " +
+ "Page up/Page Down zum Wechseln der Seiten und S und B für die Schriftgrösse.",
+
+ strings_pl: {
+ "slide":"slajd",
+ "help?":"pomoc?",
+ "contents?":"spis treści?",
+ "table of contents":"spis treści",
+ "Table of Contents":"Spis Treści",
+ "restart presentation":"Restartuj prezentację",
+ "restart?":"restart?"
+ },
+ help_pl:
+ "Zmieniaj slajdy klikając myszą, naciskając spację, strzałki lewo/prawo" +
+ "lub PgUp / PgDn. Użyj klawiszy S i B, aby zmienić rozmiar czczionki.",
+
+ strings_fr: {
+ "slide":"page",
+ "help?":"Aide",
+ "contents?":"Index",
+ "table of contents":"table des matières",
+ "Table of Contents":"Table des matières",
+ "restart presentation":"Recommencer l'exposé",
+ "restart?":"Début"
+ },
+ help_fr:
+ "Naviguez avec la souris, la barre d'espace, les flèches " +
+ "gauche/droite ou les touches Pg Up, Pg Dn. Utilisez " +
+ "les touches S et B pour modifier la taille de la police.",
+
+ strings_hu: {
+ "slide":"oldal",
+ "help?":"segítség",
+ "contents?":"tartalom",
+ "table of contents":"tartalomjegyzék",
+ "Table of Contents":"Tartalomjegyzék",
+ "restart presentation":"bemutató újraindítása",
+ "restart?":"újraindítás"
+ },
+ help_hu:
+ "Az oldalak közti lépkedéshez kattintson az egérrel, vagy " +
+ "használja a szóköz, a bal, vagy a jobb nyíl, illetve a Page Down, " +
+ "Page Up billentyűket. Az S és a B billentyűkkel változtathatja " +
+ "a szöveg méretét.",
+
+ strings_it: {
+ "slide":"pag.",
+ "help?":"Aiuto",
+ "contents?":"Indice",
+ "table of contents":"indice",
+ "Table of Contents":"Indice",
+ "restart presentation":"Ricominciare la presentazione",
+ "restart?":"Inizio"
+ },
+ help_it:
+ "Navigare con mouse, barra spazio, frecce sinistra/destra o " +
+ "PgUp e PgDn. Usare S e B per cambiare la dimensione dei caratteri.",
+
+ strings_el: {
+ "slide":"σελίδα",
+ "help?":"βοήθεια;",
+ "contents?":"περιεχόμενα;",
+ "table of contents":"πίνακας περιεχομένων",
+ "Table of Contents":"Πίνακας Περιεχομένων",
+ "restart presentation":"επανεκκίνηση παρουσίασης",
+ "restart?":"επανεκκίνηση;"
+ },
+ help_el:
+ "Πλοηγηθείτε με το κλίκ του ποντικιού, το space, τα βέλη αριστερά/δεξιά, " +
+ "ή Page Up και Page Down. Χρησιμοποιήστε τα πλήκτρα S και B για να αλλάξετε " +
+ "το μέγεθος της γραμματοσειράς.",
+
+ strings_ja: {
+ "slide":"スライド",
+ "help?":"ヘルプ",
+ "contents?":"目次",
+ "table of contents":"目次を表示",
+ "Table of Contents":"目次",
+ "restart presentation":"最初から再生",
+ "restart?":"最初から"
+ },
+ help_ja:
+ "マウス左クリック ・ スペース ・ 左右キー " +
+ "または Page Up ・ Page Downで操作, S ・ Bでフォントサイズ変更",
+
+ strings_zh: {
+ "slide":"幻灯片",
+ "help?":"帮助?",
+ "contents?":"内容?",
+ "table of contents":"目录",
+ "Table of Contents":"目录",
+ "restart presentation":"重新启动展示",
+ "restart?":"重新启动?"
+ },
+ help_zh:
+ "用鼠标点击, 空格条, 左右箭头, Pg Up 和 Pg Dn 导航. " +
+ "用 S, B 改变字体大小.",
+
+ strings_ru: {
+ "slide":"слайд",
+ "help?":"помощь?",
+ "contents?":"содержание?",
+ "table of contents":"оглавление",
+ "Table of Contents":"Оглавление",
+ "restart presentation":"перезапустить презентацию",
+ "restart?":"перезапуск?"
+ },
+ help_ru:
+ "Перемещайтесь кликая мышкой, используя клавишу пробел, стрелки" +
+ "влево/вправо или Pg Up и Pg Dn. Клавиши S и B меняют размер шрифта.",
+
+ strings_sv: {
+ "slide":"sida",
+ "help?":"hjälp",
+ "contents?":"innehåll",
+ "table of contents":"innehållsförteckning",
+ "Table of Contents":"Innehållsförteckning",
+ "restart presentation":"visa presentationen från början",
+ "restart?":"börja om"
+ },
+ help_sv:
+ "Bläddra med ett klick med vänstra musknappen, mellanslagstangenten, " +
+ "vänster- och högerpiltangenterna eller tangenterna Pg Up, Pg Dn. " +
+ "Använd tangenterna S och B för att ändra textens storlek.",
+
+// each such language array is declared in the localize array
+// which is set on string prototype and used as in "foo".localize();
+ localize: {
+ "es":this.strings_es,
+ "ca":this.strings_ca,
+ "cs":this.strings_cs,
+ "nl":this.strings_nl,
+ "de":this.strings_de,
+ "pl":this.strings_pl,
+ "fr":this.strings_fr,
+ "hu":this.strings_hu,
+ "it":this.strings_it,
+ "el":this.strings_el,
+ "jp":this.strings_ja,
+ "zh":this.strings_zh,
+ "ru":this.strings_ru,
+ "sv":this.strings_sv
+ },
+
+ init: function () {
+ var i18n = w3c_slidy_i18n;
+ var help_text = w3c_slidy.help_text;
+ i18n.strings_es[help_text] = i18n.help_es;
+ i18n.strings_ca[help_text] = i18n.help_ca;
+ i18n.strings_cs[help_text] = i18n.help_cs;
+ i18n.strings_nl[help_text] = i18n.help_nl;
+ i18n.strings_de[help_text] = i18n.help_de;
+ i18n.strings_pl[help_text] = i18n.help_pl;
+ i18n.strings_fr[help_text] = i18n.help_fr;
+ i18n.strings_hu[help_text] = i18n.help_hu;
+ i18n.strings_it[help_text] = i18n.help_it;
+ i18n.strings_el[help_text] = i18n.help_el;
+ i18n.strings_ja[help_text] = i18n.help_ja;
+ i18n.strings_zh[help_text] = i18n.help_zh;
+ i18n.strings_ru[help_text] = i18n.help_ru;
+ i18n.strings_sv[help_text] = i18n.help_sv;
+
+ w3c_slidy.lang = document.body.parentNode.getAttribute("lang");
+
+ if (!w3c_slidy.lang)
+ w3c_slidy.lang = document.body.parentNode.getAttribute("xml:lang");
+
+ if (!w3c_slidy.lang)
+ w3c_slidy.lang = "en";
+
+ // add localize method to all strings
+ // for use as in "contents".localize()
+ String.prototype.localize = function() {
+ if (this == "")
+ return this;
+
+ // try full language code, e.g. en-US
+ var s, lookup = w3c_slidy_i18n.localize[w3c_slidy.lang];
+
+ if (lookup)
+ {
+ s = lookup[this];
+
+ if (s)
+ return s;
+ }
+
+ // strip country code suffix, e.g.
+ // try en if undefined for en-US
+ var lg = w3c_slidy.lang.split("-");
+
+ if (lg.length > 1)
+ {
+ lookup = w3c_slidy_i18n.localize[lg[0]];
+
+ if (lookup)
+ {
+ s = lookup[this];
+
+ if (s)
+ return s;
+ }
+ }
+
+ // otherwise string as is
+ return this;
+ };
+ }
+};
+
+// hack for back button behavior
+if (w3c_slidy.ie6 || w3c_slidy.ie7)
+{
+ document.write("<iframe id='historyFrame' " +
+ "src='javascript:\"<html"+"></"+"html>\"' " +
+ "height='1' width='1' " +
+ "style='position:absolute;left:-800px'></iframe>");
+}
+
+// attach event listeners for initialization
+w3c_slidy.set_up();
+
+// hide the slides as soon as body element is available
+// to reduce annoying screen mess before the onload event
+setTimeout(w3c_slidy.hide_slides, 50);
+
+/*]]>*/
+</script>
+</head>
+<body class="article" style="max-width:45em">
+<div id="header" class="slide">
+<h1>Osmocom BTS Hardware Support</h1>
+<span id="author">Harald Welte &lt;hwelte@sysmocom.de&gt;</span><br />
+</div>
+<div class="sect1 slide">
+<h1 id="_overview">Overview</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="imageblock graphviz">
+<div class="content">
+<img src="bts_hardware__1.png" alt="bts_hardware__1.png" />
+</div>
+</div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_clasic_e1_t1_based_bts">Clasic E1/T1 based BTS</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>Supported Vendors/Dialects</p></div>
+<ul class="">
+<li>
+<span>
+Siemens (only BS-11 tested)
+</span>
+</li>
+<li>
+<span>
+Ericsson RBS2xxx (RBS2307, 2308, 2111 tested)
+</span>
+</li>
+<li>
+<span>
+Nokia InSite, MetroSite
+</span>
+</li>
+</ul>
+<div class="tableblock">
+<table rules="all"
+width="100%"
+frame="border"
+cellspacing="0" cellpadding="4">
+<col width="50%" />
+<col width="50%" />
+<thead>
+<tr>
+<th align="left" valign="top">Pro</th>
+<th align="left" valign="top">Con</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td align="left" valign="top"><p class="table">available inexpensively from decomissioned sites</p></td>
+<td align="left" valign="top"><p class="table">appears a bit antiquated</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">up to 12 TRX</p></td>
+<td align="left" valign="top"><p class="table">not many people familiar with E1/T1 anymore</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">high RF output power</p></td>
+<td align="left" valign="top"><p class="table">no convenient testing/debugging of E1/T1 issues</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">rugged mechanical build, high MTTF</p></td>
+<td align="left" valign="top"><p class="table">high power consumption</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table"></p></td>
+<td align="left" valign="top"><p class="table">older models no EGPRS, no AMR</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_classic_e1_t1_based_bts">Classic E1/T1 based BTS</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="imageblock">
+<div class="content">
+<img src="images/har2009-bs11_at_tree.jpg" alt="images/har2009-bs11_at_tree.jpg" width="90%" />
+</div>
+</div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_clasic_e1_t1_based_bts_2">Clasic E1/T1 based BTS</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="imageblock gimmick_right">
+<div class="content">
+<img src="images/har2009-bs11_antennas2.small.jpg" alt="images/har2009-bs11_antennas2.small.jpg" width="50%" />
+</div>
+</div>
+<ul class="">
+<li>
+<span>
+This is how it all started
+</span>
+</li>
+<li>
+<span>
+E1 based BTS (Siemens BS-11)
+</span>
+</li>
+<li>
+<span>
+HAR 2009 - Dutch Hacker Camp
+</span>
+</li>
+<li>
+<span>
+Antennas mounted with duct tape to tree
+</span>
+</li>
+<li>
+<span>
+E1 back-haul over CAT5 to OpenBSC running in tent
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_ericsson_rbs_2308">Ericsson RBS 2308</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="imageblock gimmick_right">
+<div class="content">
+<img src="images/rbs2308.jpg" alt="images/rbs2308.jpg" width="60%" />
+</div>
+</div>
+<ul class="">
+<li>
+<span>
+Many RBS2000 models
+</span>
+</li>
+<li>
+<span>
+All very similar on protocol
+</span>
+</li>
+<li>
+<span>
+Not all models tested
+</span>
+</li>
+<li>
+<span>
+Good results with RBS2308 + RBS2111
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_ip_access_nanobts">ip.access nanoBTS</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="imageblock gimmick_right">
+<div class="content">
+<img src="images/nanoBTS_small.png" alt="images/nanoBTS_small.png" width="40%" />
+</div>
+</div>
+<ul class="">
+<li>
+<span>
+PoE-enabled single-TRX 200mW indoor BTS
+</span>
+</li>
+<li>
+<span>
+GPRS/GSM only models and EGPRS-enabled models
+</span>
+</li>
+<li>
+<span>
+available in band-specific versions for all four bands
+</span>
+</li>
+<li>
+<span>
+proprietary BTS and PCU inside
+</span>
+<ul class="">
+<li>
+<span>
+lots of PCU crashes reported by users :(
+</span>
+</li>
+<li>
+<span>
+no way for us to fix it
+</span>
+</li>
+</ul>
+</li>
+<li>
+<span>
+No fully dynamic channels (TCH/F + TCH/H + PDCH)
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_sysmobts">sysmoBTS</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="imageblock gimmick_right">
+<div class="content">
+<img src="images/symoBTS_v2D_front_1024.jpg" alt="images/symoBTS_v2D_front_1024.jpg" width="35%" />
+</div>
+</div>
+<ul class="">
+<li>
+<span>
+sysmocom builds family of GSM BTS based on OsmoBTS + OsmoPCU
+</span>
+</li>
+<li>
+<span>
+revenue from this sales used to cross-subsidize OsmoBTS development
+</span>
+</li>
+<li>
+<span>
+<strong>osmo-bts-sysmo</strong> uses shared-memory /dev to talk to PHY
+</span>
+</li>
+<li>
+<span>
+<strong>osmo-pcu</strong> uses shared-memory /dev to talk to PHY
+</span>
+</li>
+</ul>
+<div class="tableblock">
+<table rules="all"
+width="100%"
+frame="border"
+cellspacing="0" cellpadding="4">
+<col width="28%" />
+<col width="14%" />
+<col width="14%" />
+<col width="14%" />
+<col width="14%" />
+<col width="14%" />
+<thead>
+<tr>
+<th align="left" valign="top">Model </th>
+<th align="left" valign="top"> RF Pwr </th>
+<th align="left" valign="top">TRX</th>
+<th align="left" valign="top">Outdoor</th>
+<th align="left" valign="top">PoE </th>
+<th align="left" valign="top"> Quad-Band</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td align="left" valign="top"><p class="table">sysmoBTS 1002</p></td>
+<td align="left" valign="top"><p class="table">0.2 W</p></td>
+<td align="left" valign="top"><p class="table">1</p></td>
+<td align="left" valign="top"><p class="table">No</p></td>
+<td align="left" valign="top"><p class="table">No</p></td>
+<td align="left" valign="top"><p class="table">Yes</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">sysmoBTS 1002 OD</p></td>
+<td align="left" valign="top"><p class="table">0.2 W</p></td>
+<td align="left" valign="top"><p class="table">1</p></td>
+<td align="left" valign="top"><p class="table">Yes</p></td>
+<td align="left" valign="top"><p class="table">Yes</p></td>
+<td align="left" valign="top"><p class="table">Yes</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">sysmoBTS 1020</p></td>
+<td align="left" valign="top"><p class="table">2.0 W</p></td>
+<td align="left" valign="top"><p class="table">1</p></td>
+<td align="left" valign="top"><p class="table">Yes</p></td>
+<td align="left" valign="top"><p class="table">Yes</p></td>
+<td align="left" valign="top"><p class="table">No</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">sysmoBTS 1100</p></td>
+<td align="left" valign="top"><p class="table">10.0 W</p></td>
+<td align="left" valign="top"><p class="table">1</p></td>
+<td align="left" valign="top"><p class="table">Yes</p></td>
+<td align="left" valign="top"><p class="table">No</p></td>
+<td align="left" valign="top"><p class="table">No</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">sysmoBTS 2050</p></td>
+<td align="left" valign="top"><p class="table">2x 5 W</p></td>
+<td align="left" valign="top"><p class="table">2</p></td>
+<td align="left" valign="top"><p class="table">Yes</p></td>
+<td align="left" valign="top"><p class="table">No</p></td>
+<td align="left" valign="top"><p class="table">No</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">sysmoBTS 2100</p></td>
+<td align="left" valign="top"><p class="table">2x10 W</p></td>
+<td align="left" valign="top"><p class="table">2</p></td>
+<td align="left" valign="top"><p class="table">Yes</p></td>
+<td align="left" valign="top"><p class="table">No</p></td>
+<td align="left" valign="top"><p class="table">No</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_nuran_litecell_1_5">Nuran LiteCell 1.5</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="imageblock gimmick_right">
+<div class="content">
+<img src="images/litecell15.jpg" alt="images/litecell15.jpg" width="40%" />
+</div>
+</div>
+<ul class="">
+<li>
+<span>
+10W 2-TRX Outdoor BTS
+</span>
+</li>
+<li>
+<span>
+<strong>osmo-bts-litecell15</strong> uses shared-memory /dev to talk to PHY
+</span>
+</li>
+<li>
+<span>
+<strong>osmo-pcu</strong> uses shared-memory /dev to talk to PHY
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_octasic_octbts_with_octphy_2g">Octasic OCTBTS with OCTPHY-2G</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="imageblock gimmick_right">
+<div class="content">
+<img src="images/octbts_3600_photo__large.png" alt="images/octbts_3600_photo__large.png" width="40%" />
+</div>
+</div>
+<ul class="">
+<li>
+<span>
+not a ready-to-deploy BTS product, more a BTS development board
+</span>
+<ul class="">
+<li>
+<span>
+no enclosure, no PA, no filters
+</span>
+</li>
+</ul>
+</li>
+<li>
+<span>
+proprietary PHY runs in Octasic DSP
+</span>
+<ul class="">
+<li>
+<span>
+raw Ethernet frames towards <strong>osmo-bts-octphy</strong>
+</span>
+</li>
+<li>
+<span>
+unix domain pcu-socket to <strong>osmo-pcu</strong>
+</span>
+</li>
+</ul>
+</li>
+<li>
+<span>
+series of different board models (3000, 3500, 3600) with different
+ number of DSPs, radio interfaces, ARM/x86 processor core
+</span>
+</li>
+<li>
+<span>
+two TRX per DSP possible
+</span>
+</li>
+<li>
+<span>
+not all voice codecs supported
+</span>
+</li>
+<li>
+<span>
+EGRPS integration with OsmoPCU not working yet
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_eof">EOF</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>End of File</p></div>
+</div>
+</div>
+</body>
+</html>
diff --git a/2017/open_source_mobilfunk-clt2017/running-foss-gsm.adoc b/2017/open_source_mobilfunk-clt2017/running-foss-gsm.adoc
index 45ce701..47db6ae 100644
--- a/2017/open_source_mobilfunk-clt2017/running-foss-gsm.adoc
+++ b/2017/open_source_mobilfunk-clt2017/running-foss-gsm.adoc
@@ -698,4 +698,4 @@ LTE cells, similar to 3.5G strategy
* the entire Osmocom team for what they have achieved
** notably Dieter Spaar, Holger Freyther, Andreas Eversberg, Sylvain Munaut
* last but not least: CEPT for making the GSM specs English
-** (who'd want to read French specs anyway?)
+** (who'd want to read French specs here?)
diff --git a/2017/path_loss_link_budget-osmocon2017/path_loss_link_budget.html b/2017/path_loss_link_budget-osmocon2017/path_loss_link_budget.html
new file mode 100644
index 0000000..bce64b7
--- /dev/null
+++ b/2017/path_loss_link_budget-osmocon2017/path_loss_link_budget.html
@@ -0,0 +1,5039 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>Path Loss and Link Budget</title>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="copyright" content="Copyright &#169; 2017 by Harald Welte (License: CC-BY-SA)" />
+<meta name="generator" content="AsciiDoc 8.6.9" />
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+/* slidy.css
+
+ Copyright (c) 2005-2010 W3C (MIT, ERCIM, Keio), All Rights Reserved.
+ W3C liability, trademark, document use and software licensing
+ rules apply, see:
+
+ http://www.w3.org/Consortium/Legal/copyright-documents
+ http://www.w3.org/Consortium/Legal/copyright-software
+*/
+
+/*
+ SJR: 2010-09-29: Modified for AsciiDoc slidy backend.
+ Mostly just commented out stuff that is handled by AsciiDoc's CSS files.
+*/
+
+body
+{
+ margin: 0 0 0 0;
+ padding: 0 0 0 0;
+ width: 100%;
+ height: 100%;
+ color: black;
+ background-color: white;
+/*
+ font-family: "Gill Sans MT", "Gill Sans", GillSans, sans-serif;
+*/
+ font-size: 14pt;
+}
+
+div.toolbar {
+ position: fixed; z-index: 200;
+ top: auto; bottom: 0; left: 0; right: 0;
+ height: 1.2em; text-align: right;
+ padding-left: 1em;
+ padding-right: 1em;
+ font-size: 60%;
+ color: red;
+ background-color: rgb(240,240,240);
+ border-top: solid 1px rgb(180,180,180);
+}
+
+div.toolbar span.copyright {
+ color: black;
+ margin-left: 0.5em;
+}
+
+div.initial_prompt {
+ position: absolute;
+ z-index: 1000;
+ bottom: 1.2em;
+ width: 90%;
+ background-color: rgb(200,200,200);
+ opacity: 0.35;
+ background-color: rgb(200,200,200, 0.35);
+ cursor: pointer;
+}
+
+div.initial_prompt p.help {
+ text-align: center;
+}
+
+div.initial_prompt p.close {
+ text-align: right;
+ font-style: italic;
+}
+
+div.slidy_toc {
+ position: absolute;
+ z-index: 300;
+ width: 60%;
+ max-width: 30em;
+ height: 30em;
+ overflow: auto;
+ top: auto;
+ right: auto;
+ left: 4em;
+ bottom: 4em;
+ padding: 1em;
+ background: rgb(240,240,240);
+ border-style: solid;
+ border-width: 2px;
+ font-size: 60%;
+}
+
+div.slidy_toc .toc_heading {
+ text-align: center;
+ width: 100%;
+ margin: 0;
+ margin-bottom: 1em;
+ border-bottom-style: solid;
+ border-bottom-color: rgb(180,180,180);
+ border-bottom-width: 1px;
+}
+
+div.slide {
+ z-index: 20;
+ margin: 0 0 0 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ padding-left: 20px;
+ padding-right: 20px;
+ border-width: 0;
+ clear: both;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ line-height: 120%;
+ background-color: transparent;
+}
+
+div.background {
+ display: none;
+}
+
+div.handout {
+ margin-left: 20px;
+ margin-right: 20px;
+}
+
+div.slide.titlepage {
+ text-align: center;
+}
+
+div.slide.titlepage.h1 {
+ padding-top: 10%;
+}
+
+div.slide h1 {
+ padding-left: 0;
+ padding-right: 20pt;
+ padding-top: 4pt;
+ padding-bottom: 4pt;
+ margin-top: 0;
+ margin-left: 0;
+ margin-right: 60pt;
+ margin-bottom: 0.5em;
+ display: block;
+ font-size: 160%;
+ line-height: 1.2em;
+ background: transparent;
+}
+
+div.toc {
+ position: absolute;
+ top: auto;
+ bottom: 4em;
+ left: 4em;
+ right: auto;
+ width: 60%;
+ max-width: 30em;
+ height: 30em;
+ border: solid thin black;
+ padding: 1em;
+ background: rgb(240,240,240);
+ color: black;
+ z-index: 300;
+ overflow: auto;
+ display: block;
+ visibility: visible;
+}
+
+div.toc-heading {
+ width: 100%;
+ border-bottom: solid 1px rgb(180,180,180);
+ margin-bottom: 1em;
+ text-align: center;
+}
+
+/*
+pre {
+ font-size: 80%;
+ font-weight: bold;
+ line-height: 120%;
+ padding-top: 0.2em;
+ padding-bottom: 0.2em;
+ padding-left: 1em;
+ padding-right: 1em;
+ border-style: solid;
+ border-left-width: 1em;
+ border-top-width: thin;
+ border-right-width: thin;
+ border-bottom-width: thin;
+ border-color: #95ABD0;
+ color: #00428C;
+ background-color: #E4E5E7;
+}
+*/
+
+/*
+li pre { margin-left: 0; }
+
+blockquote { font-style: italic }
+
+img { background-color: transparent }
+
+p.copyright { font-size: smaller }
+*/
+
+.center { text-align: center }
+.footnote { font-size: smaller; margin-left: 2em; }
+
+/*
+a img { border-width: 0; border-style: none }
+*/
+
+a:visited { color: navy }
+a:link { color: navy }
+a:hover { color: red; text-decoration: underline }
+a:active { color: red; text-decoration: underline }
+
+a {text-decoration: none}
+.navbar a:link {color: white}
+.navbar a:visited {color: yellow}
+.navbar a:active {color: red}
+.navbar a:hover {color: red}
+
+/*
+ul { list-style-type: square; }
+ul ul { list-style-type: disc; }
+ul ul ul { list-style-type: circle; }
+ul ul ul ul { list-style-type: disc; }
+li { margin-left: 0.5em; margin-top: 0.5em; }
+li li { font-size: 85%; font-style: italic }
+li li li { font-size: 85%; font-style: normal }
+*/
+
+div dt
+{
+ margin-left: 0;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+ font-weight: bold;
+}
+div dd
+{
+ margin-left: 2em;
+ margin-bottom: 0.5em;
+}
+
+
+/*
+p,pre,ul,ol,blockquote,h2,h3,h4,h5,h6,dl,table {
+ margin-left: 1em;
+ margin-right: 1em;
+}
+*/
+
+p.subhead { font-weight: bold; margin-top: 2em; }
+
+.smaller { font-size: smaller }
+.bigger { font-size: 130% }
+
+/*
+td,th { padding: 0.2em }
+*/
+
+ul {
+ margin: 0.5em 1.5em 0.5em 1.5em;
+ padding: 0;
+}
+
+ol {
+ margin: 0.5em 1.5em 0.5em 1.5em;
+ padding: 0;
+}
+
+ul { list-style-type: square; }
+ul ul { list-style-type: disc; }
+ul ul ul { list-style-type: circle; }
+ul ul ul ul { list-style-type: disc; }
+
+/*
+ul li {
+ list-style: square;
+ margin: 0.1em 0em 0.6em 0;
+ padding: 0 0 0 0;
+ line-height: 140%;
+}
+
+ol li {
+ margin: 0.1em 0em 0.6em 1.5em;
+ padding: 0 0 0 0px;
+ line-height: 140%;
+ list-style-type: decimal;
+}
+
+li ul li {
+ font-size: 85%;
+ font-style: italic;
+ list-style-type: disc;
+ background: transparent;
+ padding: 0 0 0 0;
+}
+li li ul li {
+ font-size: 85%;
+ font-style: normal;
+ list-style-type: circle;
+ background: transparent;
+ padding: 0 0 0 0;
+}
+li li li ul li {
+ list-style-type: disc;
+ background: transparent;
+ padding: 0 0 0 0;
+}
+
+li ol li {
+ list-style-type: decimal;
+}
+
+
+li li ol li {
+ list-style-type: decimal;
+}
+*/
+
+/*
+ setting class="outline" on ol or ul makes it behave as an
+ ouline list where blocklevel content in li elements is
+ hidden by default and can be expanded or collapsed with
+ mouse click. Set class="expand" on li to override default
+*/
+
+ol.outline li:hover { cursor: pointer }
+ol.outline li.nofold:hover { cursor: default }
+
+ul.outline li:hover { cursor: pointer }
+ul.outline li.nofold:hover { cursor: default }
+
+ol.outline { list-style:decimal; }
+ol.outline ol { list-style-type:lower-alpha }
+
+ol.outline li.nofold {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/nofold-dim.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.unfolded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold-dim.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.folded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold-dim.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.unfolded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.folded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold.gif) no-repeat 0px 0.5em;
+}
+
+ul.outline li.nofold {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/nofold-dim.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.unfolded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold-dim.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.folded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold-dim.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.unfolded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.folded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold.gif) no-repeat 0px 0.5em;
+}
+
+/* for slides with class "title" in table of contents */
+a.titleslide { font-weight: bold; font-style: italic }
+
+/*
+ hide images for work around for save as bug
+ where browsers fail to save images used by CSS
+*/
+img.hidden { display: none; visibility: hidden }
+div.initial_prompt { display: none; visibility: hidden }
+
+ div.slide {
+ visibility: visible;
+ position: inherit;
+ }
+ div.handout {
+ border-top-style: solid;
+ border-top-width: thin;
+ border-top-color: black;
+ }
+
+@media screen {
+ .hidden { display: none; visibility: visible }
+
+ div.slide.hidden { display: block; visibility: visible }
+ div.handout.hidden { display: block; visibility: visible }
+ div.background { display: none; visibility: hidden }
+ body.single_slide div.initial_prompt { display: block; visibility: visible }
+ body.single_slide div.background { display: block; visibility: visible }
+ body.single_slide div.background.hidden { display: none; visibility: hidden }
+ body.single_slide .invisible { visibility: hidden }
+ body.single_slide .hidden { display: none; visibility: hidden }
+ body.single_slide div.slide { position: absolute }
+ body.single_slide div.handout { display: none; visibility: hidden }
+}
+
+@media print {
+ .hidden { display: block; visibility: visible }
+
+/*
+ div.slide pre { font-size: 60%; padding-left: 0.5em; }
+*/
+ div.toolbar { display: none; visibility: hidden; }
+ div.slidy_toc { display: none; visibility: hidden; }
+ div.background { display: none; visibility: hidden; }
+ div.slide { page-break-before: always }
+ /* :first-child isn't reliable for print media */
+ div.slide.first-slide { page-break-before: avoid }
+}
+
+
+/* SJR: AsciiDoc slidy backend tweaks */
+
+ol, ul {
+ margin: 0.8em 1.5em 0.8em 1.8em;
+}
+li > ul, li > ol {
+ margin-top: 0.5em;
+}
+
+.outline > li.folded,
+.outline > li.unfolded {
+ color: #527bbd;
+}
+ul > li{ color: #aaa; }
+ul > li > *, ol > li > * { color: black; }
+
+li {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+/* slidy.js
+
+ Copyright (c) 2005-2010 W3C (MIT, ERCIM, Keio), All Rights Reserved.
+ W3C liability, trademark, document use and software licensing
+ rules apply, see:
+
+ http://www.w3.org/Consortium/Legal/copyright-documents
+ http://www.w3.org/Consortium/Legal/copyright-software
+*/
+
+// the slidy object implementation
+var w3c_slidy = {
+ // classify which kind of browser we're running under
+ ns_pos: (typeof window.pageYOffset!='undefined'),
+ khtml: ((navigator.userAgent).indexOf("KHTML") >= 0 ? true : false),
+ opera: ((navigator.userAgent).indexOf("Opera") >= 0 ? true : false),
+ ipad: ((navigator.userAgent).indexOf("iPad") >= 0 ? true : false),
+ iphone: ((navigator.userAgent).indexOf("iPhone") >= 0 ? true : false),
+ ie: (typeof document.all != "undefined" && !this.opera),
+ ie6: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 6") != -1),
+ ie7: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 7") != -1),
+ ie8: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 8") != -1),
+ ie9: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 9") != -1),
+ keyboardless: (this.ipad || this.iphone),
+
+ // are we running as XHTML? (doesn't work on Opera)
+ is_xhtml: /xml/.test(document.contentType),
+
+ slide_number: 0, // integer slide count: 0, 1, 2, ...
+ slide_number_element: null, // element containing slide number
+ slides: [], // set to array of slide div's
+ notes: [], // set to array of handout div's
+ backgrounds: [], // set to array of background div's
+ toolbar: null, // element containing toolbar
+ title: null, // document title
+ last_shown: null, // last incrementally shown item
+ eos: null, // span element for end of slide indicator
+ toc: null, // table of contents
+ outline: null, // outline element with the focus
+ selected_text_len: 0, // length of drag selection on document
+ view_all: 0, // 1 to view all slides + handouts
+ want_toolbar: true, // user preference to show/hide toolbar
+ mouse_click_enabled: true, // enables left click for next slide
+ scroll_hack: 0, // IE work around for position: fixed
+ disable_slide_click: false, // used by clicked anchors
+
+ lang: "en", // updated to language specified by html file
+
+ help_anchor: null, // used for keyboard focus hack in showToolbar()
+ help_page: "http://www.w3.org/Talks/Tools/Slidy2/help/help.html",
+ help_text: "Navigate with mouse click, space bar, Cursor Left/Right, " +
+ "or Pg Up and Pg Dn. Use S and B to change font size.",
+
+ size_index: 0,
+ size_adjustment: 0,
+ sizes: new Array("10pt", "12pt", "14pt", "16pt", "18pt", "20pt",
+ "22pt", "24pt", "26pt", "28pt", "30pt", "32pt"),
+
+ // needed for efficient resizing
+ last_width: 0,
+ last_height: 0,
+
+
+ // Needed for cross browser support for relative width/height on
+ // object elements. The work around is to save width/height attributes
+ // and then to recompute absolute width/height dimensions on resizing
+ objects: [],
+
+ // attach initialiation event handlers
+ set_up: function () {
+ var init = function() { w3c_slidy.init(); };
+ if (typeof window.addEventListener != "undefined")
+ window.addEventListener("load", init, false);
+ else
+ window.attachEvent("onload", init);
+ },
+
+ hide_slides: function () {
+ if (document.body && !w3c_slidy.initialized)
+ document.body.style.visibility = "hidden";
+ else
+ setTimeout(w3c_slidy.hide_slides, 50);
+ },
+
+ // hack to persuade IE to compute correct document height
+ // as needed for simulating fixed positioning of toolbar
+ ie_hack: function () {
+ window.resizeBy(0,-1);
+ window.resizeBy(0, 1);
+ },
+
+ init: function () {
+ //alert("slidy starting test 10");
+ document.body.style.visibility = "visible";
+ w3c_slidy_i18n.init();
+ this.add_toolbar();
+ this.wrap_implicit_slides();
+ this.collect_slides();
+ this.collect_notes();
+ this.collect_backgrounds();
+ this.objects = document.body.getElementsByTagName("object");
+ this.patch_anchors();
+ this.slide_number = this.find_slide_number(location.href);
+ window.offscreenbuffering = true;
+ this.size_adjustment = this.find_size_adjust();
+ this.time_left = this.find_duration();
+ this.hide_image_toolbar(); // suppress IE image toolbar popup
+ this.init_outliner(); // activate fold/unfold support
+ this.title = document.title;
+
+ // work around for opera bug
+ this.is_xhtml = (document.body.tagName == "BODY" ? false : true);
+
+ if (this.slides.length > 0)
+ {
+ var slide = this.slides[this.slide_number];
+
+ if (this.slide_number > 0)
+ {
+ this.set_visibility_all_incremental("visible");
+ this.last_shown = this.previous_incremental_item(null);
+ this.set_eos_status(true);
+ }
+ else
+ {
+ this.last_shown = null;
+ this.set_visibility_all_incremental("hidden");
+ this.set_eos_status(!this.next_incremental_item(this.last_shown));
+ }
+
+ this.set_location();
+ this.add_class(this.slides[0], "first-slide");
+ w3c_slidy.show_slide(slide);
+ }
+
+ this.toc = this.table_of_contents();
+
+ this.add_initial_prompt();
+
+ // bind event handlers without interfering with custom page scripts
+ // Tap events behave too weirdly to support clicks reliably on
+ // iPhone and iPad, so exclude these from click handler
+
+ if (!this.keyboardless)
+ this.add_listener(document.body, "click", this.mouse_button_click);
+
+ this.add_listener(document, "keydown", this.key_down);
+ this.add_listener(document, "keypress", this.key_press);
+ this.add_listener(window, "resize", this.resized);
+ this.add_listener(window, "scroll", this.scrolled);
+ this.add_listener(window, "unload", this.unloaded);
+
+ if (!document.body.onclick)
+ document.body.onclick = function () { };
+
+ this.single_slide_view();
+
+ //this.set_location();
+
+ this.resized();
+
+ if (this.ie7)
+ setTimeout(w3c_slidy.ie_hack, 100);
+
+ this.show_toolbar();
+
+ // for back button detection
+ setInterval(function () { w3c_slidy.check_location(); }, 200);
+ w3c_slidy.initialized = true;
+ },
+
+ // create div element with links to each slide
+ table_of_contents: function () {
+ var toc = this.create_element("div");
+ this.add_class(toc, "slidy_toc hidden");
+ //toc.setAttribute("tabindex", "0");
+
+ var heading = this.create_element("div");
+ this.add_class(heading, "toc-heading");
+ heading.innerHTML = "Table of Contents".localize();
+
+ toc.appendChild(heading);
+ var previous = null;
+
+ for (var i = 0; i < this.slides.length; ++i)
+ {
+ var title = this.has_class(this.slides[i], "title");
+ var num = document.createTextNode((i + 1) + ". ");
+
+ toc.appendChild(num);
+
+ var a = this.create_element("a");
+ a.setAttribute("href", "#(" + (i+1) + ")");
+
+ if (title)
+ this.add_class(a, "titleslide");
+
+ var name = document.createTextNode(this.slide_name(i));
+ a.appendChild(name);
+ a.onclick = w3c_slidy.toc_click;
+ a.onkeydown = w3c_slidy.toc_keydown;
+ a.previous = previous;
+
+ if (previous)
+ previous.next = a;
+
+ toc.appendChild(a);
+
+ if (i == 0)
+ toc.first = a;
+
+ if (i < this.slides.length - 1)
+ {
+ var br = this.create_element("br");
+ toc.appendChild(br);
+ }
+
+ previous = a;
+ }
+
+ toc.focus = function () {
+ if (this.first)
+ this.first.focus();
+ }
+
+ toc.onmouseup = w3c_slidy.mouse_button_up;
+
+ toc.onclick = function (e) {
+ e||(e=window.event);
+
+ if (w3c_slidy.selected_text_len <= 0)
+ w3c_slidy.hide_table_of_contents();
+
+ w3c_slidy.stop_propagation(e);
+
+ if (e.cancel != undefined)
+ e.cancel = true;
+
+ if (e.returnValue != undefined)
+ e.returnValue = false;
+
+ return false;
+ };
+
+ document.body.insertBefore(toc, document.body.firstChild);
+ return toc;
+ },
+
+ is_shown_toc: function () {
+ return !w3c_slidy.has_class(w3c_slidy.toc, "hidden");
+ },
+
+ show_table_of_contents: function () {
+ w3c_slidy.remove_class(w3c_slidy.toc, "hidden");
+ var toc = w3c_slidy.toc;
+ toc.focus();
+
+ if (w3c_slidy.ie7 && w3c_slidy.slide_number == 0)
+ setTimeout(w3c_slidy.ie_hack, 100);
+ },
+
+ hide_table_of_contents: function () {
+ w3c_slidy.add_class(w3c_slidy.toc, "hidden");
+
+ if (!w3c_slidy.opera)
+ w3c_slidy.help_anchor.focus();
+ },
+
+ toggle_table_of_contents: function () {
+ if (w3c_slidy.is_shown_toc())
+ w3c_slidy.hide_table_of_contents();
+ else
+ w3c_slidy.show_table_of_contents();
+ },
+
+ // called on clicking toc entry
+ toc_click: function (e) {
+ if (!e)
+ e = window.event;
+
+ var target = w3c_slidy.get_target(e);
+
+ if (target && target.nodeType == 1)
+ {
+ var uri = target.getAttribute("href");
+
+ if (uri)
+ {
+ //alert("going to " + uri);
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.slide_number = w3c_slidy.find_slide_number(uri);
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_location();
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+ w3c_slidy.show_slide(slide);
+ //target.focus();
+
+ try
+ {
+ if (!w3c_slidy.opera)
+ w3c_slidy.help_anchor.focus();
+ }
+ catch (e)
+ {
+ }
+ }
+ }
+
+ w3c_slidy.hide_table_of_contents(e);
+ if (w3c_slidy.ie7) w3c_slidy.ie_hack();
+ w3c_slidy.stop_propagation(e);
+ return w3c_slidy.cancel(e);
+ },
+
+ // called onkeydown for toc entry
+ toc_keydown: function (event) {
+ var key;
+
+ if (!event)
+ var event = window.event;
+
+ // kludge around NS/IE differences
+ if (window.event)
+ key = window.event.keyCode;
+ else if (event.which)
+ key = event.which;
+ else
+ return true; // Yikes! unknown browser
+
+ // ignore event if key value is zero
+ // as for alt on Opera and Konqueror
+ if (!key)
+ return true;
+
+ // check for concurrent control/command/alt key
+ // but are these only present on mouse events?
+
+ if (event.ctrlKey || event.altKey)
+ return true;
+
+ if (key == 13)
+ {
+ var uri = this.getAttribute("href");
+
+ if (uri)
+ {
+ //alert("going to " + uri);
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.slide_number = w3c_slidy.find_slide_number(uri);
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_location();
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+ w3c_slidy.show_slide(slide);
+ //target.focus();
+
+ try
+ {
+ if (!w3c_slidy.opera)
+ w3c_slidy.help_anchor.focus();
+ }
+ catch (e)
+ {
+ }
+ }
+
+ w3c_slidy.hide_table_of_contents();
+
+ if (self.ie7)
+ w3c_slidy.ie_hack();
+
+ return w3c_slidy.cancel(event);
+ }
+
+ if (key == 40 && this.next)
+ {
+ this.next.focus();
+ return w3c_slidy.cancel(event);
+ }
+
+ if (key == 38 && this.previous)
+ {
+ this.previous.focus();
+ return w3c_slidy.cancel(event);
+ }
+
+ return true;
+ },
+
+
+ // ### OBSOLETE ###
+ before_print: function () {
+ this.show_all_slides();
+ this.hide_toolbar();
+ alert("before print");
+ },
+
+ // ### OBSOLETE ###
+ after_print: function () {
+ if (!this.view_all)
+ {
+ this.single_slide_view();
+ this.show_toolbar();
+ }
+ alert("after print");
+ },
+
+ // ### OBSOLETE ###
+ print_slides: function () {
+ this.before_print();
+ window.print();
+ this.after_print();
+ },
+
+ // ### OBSOLETE ?? ###
+ toggle_view: function () {
+ if (this.view_all)
+ {
+ this.single_slide_view();
+ this.show_toolbar();
+ this.view_all = 0;
+ }
+ else
+ {
+ this.show_all_slides();
+ this.hide_toolbar();
+ this.view_all = 1;
+ }
+ },
+
+ // prepare for printing ### OBSOLETE ###
+ show_all_slides: function () {
+ this.remove_class(document.body, "single_slide");
+ this.set_visibility_all_incremental("visible");
+ },
+
+ // restore after printing ### OBSOLETE ###
+ single_slide_view: function () {
+ this.add_class(document.body, "single_slide");
+ this.set_visibility_all_incremental("visible");
+ this.last_shown = this.previous_incremental_item(null);
+ },
+
+ // suppress IE's image toolbar pop up
+ hide_image_toolbar: function () {
+ if (!this.ns_pos)
+ {
+ var images = document.getElementsByTagName("IMG");
+
+ for (var i = 0; i < images.length; ++i)
+ images[i].setAttribute("galleryimg", "no");
+ }
+ },
+
+ unloaded: function (e) {
+ //alert("unloaded");
+ },
+
+ // Safari and Konqueror don't yet support getComputedStyle()
+ // and they always reload page when location.href is updated
+ is_KHTML: function () {
+ var agent = navigator.userAgent;
+ return (agent.indexOf("KHTML") >= 0 ? true : false);
+ },
+
+ // find slide name from first h1 element
+ // default to document title + slide number
+ slide_name: function (index) {
+ var name = null;
+ var slide = this.slides[index];
+
+ var heading = this.find_heading(slide);
+
+ if (heading)
+ name = this.extract_text(heading);
+
+ if (!name)
+ name = this.title + "(" + (index + 1) + ")";
+
+ name.replace(/\&/g, "&amp;");
+ name.replace(/\</g, "&lt;");
+ name.replace(/\>/g, "&gt;");
+
+ return name;
+ },
+
+ // find first h1 element in DOM tree
+ find_heading: function (node) {
+ if (!node || node.nodeType != 1)
+ return null;
+
+ if (node.nodeName == "H1" || node.nodeName == "h1")
+ return node;
+
+ var child = node.firstChild;
+
+ while (child)
+ {
+ node = this.find_heading(child);
+
+ if (node)
+ return node;
+
+ child = child.nextSibling;
+ }
+
+ return null;
+ },
+
+ // recursively extract text from DOM tree
+ extract_text: function (node) {
+ if (!node)
+ return "";
+
+ // text nodes
+ if (node.nodeType == 3)
+ return node.nodeValue;
+
+ // elements
+ if (node.nodeType == 1)
+ {
+ node = node.firstChild;
+ var text = "";
+
+ while (node)
+ {
+ text = text + this.extract_text(node);
+ node = node.nextSibling;
+ }
+
+ return text;
+ }
+
+ return "";
+ },
+
+ // find copyright text from meta element
+ find_copyright: function () {
+ var name, content;
+ var meta = document.getElementsByTagName("meta");
+
+ for (var i = 0; i < meta.length; ++i)
+ {
+ name = meta[i].getAttribute("name");
+ content = meta[i].getAttribute("content");
+
+ if (name == "copyright")
+ return content;
+ }
+
+ return null;
+ },
+
+ find_size_adjust: function () {
+ var name, content, offset;
+ var meta = document.getElementsByTagName("meta");
+
+ for (var i = 0; i < meta.length; ++i)
+ {
+ name = meta[i].getAttribute("name");
+ content = meta[i].getAttribute("content");
+
+ if (name == "font-size-adjustment")
+ return 1 * content;
+ }
+
+ return 1;
+ },
+
+ // <meta name="duration" content="20" /> for 20 minutes
+ find_duration: function () {
+ var name, content, offset;
+ var meta = document.getElementsByTagName("meta");
+
+ for (var i = 0; i < meta.length; ++i)
+ {
+ name = meta[i].getAttribute("name");
+ content = meta[i].getAttribute("content");
+
+ if (name == "duration")
+ return 60000 * content;
+ }
+
+ return null;
+ },
+
+ replace_by_non_breaking_space: function (str) {
+ for (var i = 0; i < str.length; ++i)
+ str[i] = 160;
+ },
+
+ // ### CHECK ME ### is use of "li" okay for text/html?
+ // for XHTML do we also need to specify namespace?
+ init_outliner: function () {
+ var items = document.getElementsByTagName("li");
+
+ for (var i = 0; i < items.length; ++i)
+ {
+ var target = items[i];
+
+ if (!this.has_class(target.parentNode, "outline"))
+ continue;
+
+ target.onclick = this.outline_click;
+/* ### more work needed for IE6
+ if (!this.ns_pos)
+ {
+ target.onmouseover = this.hover_outline;
+ target.onmouseout = this.unhover_outline;
+ }
+*/
+ if (this.foldable(target))
+ {
+ target.foldable = true;
+ target.onfocus = function () {w3c_slidy.outline = this;};
+ target.onblur = function () {w3c_slidy.outline = null;};
+
+ if (!target.getAttribute("tabindex"))
+ target.setAttribute("tabindex", "0");
+
+ if (this.has_class(target, "expand"))
+ this.unfold(target);
+ else
+ this.fold(target);
+ }
+ else
+ {
+ this.add_class(target, "nofold");
+ target.visible = true;
+ target.foldable = false;
+ }
+ }
+ },
+
+ foldable: function (item) {
+ if (!item || item.nodeType != 1)
+ return false;
+
+ var node = item.firstChild;
+
+ while (node)
+ {
+ if (node.nodeType == 1 && this.is_block(node))
+ return true;
+
+ node = node.nextSibling;
+ }
+
+ return false;
+ },
+
+ // ### CHECK ME ### switch to add/remove "hidden" class
+ fold: function (item) {
+ if (item)
+ {
+ this.remove_class(item, "unfolded");
+ this.add_class(item, "folded");
+ }
+
+ var node = item ? item.firstChild : null;
+
+ while (node)
+ {
+ if (node.nodeType == 1 && this.is_block(node)) // element
+ {
+ w3c_slidy.add_class(node, "hidden");
+ }
+
+ node = node.nextSibling;
+ }
+
+ item.visible = false;
+ },
+
+ // ### CHECK ME ### switch to add/remove "hidden" class
+ unfold: function (item) {
+ if (item)
+ {
+ this.add_class(item, "unfolded");
+ this.remove_class(item, "folded");
+ }
+
+ var node = item ? item.firstChild : null;
+
+ while (node)
+ {
+ if (node.nodeType == 1 && this.is_block(node)) // element
+ {
+ w3c_slidy.remove_class(node, "hidden");
+ }
+
+ node = node.nextSibling;
+ }
+
+ item.visible = true;
+ },
+
+ outline_click: function (e) {
+ if (!e)
+ e = window.event;
+
+ var rightclick = false;
+ var target = w3c_slidy.get_target(e);
+
+ while (target && target.visible == undefined)
+ target = target.parentNode;
+
+ if (!target)
+ return true;
+
+ if (e.which)
+ rightclick = (e.which == 3);
+ else if (e.button)
+ rightclick = (e.button == 2);
+
+ if (!rightclick && target.visible != undefined)
+ {
+ if (target.foldable)
+ {
+ if (target.visible)
+ w3c_slidy.fold(target);
+ else
+ w3c_slidy.unfold(target);
+ }
+
+ w3c_slidy.stop_propagation(e);
+ e.cancel = true;
+ e.returnValue = false;
+ }
+
+ return false;
+ },
+
+ add_initial_prompt: function () {
+ var prompt = this.create_element("div");
+ prompt.setAttribute("class", "initial_prompt");
+
+ var p1 = this.create_element("p");
+ prompt.appendChild(p1);
+ p1.setAttribute("class", "help");
+
+ if (this.keyboardless)
+ p1.innerHTML = "Tap footer to move to next slide";
+ else
+ p1.innerHTML = "Space or Right Arrow to move to next " +
+ "slide, click help below for more details";
+
+ this.add_listener(prompt, "click", function (e) {
+ document.body.removeChild(prompt);
+ w3c_slidy.stop_propagation(e);
+
+ if (e.cancel != undefined)
+ e.cancel = true;
+
+ if (e.returnValue != undefined)
+ e.returnValue = false;
+
+ return false;
+ });
+
+ document.body.appendChild(prompt);
+ this.initial_prompt = prompt;
+ setTimeout(function() {document.body.removeChild(prompt);}, 5000);
+ },
+
+ add_toolbar: function () {
+ var counter, page;
+
+ this.toolbar = this.create_element("div");
+ this.toolbar.setAttribute("class", "toolbar");
+
+ // a reasonably behaved browser
+ if (this.ns_pos || !this.ie6)
+ {
+ var right = this.create_element("div");
+ right.setAttribute("style", "float: right; text-align: right");
+
+ counter = this.create_element("span")
+ counter.innerHTML = "slide".localize() + " n/m";
+ right.appendChild(counter);
+ this.toolbar.appendChild(right);
+
+ var left = this.create_element("div");
+ left.setAttribute("style", "text-align: left");
+
+ // global end of slide indicator
+ this.eos = this.create_element("span");
+ this.eos.innerHTML = "* ";
+ left.appendChild(this.eos);
+
+ var help = this.create_element("a");
+ help.setAttribute("href", this.help_page);
+ help.setAttribute("title", this.help_text.localize());
+ help.innerHTML = "help?".localize();
+ left.appendChild(help);
+ this.help_anchor = help; // save for focus hack
+
+ var gap1 = document.createTextNode(" ");
+ left.appendChild(gap1);
+
+ var contents = this.create_element("a");
+ contents.setAttribute("href", "javascript:w3c_slidy.toggle_table_of_contents()");
+ contents.setAttribute("title", "table of contents".localize());
+ contents.innerHTML = "contents?".localize();
+ left.appendChild(contents);
+
+ var gap2 = document.createTextNode(" ");
+ left.appendChild(gap2);
+
+ var copyright = this.find_copyright();
+
+ if (copyright)
+ {
+ var span = this.create_element("span");
+ span.className = "copyright";
+ span.innerHTML = copyright;
+ left.appendChild(span);
+ }
+
+ this.toolbar.setAttribute("tabindex", "0");
+ this.toolbar.appendChild(left);
+ }
+ else // IE6 so need to work around its poor CSS support
+ {
+ this.toolbar.style.position = (this.ie7 ? "fixed" : "absolute");
+ this.toolbar.style.zIndex = "200";
+ this.toolbar.style.width = "99.9%";
+ this.toolbar.style.height = "1.2em";
+ this.toolbar.style.top = "auto";
+ this.toolbar.style.bottom = "0";
+ this.toolbar.style.left = "0";
+ this.toolbar.style.right = "0";
+ this.toolbar.style.textAlign = "left";
+ this.toolbar.style.fontSize = "60%";
+ this.toolbar.style.color = "red";
+ this.toolbar.borderWidth = 0;
+ this.toolbar.className = "toolbar";
+ this.toolbar.style.background = "rgb(240,240,240)";
+
+ // would like to have help text left aligned
+ // and page counter right aligned, floating
+ // div's don't work, so instead use nested
+ // absolutely positioned div's.
+
+ var sp = this.create_element("span");
+ sp.innerHTML = "&nbsp;&nbsp;*&nbsp;";
+ this.toolbar.appendChild(sp);
+ this.eos = sp; // end of slide indicator
+
+ var help = this.create_element("a");
+ help.setAttribute("href", this.help_page);
+ help.setAttribute("title", this.help_text.localize());
+ help.innerHTML = "help?".localize();
+ this.toolbar.appendChild(help);
+ this.help_anchor = help; // save for focus hack
+
+ var gap1 = document.createTextNode(" ");
+ this.toolbar.appendChild(gap1);
+
+ var contents = this.create_element("a");
+ contents.setAttribute("href", "javascript:toggleTableOfContents()");
+ contents.setAttribute("title", "table of contents".localize());
+ contents.innerHTML = "contents?".localize();
+ this.toolbar.appendChild(contents);
+
+ var gap2 = document.createTextNode(" ");
+ this.toolbar.appendChild(gap2);
+
+ var copyright = this.find_copyright();
+
+ if (copyright)
+ {
+ var span = this.create_element("span");
+ span.innerHTML = copyright;
+ span.style.color = "black";
+ span.style.marginLeft = "0.5em";
+ this.toolbar.appendChild(span);
+ }
+
+ counter = this.create_element("div")
+ counter.style.position = "absolute";
+ counter.style.width = "auto"; //"20%";
+ counter.style.height = "1.2em";
+ counter.style.top = "auto";
+ counter.style.bottom = 0;
+ counter.style.right = "0";
+ counter.style.textAlign = "right";
+ counter.style.color = "red";
+ counter.style.background = "rgb(240,240,240)";
+
+ counter.innerHTML = "slide".localize() + " n/m";
+ this.toolbar.appendChild(counter);
+ }
+
+ // ensure that click isn't passed through to the page
+ this.toolbar.onclick =
+ function (e) {
+ if (!e)
+ e = window.event;
+
+ var target = e.target;
+
+ if (!target && e.srcElement)
+ target = e.srcElement;
+
+ // work around Safari bug
+ if (target && target.nodeType == 3)
+ target = target.parentNode;
+
+ w3c_slidy.stop_propagation(e);
+
+ if (target && target.nodeName.toLowerCase() != "a")
+ w3c_slidy.mouse_button_click(e);
+ };
+
+ this.slide_number_element = counter;
+ this.set_eos_status(false);
+ document.body.appendChild(this.toolbar);
+ },
+
+ // wysiwyg editors make it hard to use div elements
+ // e.g. amaya loses the div when you copy and paste
+ // this function wraps div elements around implicit
+ // slides which start with an h1 element and continue
+ // up to the next heading or div element
+ wrap_implicit_slides: function () {
+ var i, heading, node, next, div;
+ var headings = document.getElementsByTagName("h1");
+
+ if (!headings)
+ return;
+
+ for (i = 0; i < headings.length; ++i)
+ {
+ heading = headings[i];
+
+ if (heading.parentNode != document.body)
+ continue;
+
+ node = heading.nextSibling;
+
+ div = document.createElement("div");
+ this.add_class(div, "slide");
+ document.body.replaceChild(div, heading);
+ div.appendChild(heading);
+
+ while (node)
+ {
+ if (node.nodeType == 1 && // an element
+ (node.nodeName == "H1" ||
+ node.nodeName == "h1" ||
+ node.nodeName == "DIV" ||
+ node.nodeName == "div"))
+ break;
+
+ next = node.nextSibling;
+ node = document.body.removeChild(node);
+ div.appendChild(node);
+ node = next;
+ }
+ }
+ },
+
+// return new array of all slides
+ collect_slides: function () {
+ var slides = new Array();
+ var divs = document.body.getElementsByTagName("div");
+
+ for (var i = 0; i < divs.length; ++i)
+ {
+ div = divs.item(i);
+
+ if (this.has_class(div, "slide"))
+ {
+ // add slide to collection
+ slides[slides.length] = div;
+
+ // hide each slide as it is found
+ this.add_class(div, "hidden");
+
+ // add dummy <br/> at end for scrolling hack
+ var node1 = document.createElement("br");
+ div.appendChild(node1);
+ var node2 = document.createElement("br");
+ div.appendChild(node2);
+ }
+ else if (this.has_class(div, "background"))
+ { // work around for Firefox SVG reload bug
+ // which otherwise replaces 1st SVG graphic with 2nd
+ div.style.display = "block";
+ }
+ }
+
+ this.slides = slides;
+ },
+
+ // return new array of all <div class="handout">
+ collect_notes: function () {
+ var notes = new Array();
+ var divs = document.body.getElementsByTagName("div");
+
+ for (var i = 0; i < divs.length; ++i)
+ {
+ div = divs.item(i);
+
+ if (this.has_class(div, "handout"))
+ {
+ // add note to collection
+ notes[notes.length] = div;
+
+ // and hide it
+ this.add_class(div, "hidden");
+ }
+ }
+
+ this.notes = notes;
+ },
+
+ // return new array of all <div class="background">
+ // including named backgrounds e.g. class="background titlepage"
+ collect_backgrounds: function () {
+ var backgrounds = new Array();
+ var divs = document.body.getElementsByTagName("div");
+
+ for (var i = 0; i < divs.length; ++i)
+ {
+ div = divs.item(i);
+
+ if (this.has_class(div, "background"))
+ {
+ // add background to collection
+ backgrounds[backgrounds.length] = div;
+
+ // and hide it
+ this.add_class(div, "hidden");
+ }
+ }
+
+ this.backgrounds = backgrounds;
+ },
+
+ // set click handlers on all anchors
+ patch_anchors: function () {
+ var self = w3c_slidy;
+ var handler = function (event) {
+ // compare this.href with location.href
+ // for link to another slide in this doc
+
+ if (self.page_address(this.href) == self.page_address(location.href))
+ {
+ // yes, so find new slide number
+ var newslidenum = self.find_slide_number(this.href);
+
+ if (newslidenum != self.slide_number)
+ {
+ var slide = self.slides[self.slide_number];
+ self.hide_slide(slide);
+ self.slide_number = newslidenum;
+ slide = self.slides[self.slide_number];
+ self.show_slide(slide);
+ self.set_location();
+ }
+ }
+ else if (this.target == null)
+ location.href = this.href;
+
+ this.blur();
+ self.disable_slide_click = true;
+ };
+
+ var anchors = document.body.getElementsByTagName("a");
+
+ for (var i = 0; i < anchors.length; ++i)
+ {
+ if (window.addEventListener)
+ anchors[i].addEventListener("click", handler, false);
+ else
+ anchors[i].attachEvent("onclick", handler);
+ }
+ },
+
+ // ### CHECK ME ### see which functions are invoked via setTimeout
+ // either directly or indirectly for use of w3c_slidy vs this
+ show_slide_number: function () {
+ var timer = w3c_slidy.get_timer();
+ w3c_slidy.slide_number_element.innerHTML = timer + "slide".localize() + " " +
+ (w3c_slidy.slide_number + 1) + "/" + w3c_slidy.slides.length;
+ },
+
+ // every 200mS check if the location has been changed as a
+ // result of the user activating the Back button/menu item
+ // doesn't work for Opera < 9.5
+ check_location: function () {
+ var hash = location.hash;
+
+ if (w3c_slidy.slide_number > 0 && (hash == "" || hash == "#"))
+ w3c_slidy.goto_slide(0);
+ else if (hash.length > 2 && hash != "#("+(w3c_slidy.slide_number+1)+")")
+ {
+ var num = parseInt(location.hash.substr(2));
+
+ if (!isNaN(num))
+ w3c_slidy.goto_slide(num-1);
+ }
+
+ if (w3c_slidy.time_left && w3c_slidy.slide_number > 0)
+ {
+ w3c_slidy.show_slide_number();
+
+ if (w3c_slidy.time_left > 0)
+ w3c_slidy.time_left -= 200;
+ }
+ },
+
+ get_timer: function () {
+ var timer = "";
+ if (w3c_slidy.time_left)
+ {
+ var mins, secs;
+ secs = Math.floor(w3c_slidy.time_left/1000);
+ mins = Math.floor(secs / 60);
+ secs = secs % 60;
+ timer = (mins ? mins+"m" : "") + secs + "s ";
+ }
+
+ return timer;
+ },
+
+ // this doesn't push location onto history stack for IE
+ // for which a hidden iframe hack is needed: load page into
+ // the iframe with script that set's parent's location.hash
+ // but that won't work for standalone use unless we can
+ // create the page dynamically via a javascript: URL
+ set_location: function () {
+ var uri = w3c_slidy.page_address(location.href);
+ var hash = "#(" + (w3c_slidy.slide_number+1) + ")";
+
+ if (w3c_slidy.slide_number >= 0)
+ uri = uri + hash;
+
+ if (w3c_slidy.ie && !w3c_slidy.ie8)
+ w3c_slidy.push_hash(hash);
+
+ if (uri != location.href) // && !khtml
+ location.href = uri;
+
+ if (this.khtml)
+ hash = "(" + (w3c_slidy.slide_number+1) + ")";
+
+ if (!this.ie && location.hash != hash && location.hash != "")
+ location.hash = hash;
+
+ document.title = w3c_slidy.title + " (" + (w3c_slidy.slide_number+1) + ")";
+ w3c_slidy.show_slide_number();
+ },
+
+ page_address: function (uri) {
+ var i = uri.indexOf("#");
+
+ if (i < 0)
+ i = uri.indexOf("%23");
+
+ // check if anchor is entire page
+
+ if (i < 0)
+ return uri; // yes
+
+ return uri.substr(0, i);
+ },
+
+ // only used for IE6 and IE7
+ on_frame_loaded: function (hash) {
+ location.hash = hash;
+ var uri = w3c_slidy.page_address(location.href);
+ location.href = uri + hash;
+ },
+
+ // history hack with thanks to Bertrand Le Roy
+ push_hash: function (hash) {
+ if (hash == "") hash = "#(1)";
+ window.location.hash = hash;
+
+ var doc = document.getElementById("historyFrame").contentWindow.document;
+ doc.open("javascript:'<html></html>'");
+ // PWL modified this string literal to break the close script tag
+ // which otherwise gets parsed when incorporated
+ doc.write("<html><head><script type=\"text/javascript\">window.parent.w3c_slidy.on_frame_loaded('"+
+ (hash) + "');</" + "script></head><body>hello mum</body></html>");
+ doc.close();
+ },
+
+ // find current slide based upon location
+ // first find target anchor and then look
+ // for associated div element enclosing it
+ // finally map that to slide number
+ find_slide_number: function (uri) {
+ // first get anchor from page location
+
+ var i = uri.indexOf("#");
+
+ // check if anchor is entire page
+ if (i < 0)
+ return 0; // yes
+
+ var anchor = unescape(uri.substr(i+1));
+
+ // now use anchor as XML ID to find target
+ var target = document.getElementById(anchor);
+
+ if (!target)
+ {
+ // does anchor look like "(2)" for slide 2 ??
+ // where first slide is (1)
+ var re = /\((\d)+\)/;
+
+ if (anchor.match(re))
+ {
+ var num = parseInt(anchor.substring(1, anchor.length-1));
+
+ if (num > this.slides.length)
+ num = 1;
+
+ if (--num < 0)
+ num = 0;
+
+ return num;
+ }
+
+ // accept [2] for backwards compatibility
+ re = /\[(\d)+\]/;
+
+ if (anchor.match(re))
+ {
+ var num = parseInt(anchor.substring(1, anchor.length-1));
+
+ if (num > this.slides.length)
+ num = 1;
+
+ if (--num < 0)
+ num = 0;
+
+ return num;
+ }
+
+ // oh dear unknown anchor
+ return 0;
+ }
+
+ // search for enclosing slide
+
+ while (true)
+ {
+ // browser coerces html elements to uppercase!
+ if (target.nodeName.toLowerCase() == "div" &&
+ this.has_class(target, "slide"))
+ {
+ // found the slide element
+ break;
+ }
+
+ // otherwise try parent element if any
+
+ target = target.parentNode;
+
+ if (!target)
+ {
+ return 0; // no luck!
+ }
+ };
+
+ for (i = 0; i < slides.length; ++i)
+ {
+ if (slides[i] == target)
+ return i; // success
+ }
+
+ // oh dear still no luck
+ return 0;
+ },
+
+ previous_slide: function (incremental) {
+ if (!w3c_slidy.view_all)
+ {
+ var slide;
+
+ if ((incremental || w3c_slidy.slide_number == 0) && w3c_slidy.last_shown != null)
+ {
+ w3c_slidy.last_shown = w3c_slidy.hide_previous_item(w3c_slidy.last_shown);
+ w3c_slidy.set_eos_status(false);
+ }
+ else if (w3c_slidy.slide_number > 0)
+ {
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+
+ w3c_slidy.slide_number = w3c_slidy.slide_number - 1;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.set_visibility_all_incremental("visible");
+ w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null);
+ w3c_slidy.set_eos_status(true);
+ w3c_slidy.show_slide(slide);
+ }
+
+ w3c_slidy.set_location();
+
+ if (!w3c_slidy.ns_pos)
+ w3c_slidy.refresh_toolbar(200);
+ }
+ },
+
+ next_slide: function (incremental) {
+ if (!w3c_slidy.view_all)
+ {
+ var slide, last = w3c_slidy.last_shown;
+
+ if (incremental || w3c_slidy.slide_number == w3c_slidy.slides.length - 1)
+ w3c_slidy.last_shown = w3c_slidy.reveal_next_item(w3c_slidy.last_shown);
+
+ if ((!incremental || w3c_slidy.last_shown == null) &&
+ w3c_slidy.slide_number < w3c_slidy.slides.length - 1)
+ {
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+
+ w3c_slidy.slide_number = w3c_slidy.slide_number + 1;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.show_slide(slide);
+ }
+ else if (!w3c_slidy.last_shown)
+ {
+ if (last && incremental)
+ w3c_slidy.last_shown = last;
+ }
+
+ w3c_slidy.set_location();
+
+ w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+
+ if (!w3c_slidy.ns_pos)
+ w3c_slidy.refresh_toolbar(200);
+ }
+ },
+
+ // to first slide with nothing revealed
+ // i.e. state at start of presentation
+ first_slide: function () {
+ if (!w3c_slidy.view_all)
+ {
+ var slide;
+
+ if (w3c_slidy.slide_number != 0)
+ {
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+
+ w3c_slidy.slide_number = 0;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.show_slide(slide);
+ }
+
+ w3c_slidy.set_eos_status(
+ !w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+ w3c_slidy.set_location();
+ }
+ },
+
+ // goto last slide with everything revealed
+ // i.e. state at end of presentation
+ last_slide: function () {
+ if (!w3c_slidy.view_all)
+ {
+ var slide;
+
+ w3c_slidy.last_shown = null; //revealNextItem(lastShown);
+
+ if (w3c_slidy.last_shown == null &&
+ w3c_slidy.slide_number < w3c_slidy.slides.length - 1)
+ {
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.slide_number = w3c_slidy.slides.length - 1;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.set_visibility_all_incremental("visible");
+ w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null);
+
+ w3c_slidy.show_slide(slide);
+ }
+ else
+ {
+ w3c_slidy.set_visibility_all_incremental("visible");
+ w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null);
+ }
+
+ w3c_slidy.set_eos_status(true);
+ w3c_slidy.set_location();
+ }
+ },
+
+
+ // ### check this and consider add/remove class
+ set_eos_status: function (state) {
+ if (this.eos)
+ this.eos.style.color = (state ? "rgb(240,240,240)" : "red");
+ },
+
+ // first slide is 0
+ goto_slide: function (num) {
+ //alert("going to slide " + (num+1));
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.slide_number = num;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+ document.title = w3c_slidy.title + " (" + (w3c_slidy.slide_number+1) + ")";
+ w3c_slidy.show_slide(slide);
+ w3c_slidy.show_slide_number();
+ },
+
+
+ show_slide: function (slide) {
+ this.sync_background(slide);
+ window.scrollTo(0,0);
+ this.remove_class(slide, "hidden");
+ },
+
+ hide_slide: function (slide) {
+ this.add_class(slide, "hidden");
+ },
+
+ // show just the backgrounds pertinent to this slide
+ // when slide background-color is transparent
+ // this should now work with rgba color values
+ sync_background: function (slide) {
+ var background;
+ var bgColor;
+
+ if (slide.currentStyle)
+ bgColor = slide.currentStyle["backgroundColor"];
+ else if (document.defaultView)
+ {
+ var styles = document.defaultView.getComputedStyle(slide,null);
+
+ if (styles)
+ bgColor = styles.getPropertyValue("background-color");
+ else // broken implementation probably due Safari or Konqueror
+ {
+ //alert("defective implementation of getComputedStyle()");
+ bgColor = "transparent";
+ }
+ }
+ else
+ bgColor == "transparent";
+
+ if (bgColor == "transparent" ||
+ bgColor.indexOf("rgba") >= 0 ||
+ bgColor.indexOf("opacity") >= 0)
+ {
+ var slideClass = this.get_class_list(slide);
+
+ for (var i = 0; i < this.backgrounds.length; i++)
+ {
+ background = this.backgrounds[i];
+
+ var bgClass = this.get_class_list(background);
+
+ if (this.matching_background(slideClass, bgClass))
+ this.remove_class(background, "hidden");
+ else
+ this.add_class(background, "hidden");
+ }
+ }
+ else // forcibly hide all backgrounds
+ this.hide_backgrounds();
+ },
+
+ hide_backgrounds: function () {
+ for (var i = 0; i < this.backgrounds.length; i++)
+ {
+ background = this.backgrounds[i];
+ this.add_class(background, "hidden");
+ }
+ },
+
+ // compare classes for slide and background
+ matching_background: function (slideClass, bgClass) {
+ var i, count, pattern, result;
+
+ // define pattern as regular expression
+ pattern = /\w+/g;
+
+ // check background class names
+ result = bgClass.match(pattern);
+
+ for (i = count = 0; i < result.length; i++)
+ {
+ if (result[i] == "hidden")
+ continue;
+
+ if (result[i] == "background")
+ continue;
+
+ ++count;
+ }
+
+ if (count == 0) // default match
+ return true;
+
+ // check for matches and place result in array
+ result = slideClass.match(pattern);
+
+ // now check if desired name is present for background
+ for (i = count = 0; i < result.length; i++)
+ {
+ if (result[i] == "hidden")
+ continue;
+
+ if (this.has_token(bgClass, result[i]))
+ return true;
+ }
+
+ return false;
+ },
+
+ resized: function () {
+ var width = 0;
+
+ if ( typeof( window.innerWidth ) == 'number' )
+ width = window.innerWidth; // Non IE browser
+ else if (document.documentElement && document.documentElement.clientWidth)
+ width = document.documentElement.clientWidth; // IE6
+ else if (document.body && document.body.clientWidth)
+ width = document.body.clientWidth; // IE4
+
+ var height = 0;
+
+ if ( typeof( window.innerHeight ) == 'number' )
+ height = window.innerHeight; // Non IE browser
+ else if (document.documentElement && document.documentElement.clientHeight)
+ height = document.documentElement.clientHeight; // IE6
+ else if (document.body && document.body.clientHeight)
+ height = document.body.clientHeight; // IE4
+
+ if (height && (width/height > 1.05*1024/768))
+ {
+ width = height * 1024.0/768;
+ }
+
+ // IE fires onresize even when only font size is changed!
+ // so we do a check to avoid blocking < and > actions
+ if (width != w3c_slidy.last_width || height != w3c_slidy.last_height)
+ {
+ if (width >= 1100)
+ w3c_slidy.size_index = 5; // 4
+ else if (width >= 1000)
+ w3c_slidy.size_index = 4; // 3
+ else if (width >= 800)
+ w3c_slidy.size_index = 3; // 2
+ else if (width >= 600)
+ w3c_slidy.size_index = 2; // 1
+ else if (width)
+ w3c_slidy.size_index = 0;
+
+ // add in font size adjustment from meta element e.g.
+ // <meta name="font-size-adjustment" content="-2" />
+ // useful when slides have too much content ;-)
+
+ if (0 <= w3c_slidy.size_index + w3c_slidy.size_adjustment &&
+ w3c_slidy.size_index + w3c_slidy.size_adjustment < w3c_slidy.sizes.length)
+ w3c_slidy.size_index = w3c_slidy.size_index + w3c_slidy.size_adjustment;
+
+ // enables cross browser use of relative width/height
+ // on object elements for use with SVG and Flash media
+ w3c_slidy.adjust_object_dimensions(width, height);
+
+ if (document.body.style.fontSize != w3c_slidy.sizes[w3c_slidy.size_index])
+ {
+ document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index];
+ }
+
+ w3c_slidy.last_width = width;
+ w3c_slidy.last_height = height;
+
+ // force reflow to work around Mozilla bug
+ if (w3c_slidy.ns_pos)
+ {
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.show_slide(slide);
+ }
+
+ // force correct positioning of toolbar
+ w3c_slidy.refresh_toolbar(200);
+ }
+ },
+
+ scrolled: function () {
+ if (w3c_slidy.toolbar && !w3c_slidy.ns_pos && !w3c_slidy.ie7)
+ {
+ w3c_slidy.hack_offset = w3c_slidy.scroll_x_offset();
+ // hide toolbar
+ w3c_slidy.toolbar.style.display = "none";
+
+ // make it reappear later
+ if (w3c_slidy.scrollhack == 0 && !w3c_slidy.view_all)
+ {
+ setTimeout(function () {w3c_slidy.show_toolbar(); }, 1000);
+ w3c_slidy.scrollhack = 1;
+ }
+ }
+ },
+
+ hide_toolbar: function () {
+ w3c_slidy.add_class(w3c_slidy.toolbar, "hidden");
+ window.focus();
+ },
+
+ // used to ensure IE refreshes toolbar in correct position
+ refresh_toolbar: function (interval) {
+ if (!w3c_slidy.ns_pos && !w3c_slidy.ie7)
+ {
+ w3c_slidy.hide_toolbar();
+ setTimeout(function () {w3c_slidy.show_toolbar(); }, interval);
+ }
+ },
+
+ // restores toolbar after short delay
+ show_toolbar: function () {
+ if (w3c_slidy.want_toolbar)
+ {
+ w3c_slidy.toolbar.style.display = "block";
+
+ if (!w3c_slidy.ns_pos)
+ {
+ // adjust position to allow for scrolling
+ var xoffset = w3c_slidy.scroll_x_offset();
+ w3c_slidy.toolbar.style.left = xoffset;
+ w3c_slidy.toolbar.style.right = xoffset;
+
+ // determine vertical scroll offset
+ //var yoffset = scrollYOffset();
+
+ // bottom is doc height - window height - scroll offset
+ //var bottom = documentHeight() - lastHeight - yoffset
+
+ //if (yoffset > 0 || documentHeight() > lastHeight)
+ // bottom += 16; // allow for height of scrollbar
+
+ w3c_slidy.toolbar.style.bottom = 0; //bottom;
+ }
+
+ w3c_slidy.remove_class(w3c_slidy.toolbar, "hidden");
+ }
+
+ w3c_slidy.scrollhack = 0;
+
+
+ // set the keyboard focus to the help link on the
+ // toolbar to ensure that document has the focus
+ // IE doesn't always work with window.focus()
+ // and this hack has benefit of Enter for help
+
+ try
+ {
+ if (!w3c_slidy.opera)
+ w3c_slidy.help_anchor.focus();
+ }
+ catch (e)
+ {
+ }
+ },
+
+// invoked via F key
+ toggle_toolbar: function () {
+ if (!w3c_slidy.view_all)
+ {
+ if (w3c_slidy.has_class(w3c_slidy.toolbar, "hidden"))
+ {
+ w3c_slidy.remove_class(w3c_slidy.toolbar, "hidden")
+ w3c_slidy.want_toolbar = 1;
+ }
+ else
+ {
+ w3c_slidy.add_class(w3c_slidy.toolbar, "hidden")
+ w3c_slidy.want_toolbar = 0;
+ }
+ }
+ },
+
+ scroll_x_offset: function () {
+ if (window.pageXOffset)
+ return self.pageXOffset;
+
+ if (document.documentElement &&
+ document.documentElement.scrollLeft)
+ return document.documentElement.scrollLeft;
+
+ if (document.body)
+ return document.body.scrollLeft;
+
+ return 0;
+ },
+
+ scroll_y_offset: function () {
+ if (window.pageYOffset)
+ return self.pageYOffset;
+
+ if (document.documentElement &&
+ document.documentElement.scrollTop)
+ return document.documentElement.scrollTop;
+
+ if (document.body)
+ return document.body.scrollTop;
+
+ return 0;
+ },
+
+ // looking for a way to determine height of slide content
+ // the slide itself is set to the height of the window
+ optimize_font_size: function () {
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+
+ //var dh = documentHeight(); //getDocHeight(document);
+ var dh = slide.scrollHeight;
+ var wh = getWindowHeight();
+ var u = 100 * dh / wh;
+
+ alert("window utilization = " + u + "% (doc "
+ + dh + " win " + wh + ")");
+ },
+
+ // from document object
+ get_doc_height: function (doc) {
+ if (!doc)
+ doc = document;
+
+ if (doc && doc.body && doc.body.offsetHeight)
+ return doc.body.offsetHeight; // ns/gecko syntax
+
+ if (doc && doc.body && doc.body.scrollHeight)
+ return doc.body.scrollHeight;
+
+ alert("couldn't determine document height");
+ },
+
+ get_window_height: function () {
+ if ( typeof( window.innerHeight ) == 'number' )
+ return window.innerHeight; // Non IE browser
+
+ if (document.documentElement && document.documentElement.clientHeight)
+ return document.documentElement.clientHeight; // IE6
+
+ if (document.body && document.body.clientHeight)
+ return document.body.clientHeight; // IE4
+ },
+
+ document_height: function () {
+ var sh, oh;
+
+ sh = document.body.scrollHeight;
+ oh = document.body.offsetHeight;
+
+ if (sh && oh)
+ {
+ return (sh > oh ? sh : oh);
+ }
+
+ // no idea!
+ return 0;
+ },
+
+ smaller: function () {
+ if (w3c_slidy.size_index > 0)
+ {
+ --w3c_slidy.size_index;
+ }
+
+ w3c_slidy.toolbar.style.display = "none";
+ document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index];
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.show_slide(slide);
+ setTimeout(function () {w3c_slidy.show_toolbar(); }, 50);
+ },
+
+ bigger: function () {
+ if (w3c_slidy.size_index < w3c_slidy.sizes.length - 1)
+ {
+ ++w3c_slidy.size_index;
+ }
+
+ w3c_slidy.toolbar.style.display = "none";
+ document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index];
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.show_slide(slide);
+ setTimeout(function () {w3c_slidy.show_toolbar(); }, 50);
+ },
+
+ // enables cross browser use of relative width/height
+ // on object elements for use with SVG and Flash media
+ // with thanks to Ivan Herman for the suggestion
+ adjust_object_dimensions: function (width, height) {
+ for( var i = 0; i < w3c_slidy.objects.length; i++ )
+ {
+ var obj = this.objects[i];
+ var mimeType = obj.getAttribute("type");
+
+ if (mimeType == "image/svg+xml" || mimeType == "application/x-shockwave-flash")
+ {
+ if ( !obj.initialWidth )
+ obj.initialWidth = obj.getAttribute("width");
+
+ if ( !obj.initialHeight )
+ obj.initialHeight = obj.getAttribute("height");
+
+ if ( obj.initialWidth && obj.initialWidth.charAt(obj.initialWidth.length-1) == "%" )
+ {
+ var w = parseInt(obj.initialWidth.slice(0, obj.initialWidth.length-1));
+ var newW = width * (w/100.0);
+ obj.setAttribute("width",newW);
+ }
+
+ if ( obj.initialHeight &&
+ obj.initialHeight.charAt(obj.initialHeight.length-1) == "%" )
+ {
+ var h = parseInt(obj.initialHeight.slice(0, obj.initialHeight.length-1));
+ var newH = height * (h/100.0);
+ obj.setAttribute("height", newH);
+ }
+ }
+ }
+ },
+
+ // needed for Opera to inhibit default behavior
+ // since Opera delivers keyPress even if keyDown
+ // was cancelled
+ key_press: function (event) {
+ if (!event)
+ event = window.event;
+
+ if (!w3c_slidy.key_wanted)
+ return w3c_slidy.cancel(event);
+
+ return true;
+ },
+
+ // See e.g. http://www.quirksmode.org/js/events/keys.html for keycodes
+ key_down: function (event) {
+ var key;
+
+ w3c_slidy.key_wanted = true;
+
+ if (!event)
+ event = window.event;
+
+ // kludge around NS/IE differences
+ if (window.event)
+ key = window.event.keyCode;
+ else if (event.which)
+ key = event.which;
+ else
+ return true; // Yikes! unknown browser
+
+ // ignore event if key value is zero
+ // as for alt on Opera and Konqueror
+ if (!key)
+ return true;
+
+ // check for concurrent control/command/alt key
+ // but are these only present on mouse events?
+
+ if (event.ctrlKey || event.altKey || event.metaKey)
+ return true;
+
+ // dismiss table of contents if visible
+ if (w3c_slidy.is_shown_toc() && key != 9 && key != 16 && key != 38 && key != 40)
+ {
+ w3c_slidy.hide_table_of_contents();
+
+ if (key == 27 || key == 84 || key == 67)
+ return w3c_slidy.cancel(event);
+ }
+
+ if (key == 34) // Page Down
+ {
+ if (w3c_slidy.view_all)
+ return true;
+
+ w3c_slidy.next_slide(false);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 33) // Page Up
+ {
+ if (w3c_slidy.view_all)
+ return true;
+
+ w3c_slidy.previous_slide(false);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 32) // space bar
+ {
+ w3c_slidy.next_slide(true);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 37) // Left arrow
+ {
+ w3c_slidy.previous_slide(!event.shiftKey);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 36) // Home
+ {
+ w3c_slidy.first_slide();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 35) // End
+ {
+ w3c_slidy.last_slide();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 39) // Right arrow
+ {
+ w3c_slidy.next_slide(!event.shiftKey);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 13) // Enter
+ {
+ if (w3c_slidy.outline)
+ {
+ if (w3c_slidy.outline.visible)
+ w3c_slidy.fold(w3c_slidy.outline);
+ else
+ w3c_slidy.unfold(w3c_slidy.outline);
+
+ return w3c_slidy.cancel(event);
+ }
+ }
+ else if (key == 188) // < for smaller fonts
+ {
+ w3c_slidy.smaller();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 190) // > for larger fonts
+ {
+ w3c_slidy.bigger();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 189 || key == 109) // - for smaller fonts
+ {
+ w3c_slidy.smaller();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 187 || key == 191 || key == 107) // = + for larger fonts
+ {
+ w3c_slidy.bigger();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 83) // S for smaller fonts
+ {
+ w3c_slidy.smaller();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 66) // B for larger fonts
+ {
+ w3c_slidy.bigger();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 90) // Z for last slide
+ {
+ w3c_slidy.last_slide();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 70) // F for toggle toolbar
+ {
+ w3c_slidy.toggle_toolbar();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 65) // A for toggle view single/all slides
+ {
+ w3c_slidy.toggle_view();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 75) // toggle action of left click for next page
+ {
+ w3c_slidy.mouse_click_enabled = !w3c_slidy.mouse_click_enabled;
+ var alert_msg = (w3c_slidy.mouse_click_enabled ?
+ "enabled" : "disabled") + " mouse click advance";
+
+ alert(alert_msg.localize());
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 84 || key == 67) // T or C for table of contents
+ {
+ if (w3c_slidy.toc)
+ w3c_slidy.toggle_table_of_contents();
+
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 72) // H for help
+ {
+ window.location = w3c_slidy.help_page;
+ return w3c_slidy.cancel(event);
+ }
+ //else alert("key code is "+ key);
+
+ return true;
+ },
+
+ // safe for both text/html and application/xhtml+xml
+ create_element: function (name) {
+ if (this.xhtml && (typeof document.createElementNS != 'undefined'))
+ return document.createElementNS("http://www.w3.org/1999/xhtml", name)
+
+ return document.createElement(name);
+ },
+
+ get_element_style: function (elem, IEStyleProp, CSSStyleProp) {
+ if (elem.currentStyle)
+ {
+ return elem.currentStyle[IEStyleProp];
+ }
+ else if (window.getComputedStyle)
+ {
+ var compStyle = window.getComputedStyle(elem, "");
+ return compStyle.getPropertyValue(CSSStyleProp);
+ }
+ return "";
+ },
+
+ // the string str is a whitespace separated list of tokens
+ // test if str contains a particular token, e.g. "slide"
+ has_token: function (str, token) {
+ if (str)
+ {
+ // define pattern as regular expression
+ var pattern = /\w+/g;
+
+ // check for matches
+ // place result in array
+ var result = str.match(pattern);
+
+ // now check if desired token is present
+ for (var i = 0; i < result.length; i++)
+ {
+ if (result[i] == token)
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ get_class_list: function (element) {
+ if (typeof element.className != 'undefined')
+ return element.className;
+
+ return element.getAttribute("class");
+ },
+
+ has_class: function (element, name) {
+ if (element.nodeType != 1)
+ return false;
+
+ var regexp = new RegExp("(^| )" + name + "\W*");
+
+ if (typeof element.className != 'undefined')
+ return regexp.test(element.className);
+
+ return regexp.test(element.getAttribute("class"));
+ },
+
+ remove_class: function (element, name) {
+ var regexp = new RegExp("(^| )" + name + "\W*");
+ var clsval = "";
+
+ if (typeof element.className != 'undefined')
+ {
+ clsval = element.className;
+
+ if (clsval)
+ {
+ clsval = clsval.replace(regexp, "");
+ element.className = clsval;
+ }
+ }
+ else
+ {
+ clsval = element.getAttribute("class");
+
+ if (clsval)
+ {
+ clsval = clsval.replace(regexp, "");
+ element.setAttribute("class", clsval);
+ }
+ }
+ },
+
+ add_class: function (element, name) {
+ if (!this.has_class(element, name))
+ {
+ if (typeof element.className != 'undefined')
+ element.className += " " + name;
+ else
+ {
+ var clsval = element.getAttribute("class");
+ clsval = clsval ? clsval + " " + name : name;
+ element.setAttribute("class", clsval);
+ }
+ }
+ },
+
+ // HTML elements that can be used with class="incremental"
+ // note that you can also put the class on containers like
+ // up, ol, dl, and div to make their contents appear
+ // incrementally. Upper case is used since this is what
+ // browsers report for HTML node names (text/html).
+ incremental_elements: null,
+ okay_for_incremental: function (name) {
+ if (!this.incremental_elements)
+ {
+ var inclist = new Array();
+ inclist["p"] = true;
+ inclist["pre"] = true;
+ inclist["li"] = true;
+ inclist["blockquote"] = true;
+ inclist["dt"] = true;
+ inclist["dd"] = true;
+ inclist["h2"] = true;
+ inclist["h3"] = true;
+ inclist["h4"] = true;
+ inclist["h5"] = true;
+ inclist["h6"] = true;
+ inclist["span"] = true;
+ inclist["address"] = true;
+ inclist["table"] = true;
+ inclist["tr"] = true;
+ inclist["th"] = true;
+ inclist["td"] = true;
+ inclist["img"] = true;
+ inclist["object"] = true;
+ this.incremental_elements = inclist;
+ }
+ return this.incremental_elements[name.toLowerCase()];
+ },
+
+ next_incremental_item: function (node) {
+ var br = this.is_xhtml ? "br" : "BR";
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+
+ for (;;)
+ {
+ node = w3c_slidy.next_node(slide, node);
+
+ if (node == null || node.parentNode == null)
+ break;
+
+ if (node.nodeType == 1) // ELEMENT
+ {
+ if (node.nodeName == br)
+ continue;
+
+ if (w3c_slidy.has_class(node, "incremental")
+ && w3c_slidy.okay_for_incremental(node.nodeName))
+ return node;
+
+ if (w3c_slidy.has_class(node.parentNode, "incremental")
+ && !w3c_slidy.has_class(node, "non-incremental"))
+ return node;
+ }
+ }
+
+ return node;
+ },
+
+ previous_incremental_item: function (node) {
+ var br = this.is_xhtml ? "br" : "BR";
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+
+ for (;;)
+ {
+ node = w3c_slidy.previous_node(slide, node);
+
+ if (node == null || node.parentNode == null)
+ break;
+
+ if (node.nodeType == 1)
+ {
+ if (node.nodeName == br)
+ continue;
+
+ if (w3c_slidy.has_class(node, "incremental")
+ && w3c_slidy.okay_for_incremental(node.nodeName))
+ return node;
+
+ if (w3c_slidy.has_class(node.parentNode, "incremental")
+ && !w3c_slidy.has_class(node, "non-incremental"))
+ return node;
+ }
+ }
+
+ return node;
+ },
+
+ // set visibility for all elements on current slide with
+ // a parent element with attribute class="incremental"
+ set_visibility_all_incremental: function (value) {
+ var node = this.next_incremental_item(null);
+
+ if (value == "hidden")
+ {
+ while (node)
+ {
+ w3c_slidy.add_class(node, "invisible");
+ node = w3c_slidy.next_incremental_item(node);
+ }
+ }
+ else // value == "visible"
+ {
+ while (node)
+ {
+ w3c_slidy.remove_class(node, "invisible");
+ node = w3c_slidy.next_incremental_item(node);
+ }
+ }
+ },
+
+ // reveal the next hidden item on the slide
+ // node is null or the node that was last revealed
+ reveal_next_item: function (node) {
+ node = w3c_slidy.next_incremental_item(node);
+
+ if (node && node.nodeType == 1) // an element
+ w3c_slidy.remove_class(node, "invisible");
+
+ return node;
+ },
+
+ // exact inverse of revealNextItem(node)
+ hide_previous_item: function (node) {
+ if (node && node.nodeType == 1) // an element
+ w3c_slidy.add_class(node, "invisible");
+
+ return this.previous_incremental_item(node);
+ },
+
+ // left to right traversal of root's content
+ next_node: function (root, node) {
+ if (node == null)
+ return root.firstChild;
+
+ if (node.firstChild)
+ return node.firstChild;
+
+ if (node.nextSibling)
+ return node.nextSibling;
+
+ for (;;)
+ {
+ node = node.parentNode;
+
+ if (!node || node == root)
+ break;
+
+ if (node && node.nextSibling)
+ return node.nextSibling;
+ }
+
+ return null;
+ },
+
+ // right to left traversal of root's content
+ previous_node: function (root, node) {
+ if (node == null)
+ {
+ node = root.lastChild;
+
+ if (node)
+ {
+ while (node.lastChild)
+ node = node.lastChild;
+ }
+
+ return node;
+ }
+
+ if (node.previousSibling)
+ {
+ node = node.previousSibling;
+
+ while (node.lastChild)
+ node = node.lastChild;
+
+ return node;
+ }
+
+ if (node.parentNode != root)
+ return node.parentNode;
+
+ return null;
+ },
+
+ previous_sibling_element: function (el) {
+ el = el.previousSibling;
+
+ while (el && el.nodeType != 1)
+ el = el.previousSibling;
+
+ return el;
+ },
+
+ next_sibling_element: function (el) {
+ el = el.nextSibling;
+
+ while (el && el.nodeType != 1)
+ el = el.nextSibling;
+
+ return el;
+ },
+
+ first_child_element: function (el) {
+ var node;
+
+ for (node = el.firstChild; node; node = node.nextSibling)
+ {
+ if (node.nodeType == 1)
+ break;
+ }
+
+ return node;
+ },
+
+ first_tag: function (element, tag) {
+ var node;
+
+ if (!this.is_xhtml)
+ tag = tag.toUpperCase();
+
+ for (node = element.firstChild; node; node = node.nextSibling)
+ {
+ if (node.nodeType == 1 && node.nodeName == tag)
+ break;
+ }
+
+ return node;
+ },
+
+ hide_selection: function () {
+ if (window.getSelection) // Firefox, Chromium, Safari, Opera
+ {
+ var selection = window.getSelection();
+
+ if (selection.rangeCount > 0)
+ {
+ var range = selection.getRangeAt(0);
+ range.collapse (false);
+ }
+ }
+ else // Internet Explorer
+ {
+ var textRange = document.selection.createRange ();
+ textRange.collapse (false);
+ }
+ },
+
+ get_selected_text: function () {
+ try
+ {
+ if (window.getSelection)
+ return window.getSelection().toString();
+
+ if (document.getSelection)
+ return document.getSelection().toString();
+
+ if (document.selection)
+ return document.selection.createRange().text;
+ }
+ catch (e)
+ {
+ }
+
+ return "";
+ },
+
+ // make note of length of selected text
+ // as this evaluates to zero in click event
+ mouse_button_up: function (e) {
+ w3c_slidy.selected_text_len = w3c_slidy.get_selected_text().length;
+ },
+
+ // right mouse button click is reserved for context menus
+ // it is more reliable to detect rightclick than leftclick
+ mouse_button_click: function (e) {
+ var rightclick = false;
+ var leftclick = false;
+ var middleclick = false;
+ var target;
+
+ if (!e)
+ var e = window.event;
+
+ if (e.target)
+ target = e.target;
+ else if (e.srcElement)
+ target = e.srcElement;
+
+ // work around Safari bug
+ if (target.nodeType == 3)
+ target = target.parentNode;
+
+ if (e.which) // all browsers except IE
+ {
+ leftclick = (e.which == 1);
+ middleclick = (e.which == 2);
+ rightclick = (e.which == 3);
+ }
+ else if (e.button)
+ {
+ // Konqueror gives 1 for left, 4 for middle
+ // IE6 gives 0 for left and not 1 as I expected
+
+ if (e.button == 4)
+ middleclick = true;
+
+ // all browsers agree on 2 for right button
+ rightclick = (e.button == 2);
+ }
+ else leftclick = true;
+/*
+ alert("you clicked over a " + target.nodeName + " element\n" +
+ "w3c_slidy.mouse_click_enabled = " + w3c_slidy.mouse_click_enabled + "\n" +
+ "leftclick = " + leftclick + "\n" +
+ "selected text length = " + w3c_slidy.selected_text_len);
+ //alert("selected text length = " + w3c_slidy.selected_text_len);
+*/
+ if (w3c_slidy.selected_text_len > 0)
+ {
+ w3c_slidy.stop_propagation(e);
+ e.cancel = true;
+ e.returnValue = false;
+ return false;
+ }
+
+ // dismiss table of contents
+ w3c_slidy.hide_table_of_contents();
+
+ // check if target is something that probably want's clicks
+ // e.g. a, embed, object, input, textarea, select, option
+ var tag = target.nodeName.toLowerCase();
+
+ if (w3c_slidy.mouse_click_enabled && leftclick &&
+ tag != "a" &&
+ tag != "embed" &&
+ tag != "object" &&
+ tag != "video" &&
+ tag != "input" &&
+ tag != "textarea" &&
+ tag != "select" &&
+ tag != "option" &&
+ !target.onclick)
+ {
+ w3c_slidy.next_slide(true);
+ w3c_slidy.stop_propagation(e);
+ e.cancel = true;
+ e.returnValue = false;
+ return false;
+ }
+ },
+
+ get_key: function (e)
+ {
+ var key;
+
+ // kludge around NS/IE differences
+ if (typeof window.event != "undefined")
+ key = window.event.keyCode;
+ else if (e.which)
+ key = e.which;
+
+ return key;
+ },
+
+ get_target: function (e) {
+ var target;
+
+ if (!e)
+ e = window.event;
+
+ if (e.target)
+ target = e.target;
+ else if (e.srcElement)
+ target = e.srcElement;
+
+ if (target.nodeType != 1)
+ target = target.parentNode;
+
+ return target;
+ },
+
+ // does display property provide correct defaults?
+ is_block: function (elem) {
+ var tag = elem.nodeName.toLowerCase();
+
+ return tag == "ol" || tag == "ul" || tag == "p" ||
+ tag == "li" || tag == "table" || tag == "pre" ||
+ tag == "h1" || tag == "h2" || tag == "h3" ||
+ tag == "h4" || tag == "h5" || tag == "h6" ||
+ tag == "blockquote" || tag == "address";
+ },
+
+ add_listener: function (element, event, handler) {
+ if (window.addEventListener)
+ element.addEventListener(event, handler, false);
+ else
+ element.attachEvent("on"+event, handler);
+ },
+
+ // used to prevent event propagation from field controls
+ stop_propagation: function (event) {
+ event = event ? event : window.event;
+ event.cancelBubble = true; // for IE
+
+ if (event.stopPropagation)
+ event.stopPropagation();
+
+ return true;
+ },
+
+ cancel: function (event) {
+ if (event)
+ {
+ event.cancel = true;
+ event.returnValue = false;
+
+ if (event.preventDefault)
+ event.preventDefault();
+ }
+
+ w3c_slidy.key_wanted = false;
+ return false;
+ }
+};
+
+// for each language define an associative array
+// and also the help text which is longer
+
+var w3c_slidy_i18n = {
+ strings_es: {
+ "slide":"pág.",
+ "help?":"Ayuda",
+ "contents?":"Índice",
+ "table of contents":"tabla de contenidos",
+ "Table of Contents":"Tabla de Contenidos",
+ "restart presentation":"Reiniciar presentación",
+ "restart?":"Inicio"
+ },
+ help_es:
+ "Utilice el ratón, barra espaciadora, teclas Izda/Dcha, " +
+ "o Re pág y Av pág. Use S y B para cambiar el tamaño de fuente.",
+
+ strings_ca: {
+ "slide":"pàg..",
+ "help?":"Ajuda",
+ "contents?":"Índex",
+ "table of contents":"taula de continguts",
+ "Table of Contents":"Taula de Continguts",
+ "restart presentation":"Reiniciar presentació",
+ "restart?":"Inici"
+ },
+ help_ca:
+ "Utilitzi el ratolí, barra espaiadora, tecles Esq./Dta. " +
+ "o Re pàg y Av pàg. Usi S i B per canviar grandària de font.",
+
+ strings_cs: {
+ "slide":"snímek",
+ "help?":"nápověda",
+ "contents?":"obsah",
+ "table of contents":"obsah prezentace",
+ "Table of Contents":"Obsah prezentace",
+ "restart presentation":"znovu spustit prezentaci",
+ "restart?":"restart"
+ },
+ help_cs:
+ "Prezentaci můžete procházet pomocí kliknutí myši, mezerníku, " +
+ "šipek vlevo a vpravo nebo kláves PageUp a PageDown. Písmo se " +
+ "dá zvětšit a zmenšit pomocí kláves B a S.",
+
+ strings_nl: {
+ "slide":"pagina",
+ "help?":"Help?",
+ "contents?":"Inhoud?",
+ "table of contents":"inhoudsopgave",
+ "Table of Contents":"Inhoudsopgave",
+ "restart presentation":"herstart presentatie",
+ "restart?":"Herstart?"
+ },
+ help_nl:
+ "Navigeer d.m.v. het muis, spatiebar, Links/Rechts toetsen, " +
+ "of PgUp en PgDn. Gebruik S en B om de karaktergrootte te veranderen.",
+
+ strings_de: {
+ "slide":"Seite",
+ "help?":"Hilfe",
+ "contents?":"Übersicht",
+ "table of contents":"Inhaltsverzeichnis",
+ "Table of Contents":"Inhaltsverzeichnis",
+ "restart presentation":"Präsentation neu starten",
+ "restart?":"Neustart"
+ },
+ help_de:
+ "Benutzen Sie die Maus, Leerschlag, die Cursortasten links/rechts oder " +
+ "Page up/Page Down zum Wechseln der Seiten und S und B für die Schriftgrösse.",
+
+ strings_pl: {
+ "slide":"slajd",
+ "help?":"pomoc?",
+ "contents?":"spis treści?",
+ "table of contents":"spis treści",
+ "Table of Contents":"Spis Treści",
+ "restart presentation":"Restartuj prezentację",
+ "restart?":"restart?"
+ },
+ help_pl:
+ "Zmieniaj slajdy klikając myszą, naciskając spację, strzałki lewo/prawo" +
+ "lub PgUp / PgDn. Użyj klawiszy S i B, aby zmienić rozmiar czczionki.",
+
+ strings_fr: {
+ "slide":"page",
+ "help?":"Aide",
+ "contents?":"Index",
+ "table of contents":"table des matières",
+ "Table of Contents":"Table des matières",
+ "restart presentation":"Recommencer l'exposé",
+ "restart?":"Début"
+ },
+ help_fr:
+ "Naviguez avec la souris, la barre d'espace, les flèches " +
+ "gauche/droite ou les touches Pg Up, Pg Dn. Utilisez " +
+ "les touches S et B pour modifier la taille de la police.",
+
+ strings_hu: {
+ "slide":"oldal",
+ "help?":"segítség",
+ "contents?":"tartalom",
+ "table of contents":"tartalomjegyzék",
+ "Table of Contents":"Tartalomjegyzék",
+ "restart presentation":"bemutató újraindítása",
+ "restart?":"újraindítás"
+ },
+ help_hu:
+ "Az oldalak közti lépkedéshez kattintson az egérrel, vagy " +
+ "használja a szóköz, a bal, vagy a jobb nyíl, illetve a Page Down, " +
+ "Page Up billentyűket. Az S és a B billentyűkkel változtathatja " +
+ "a szöveg méretét.",
+
+ strings_it: {
+ "slide":"pag.",
+ "help?":"Aiuto",
+ "contents?":"Indice",
+ "table of contents":"indice",
+ "Table of Contents":"Indice",
+ "restart presentation":"Ricominciare la presentazione",
+ "restart?":"Inizio"
+ },
+ help_it:
+ "Navigare con mouse, barra spazio, frecce sinistra/destra o " +
+ "PgUp e PgDn. Usare S e B per cambiare la dimensione dei caratteri.",
+
+ strings_el: {
+ "slide":"σελίδα",
+ "help?":"βοήθεια;",
+ "contents?":"περιεχόμενα;",
+ "table of contents":"πίνακας περιεχομένων",
+ "Table of Contents":"Πίνακας Περιεχομένων",
+ "restart presentation":"επανεκκίνηση παρουσίασης",
+ "restart?":"επανεκκίνηση;"
+ },
+ help_el:
+ "Πλοηγηθείτε με το κλίκ του ποντικιού, το space, τα βέλη αριστερά/δεξιά, " +
+ "ή Page Up και Page Down. Χρησιμοποιήστε τα πλήκτρα S και B για να αλλάξετε " +
+ "το μέγεθος της γραμματοσειράς.",
+
+ strings_ja: {
+ "slide":"スライド",
+ "help?":"ヘルプ",
+ "contents?":"目次",
+ "table of contents":"目次を表示",
+ "Table of Contents":"目次",
+ "restart presentation":"最初から再生",
+ "restart?":"最初から"
+ },
+ help_ja:
+ "マウス左クリック ・ スペース ・ 左右キー " +
+ "または Page Up ・ Page Downで操作, S ・ Bでフォントサイズ変更",
+
+ strings_zh: {
+ "slide":"幻灯片",
+ "help?":"帮助?",
+ "contents?":"内容?",
+ "table of contents":"目录",
+ "Table of Contents":"目录",
+ "restart presentation":"重新启动展示",
+ "restart?":"重新启动?"
+ },
+ help_zh:
+ "用鼠标点击, 空格条, 左右箭头, Pg Up 和 Pg Dn 导航. " +
+ "用 S, B 改变字体大小.",
+
+ strings_ru: {
+ "slide":"слайд",
+ "help?":"помощь?",
+ "contents?":"содержание?",
+ "table of contents":"оглавление",
+ "Table of Contents":"Оглавление",
+ "restart presentation":"перезапустить презентацию",
+ "restart?":"перезапуск?"
+ },
+ help_ru:
+ "Перемещайтесь кликая мышкой, используя клавишу пробел, стрелки" +
+ "влево/вправо или Pg Up и Pg Dn. Клавиши S и B меняют размер шрифта.",
+
+ strings_sv: {
+ "slide":"sida",
+ "help?":"hjälp",
+ "contents?":"innehåll",
+ "table of contents":"innehållsförteckning",
+ "Table of Contents":"Innehållsförteckning",
+ "restart presentation":"visa presentationen från början",
+ "restart?":"börja om"
+ },
+ help_sv:
+ "Bläddra med ett klick med vänstra musknappen, mellanslagstangenten, " +
+ "vänster- och högerpiltangenterna eller tangenterna Pg Up, Pg Dn. " +
+ "Använd tangenterna S och B för att ändra textens storlek.",
+
+// each such language array is declared in the localize array
+// which is set on string prototype and used as in "foo".localize();
+ localize: {
+ "es":this.strings_es,
+ "ca":this.strings_ca,
+ "cs":this.strings_cs,
+ "nl":this.strings_nl,
+ "de":this.strings_de,
+ "pl":this.strings_pl,
+ "fr":this.strings_fr,
+ "hu":this.strings_hu,
+ "it":this.strings_it,
+ "el":this.strings_el,
+ "jp":this.strings_ja,
+ "zh":this.strings_zh,
+ "ru":this.strings_ru,
+ "sv":this.strings_sv
+ },
+
+ init: function () {
+ var i18n = w3c_slidy_i18n;
+ var help_text = w3c_slidy.help_text;
+ i18n.strings_es[help_text] = i18n.help_es;
+ i18n.strings_ca[help_text] = i18n.help_ca;
+ i18n.strings_cs[help_text] = i18n.help_cs;
+ i18n.strings_nl[help_text] = i18n.help_nl;
+ i18n.strings_de[help_text] = i18n.help_de;
+ i18n.strings_pl[help_text] = i18n.help_pl;
+ i18n.strings_fr[help_text] = i18n.help_fr;
+ i18n.strings_hu[help_text] = i18n.help_hu;
+ i18n.strings_it[help_text] = i18n.help_it;
+ i18n.strings_el[help_text] = i18n.help_el;
+ i18n.strings_ja[help_text] = i18n.help_ja;
+ i18n.strings_zh[help_text] = i18n.help_zh;
+ i18n.strings_ru[help_text] = i18n.help_ru;
+ i18n.strings_sv[help_text] = i18n.help_sv;
+
+ w3c_slidy.lang = document.body.parentNode.getAttribute("lang");
+
+ if (!w3c_slidy.lang)
+ w3c_slidy.lang = document.body.parentNode.getAttribute("xml:lang");
+
+ if (!w3c_slidy.lang)
+ w3c_slidy.lang = "en";
+
+ // add localize method to all strings
+ // for use as in "contents".localize()
+ String.prototype.localize = function() {
+ if (this == "")
+ return this;
+
+ // try full language code, e.g. en-US
+ var s, lookup = w3c_slidy_i18n.localize[w3c_slidy.lang];
+
+ if (lookup)
+ {
+ s = lookup[this];
+
+ if (s)
+ return s;
+ }
+
+ // strip country code suffix, e.g.
+ // try en if undefined for en-US
+ var lg = w3c_slidy.lang.split("-");
+
+ if (lg.length > 1)
+ {
+ lookup = w3c_slidy_i18n.localize[lg[0]];
+
+ if (lookup)
+ {
+ s = lookup[this];
+
+ if (s)
+ return s;
+ }
+ }
+
+ // otherwise string as is
+ return this;
+ };
+ }
+};
+
+// hack for back button behavior
+if (w3c_slidy.ie6 || w3c_slidy.ie7)
+{
+ document.write("<iframe id='historyFrame' " +
+ "src='javascript:\"<html"+"></"+"html>\"' " +
+ "height='1' width='1' " +
+ "style='position:absolute;left:-800px'></iframe>");
+}
+
+// attach event listeners for initialization
+w3c_slidy.set_up();
+
+// hide the slides as soon as body element is available
+// to reduce annoying screen mess before the onload event
+setTimeout(w3c_slidy.hide_slides, 50);
+
+/*]]>*/
+</script>
+</head>
+<body class="article" style="max-width:45em">
+<div id="header" class="slide">
+<h1>Path Loss and Link Budget</h1>
+<span id="author">Harald Welte &lt;hwelte@sysmocom.de&gt;</span><br />
+</div>
+<div class="sect1 slide">
+<h1 id="rf-path-loss">Path Loss</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>A fundamental concept in planning any type of radio communications link
+is the concept of <em>Path Loss</em>. Path Loss describes the amount of
+signal loss (attenuation) between a receive and a transmitter.</p></div>
+<div class="paragraph"><p>As GSM operates in frequency duplex on uplink and downlink, there is
+correspondingly an <em>Uplink Path Loss</em> from MS to BTS, and a <em>Downlink
+Path Loss</em> from BTS to MS. Both need to be considered.</p></div>
+<div class="paragraph"><p>It is possible to compute the path loss in a theoretical ideal
+situation, where transmitter and receiver are in empty space, with no
+surfaces anywhere nearby causing reflections, and with no objects or
+materials in between them. This is generally called the <em>Free Space
+Path Loss</em>.</p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="rf-path-loss">Path Loss</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>Estimating the path loss within a given real-world terrain/geography is
+a hard problem, and there are no easy solutions. It is impacted, among
+other things, by</p></div>
+<ul class="">
+<li>
+<span>
+the height of the transmitter and receiver antennas
+</span>
+</li>
+<li>
+<span>
+whether there is line-of-sight (LOS) or non-line-of-sight (NLOS)
+</span>
+</li>
+<li>
+<span>
+the geography/terrain in terms of hills, mountains, etc.
+</span>
+</li>
+<li>
+<span>
+the vegetation in terms of attenuation by foliage
+</span>
+</li>
+<li>
+<span>
+any type of construction, and if so, the type of materials used in
+ that construction, the height of the buildings, their distance, etc.
+</span>
+</li>
+<li>
+<span>
+the frequency (band) used. Lower frequencies generally expose better
+ NLOS characteristics than higher frequencies.
+</span>
+</li>
+</ul>
+<div class="paragraph"><p>The above factors determine on the one hand side the actual attenuation
+of the radio wave between transmitter and receiver. On the other
+hand, they also determine how many reflections there are on this path,
+causing so-called <em>Multipath Fading</em> of the signal.</p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_radio_propagation_models">Radio Propagation Models</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>Over decades, many different radio propagation models have been designed
+by scientists and engineers. They might be based on empirical studies
+condensed down into relatively simple models, or they might be based on
+ray-tracing in a 3D model of the terrain.</p></div>
+<div class="paragraph"><p>Several companies have developed (expensive, proprietary) simulation
+software that can help with this process in detail. However, the
+results of such simulation also depend significantly on the availability
+of precise 3D models of the geography/terrain as well as the building
+structure in the coverage area.</p></div>
+<div class="paragraph"><p>In absence of such simulation software and/or precise models, there are
+several models that can help, depending on the general terrain:</p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_common_path_loss_models">Common Path Loss Models</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="tableblock" id="path-loss-models">
+<table rules="all"
+width="100%"
+frame="border"
+cellspacing="0" cellpadding="4">
+<caption class="title">Table 1. List of common path loss models</caption>
+<col width="20%" />
+<col width="20%" />
+<col width="20%" />
+<col width="40%" />
+<thead>
+<tr>
+<th align="left" valign="top">Type</th>
+<th align="left" valign="top">Sub-Type</th>
+<th align="left" valign="top">Bands</th>
+<th align="left" valign="top">Name</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td align="left" valign="top"><p class="table">Terrain</p></td>
+<td align="left" valign="top"><p class="table">-</p></td>
+<td align="left" valign="top"><p class="table">850, 900, 1800, 1900</p></td>
+<td align="left" valign="top"><p class="table">ITU terrain model</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">Rural</p></td>
+<td align="left" valign="top"><p class="table">Foliage</p></td>
+<td align="left" valign="top"><p class="table">850, 900, 1800, 1900</p></td>
+<td align="left" valign="top"><p class="table">One woodland terminal model</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">City</p></td>
+<td align="left" valign="top"><p class="table">Urban</p></td>
+<td align="left" valign="top"><p class="table">850, 900</p></td>
+<td align="left" valign="top"><p class="table">Okumura-Hata Model for Urban Areas</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">City</p></td>
+<td align="left" valign="top"><p class="table">Suburban</p></td>
+<td align="left" valign="top"><p class="table">850, 900</p></td>
+<td align="left" valign="top"><p class="table">Okumura-Hata Model for Suburban Areas</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">City</p></td>
+<td align="left" valign="top"><p class="table">Open</p></td>
+<td align="left" valign="top"><p class="table">850, 900</p></td>
+<td align="left" valign="top"><p class="table">Okumura-Hata Model for Open Areas</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">City</p></td>
+<td align="left" valign="top"><p class="table">Urban</p></td>
+<td align="left" valign="top"><p class="table">1800, 1900</p></td>
+<td align="left" valign="top"><p class="table">COST-231 Hata Model</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">Indoor</p></td>
+<td align="left" valign="top"><p class="table">-</p></td>
+<td align="left" valign="top"><p class="table">900, 1800, 1900</p></td>
+<td align="left" valign="top"><p class="table">ITU model for indoor attenuation</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="paragraph"><p>In <a href="#path-loss-models">[path-loss-models]</a> you can see a list of commonly-used path loss
+models. They are typically quite simple equations which only require
+certain parameters like the distance of transmitter and receiver as well
+as the antenna height, etc. No detailed 3D models of the terrain are
+required.</p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_rf_power_in_a_wireless_link">RF Power in a Wireless Link</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="imageblock">
+<div class="content">
+<img src="link_budget.png" alt="link_budget.png" width="90%" />
+</div>
+</div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="rf-link-budget">Link Budget</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>The link budget consists of the total budget of all elements in the
+telecommunication system between BTS and MS (and vice-versa).</p></div>
+<div class="paragraph"><p>This includes</p></div>
+<ul class="">
+<li>
+<span>
+antenna gains on both sides
+</span>
+</li>
+<li>
+<span>
+coaxial cabling between antenna and receiver/transmitter
+</span>
+</li>
+<li>
+<span>
+losses in duplexers, splitters, connectors, etc
+</span>
+</li>
+<li>
+<span>
+gain of any amplifiers (PA, LNA)
+</span>
+</li>
+<li>
+<span>
+path loss of the radio link between the two antennas
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_simplified_link_budget_equation">Simplified Link Budget Equation</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>The simplified link budget equations looks like this:</p></div>
+<div class="listingblock">
+<div class="content">
+<pre><code>Rx Power (dBm) = Tx Power (dBm) + Gains (dB) − Losses (dB)</code></pre>
+</div></div>
+<div class="paragraph"><p>Gains is the sum of all gains, including</p></div>
+<ul class="">
+<li>
+<span>
+Gain of the transmitter antenna
+</span>
+</li>
+<li>
+<span>
+Gain of the receiver antenna
+</span>
+</li>
+<li>
+<span>
+Gain of any PA (transmitter) or LNA (receiver)
+</span>
+</li>
+</ul>
+<div class="paragraph"><p>Losses is the sum of all losses, including</p></div>
+<ul class="">
+<li>
+<span>
+Loss of any cabling and/or connectors on either side
+</span>
+</li>
+<li>
+<span>
+Loss of any passive components like duplexers/splitters on either side
+</span>
+</li>
+<li>
+<span>
+Path Loss of the radio link
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_link_budget_equation_vs_path_loss">Link Budget Equation vs. Path Loss</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+Using the Link Budget equation and resolving it for the path loss will
+ give you an idea of how much path loss on the radio link you can afford
+ while still having a reliable radio link.
+</span>
+</li>
+<li>
+<span>
+Resolving the path loss into a physical distance based on your path
+ loss model will then give you an idea about the coverage area that
+ you can expect.
+</span>
+<div class="dlist"><dl class="">
+<dt class="hdlist1">
+NOTE
+</dt>
+<dd>
+<p>
+The Rx Power substituted in the Link budget equation is
+determined by the receiver sensitivity. It is customary to add some
+some safety margin to cover for fading.
+</p>
+</dd>
+</dl></div>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_rf_link">RF Link</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="imageblock">
+<div class="content">
+<img src="ap_to_client.png" alt="ap_to_client.png" width="90%" />
+</div>
+</div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_uplink_link_budget">Uplink Link Budget</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="imageblock graphviz">
+<div class="content">
+<img src="path_loss_link_budget__1.png" alt="path_loss_link_budget__1.png" />
+</div>
+</div>
+<div class="paragraph"><p>The transmit power of a MS depends on various factors, such as the MS
+Power Class, the frequency band and the modulation scheme used.</p></div>
+<div class="tableblock">
+<table rules="all"
+width="100%"
+frame="border"
+cellspacing="0" cellpadding="4">
+<caption class="title">Table 2. Typical MS transmit power levels</caption>
+<col width="25%" />
+<col width="25%" />
+<col width="25%" />
+<col width="25%" />
+<thead>
+<tr>
+<th align="left" valign="top">Power Class</th>
+<th align="left" valign="top">Band</th>
+<th align="left" valign="top">Modulation</th>
+<th align="left" valign="top">Power</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td align="left" valign="top"><p class="table">4</p></td>
+<td align="left" valign="top"><p class="table">850 / 900</p></td>
+<td align="left" valign="top"><p class="table">GMSK</p></td>
+<td align="left" valign="top"><p class="table">33 dBm (2 W)</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">1</p></td>
+<td align="left" valign="top"><p class="table">1800 / 1900</p></td>
+<td align="left" valign="top"><p class="table">GMSK</p></td>
+<td align="left" valign="top"><p class="table">30 dBm (1 W)</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">E2</p></td>
+<td align="left" valign="top"><p class="table">850 / 900</p></td>
+<td align="left" valign="top"><p class="table">8PSK</p></td>
+<td align="left" valign="top"><p class="table">27 dBm (0.5 W)</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">E2</p></td>
+<td align="left" valign="top"><p class="table">1800 / 1900</p></td>
+<td align="left" valign="top"><p class="table">8PSK</p></td>
+<td align="left" valign="top"><p class="table">26 dBm (0.4 W)</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="paragraph"><p>The minimum reference sensitivity level of a normal GSM BTS is specified
+in 3GPP TS 05.05 and required to be at least -104 dBm. Most modern BTSs
+outperform this significantly.</p></div>
+<div class="paragraph"><p>FIXME: Example calculation (spreadsheet screenshot?)</p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_downlink_link_budget">Downlink Link Budget</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="imageblock graphviz">
+<div class="content">
+<img src="path_loss_link_budget__2.png" alt="path_loss_link_budget__2.png" />
+</div>
+</div>
+<div class="paragraph"><p>The transmit power of the BTS depends on your BTS model and any possible
+external power amplifiers used.</p></div>
+<div class="paragraph"><p>The minimum reference sensitivity level of a GSM MS is specified in 3GPP
+TS 05.05 and can typically be assumed to be about -102 dB.</p></div>
+<div class="paragraph"><p>FIXME: Example calculation (spreadsheet screenshot?)</p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_optimization_of_the_link_budget">Optimization of the Link Budget</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>If the coverage area determined by the above procedure is insufficient,
+you can try to change some of the parameters, such as</p></div>
+<ul class="">
+<li>
+<span>
+increasing transmit power by adding a bigger PA
+</span>
+</li>
+<li>
+<span>
+increasing antenna gain by using a higher gain antenna
+</span>
+</li>
+<li>
+<span>
+reducing cable losses by using better / shorter coaxial cables
+</span>
+</li>
+<li>
+<span>
+increasing the height of your antenna
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_introduction_into_rf_electronics">Introduction into RF Electronics</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>Setup and Operation of a GSM network is not only about the configuration
+and system administration on the network elements and protocol stack,
+but also includes the physical radio transmission part.</p></div>
+<div class="paragraph"><p>Basic understanding about RF (Radio Frequency) Electronics is key to
+achieving good performance of the GSM network.</p></div>
+<div class="sect2">
+<h3 id="rf-coaxial-cabling">Coaxial Cabling</h3>
+<div class="paragraph"><p>Coaxial cables come in many different shapes, diameters, physical
+construction, dielectric materials, and last but not least brands and
+types.</p></div>
+<div class="paragraph"><p>There are many parameters that might be relevant to your particular
+installation, starting from mechanical/environmental properties such as
+temperature range, UV resilience, water/weatherproofness, flammability,
+etc.</p></div>
+<div class="paragraph"><p>For the subject of this manual, we will not look at those mechanical
+properties, but look at the electrical properties instead.</p></div>
+<div class="paragraph"><p>The prime electrical parameters of a coaxial cable are:</p></div>
+<ul class="">
+<li>
+<span>
+its attenuation over frequency and length
+</span>
+</li>
+<li>
+<span>
+its maximum current/power handling capability
+</span>
+</li>
+<li>
+<span>
+its propagation velocity (ignored here)
+</span>
+</li>
+<li>
+<span>
+its screening efficiency (ignored here)
+</span>
+</li>
+</ul>
+<div class="sect3">
+<h4 id="_coaxial_cable_attenuation">Coaxial Cable Attenuation</h4>
+<div class="paragraph"><p>The attenuation of a coaxial cable is given in dB per length, commonly
+in <em>dB per 100m</em>. This value changes significantly depending on the
+frequency of the signal transmitted via the cable. Cable manufacturers
+typically either provide tables with discrete frequency values, or
+graphs plotting the attenuation per 100m (x axis) over the frequency (y
+axis).</p></div>
+<div class="paragraph"><p>FIXME: Example.</p></div>
+<div class="paragraph"><p>So in order to estimate the loss of a coaxial cable, you need to</p></div>
+<ol class="arabic">
+<li>
+<span>
+determine the frequency at which you will use the cable, as determined
+ by the GSM frequency band of your BTS. Make sure you use the highest
+ frequency that might occur, which is typically the upper end of the
+ transmit band, see <a href="#gsm-bands">[gsm-bands]</a>
+</span>
+</li>
+<li>
+<span>
+determine the attenuation of your cable per 100m at the given
+ frequency (check the cable data sheet)
+</span>
+</li>
+<li>
+<span>
+scale that value by the actual length of the cable
+</span>
+</li>
+</ol>
+<div class="paragraph"><p>A real cable always has connectors attached to it, please add some
+additional losses for the connectors that are attached. 0.05 dB per
+connector is a general rule of thumb for the frequencies used in GSM.</p></div>
+<div class="paragraph"><p>FIXME: Example computation</p></div>
+<div class="paragraph"><p>As you can see very easily, the losses incurred in coaxial cables
+between your antenna and the BTS can very quickly become significant
+factors in your overall link budget (and thus cell coverage). This is
+particularly relevant for the uplink power budget. Every dB you loose
+in the antenna cable between antenna and the BTS receiver translates
+into reduced uplink coverage.</p></div>
+<div class="paragraph"><p>Using the shortest possible coaxial cabling (e.g. by mounting the BTS
+high up on the antenna tower) and using the highest-quality cabling are
+the best strategies to optimize</p></div>
+<div class="admonitionblock">
+<table><tr>
+<td class="icon">
+<div class="title">Warning</div>
+</td>
+<td class="content">If you plan to assemble the coaxial connectors yourself, please
+make sure you ensure to have the right skills for this. Properly
+assembling coaxial connectors (whether solder-type or crimp-type)
+requires precision tools and strict process as described by the
+manufacturer. Any mechanical imprecision of connector assembly will
+cause significant extra signal attenuation.</td>
+</tr></table>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_checking_coaxial_cables">Checking coaxial cables</h4>
+<div class="paragraph"><p>If you would like to check the proper operation of a coaxial cable,
+there are several possible methods available:</p></div>
+<ul class="">
+<li>
+<span>
+The more expensive method would be to use a <em>RF Network Analyzer</em> to
+ measure the S11/S12 parameters or the VSWR of the cable.
+</span>
+</li>
+<li>
+<span>
+Another option is to use a TDR (time domain reflectometer) to
+ determine the VSWR. The TDR method has the added advantage that you
+ can localize any damage to the cable, as such damage would cause
+ reflections that can be converted into meters cable length from the
+ port at which you are testing the cable. Mobile, battery-powered TDR
+ for field-use in GSM Site installation are available from various
+ vendors. One commonly used series is the <em>Anritsu Site Master</em>.
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect2">
+<h3 id="rf-coaxial-connectors">Coaxial Connectors</h3>
+<div class="paragraph"><p>A coaxial connector is a connector specifically designed for mounting to
+coaxial cable. It facilitates the removable / detachable connection of
+a coaxial cable to a RF device.</p></div>
+<div class="paragraph"><p>There are many different types of coaxial connectors on the market.</p></div>
+<div class="paragraph"><p>The most important types of coaxial connectors in the context of GSM
+BTSs are:</p></div>
+<ul class="">
+<li>
+<span>
+The <em>N type</em> connector
+</span>
+</li>
+<li>
+<span>
+The <em>SMA type</em> connector.
+</span>
+</li>
+<li>
+<span>
+The <em>7/16</em> type connector
+</span>
+</li>
+</ul>
+<div class="paragraph"><p>FIXME: Images</p></div>
+<div class="paragraph"><p>The above connectors are tightened by a screw-on shell. Each connector
+type has a specific designated nominal torque by which the connector
+shall be tightened. In case of uncertainty, please ask your connector
+supplier for the nominal torque.</p></div>
+<div class="admonitionblock">
+<table><tr>
+<td class="icon">
+<div class="title">Note</div>
+</td>
+<td class="content">Always ensure the proper mechanical condition of your RF
+connectors. Don&#8217;t use RF connectors that are contaminated by dust or
+dirt, or which show significant oxidization, bent contacts or the like.
+Using such connectors poses significant danger of unwanted signal loss,
+and can in some cases even lead to equipment damage (e.g. in case of RF
+power at PA output being reflected back into the PA).</td>
+</tr></table>
+</div>
+</div>
+<div class="sect2">
+<h3 id="rf-duplexers">Duplexers</h3>
+<div class="paragraph"><p>A GSM BTS (or GSM TRX inside a BTS) typically exposes separate ports for
+Rx (Receive) and Tx (Transmit). This is intentionally the case, as
+this allows the users to add e.g. additional power amplifiers, filters
+or other external components into the signal path. Those components
+typically operate on either the receive or the transmit path.</p></div>
+<div class="paragraph"><p>You could now connect two separate antennas to the two ports (one for
+Rx, one for Tx). This is commonly done in indoor installations with
+small rubber-type antennas directly attached to the BTS connectors.</p></div>
+<div class="paragraph"><p>In outdoor installations, you typically (want to) use a single Antenna
+for Rx and Tx. This single antenna needs to be connected to the BTS
+via a device that is called <em>Duplexer</em>.</p></div>
+<div class="paragraph"><p>The <em>Duplexer</em> is actually a frequency splitter/combiner, which is
+specifically tuned to the uplink and downlink frequencies of the GSM
+band in which you operate the BTS. As such, it has one port that passes
+only uplink frequencies between the antenna and that port, as well as
+another port that passes only downlink frequencies between antenna and
+that port.</p></div>
+<div class="imageblock graphviz">
+<div class="content">
+<img src="path_loss_link_budget__3.png" alt="path_loss_link_budget__3.png" />
+</div>
+<div class="title">Figure 1. Illustration of the Duplexer functionality</div>
+</div>
+<div class="admonitionblock">
+<table><tr>
+<td class="icon">
+<div class="title">Warning</div>
+</td>
+<td class="content"><strong>The ports of a duplexer are not interchangeable</strong>. Always make
+sure that you use the Rx port of the duplexer with the Rx port of the
+BTS, and vice-versa for Tx.</td>
+</tr></table>
+</div>
+</div>
+<div class="sect2">
+<h3 id="rf-pa">RF Power Amplifiers</h3>
+<div class="paragraph"><p>A RF Power Amplifier (PA) is a device that boosts the transmit power of
+your RF signal, the BTS in your case.</p></div>
+<div class="paragraph"><p>RF power amplifiers come in many different characteristics. Some of the
+key characteristics are:</p></div>
+<div class="dlist"><dl class="">
+<dt class="hdlist1">
+Frequency range
+</dt>
+<dd>
+<p>
+ A PA is typically designed for a specific frequency range. Only
+ signals inside that range will be properly amplified
+</p>
+</dd>
+<dt class="hdlist1">
+Gain in dB
+</dt>
+<dd>
+<p>
+ This tells you how many dB the power amplifier will increase your
+ signal. <code>Pout = Pin + Gain</code>
+</p>
+</dd>
+<dt class="hdlist1">
+Maximum Output Power
+</dt>
+<dd>
+<p>
+ This indicates the maximum absolute output power. For example, if the
+ maximum output power is 40 dBm, and the gain is 10dBm, then an input
+ signal of 30dBm will render the maximum output power. An input signal
+ of 20dBm would subsequently generate only 30dBm of output power.
+</p>
+</dd>
+<dt class="hdlist1">
+Efficiency
+</dt>
+<dd>
+<p>
+ The efficiency determines how much electrical power is consumed for
+ the given output power. Often expressed as Power Added Efficiency
+ (PAE).
+</p>
+</dd>
+</dl></div>
+<div class="admonitionblock">
+<table><tr>
+<td class="icon">
+<div class="title">Warning</div>
+</td>
+<td class="content">If you add external power amplifiers to a GSM BTS or any other
+transmitter, this will invalidate the regulatory approval of the BTS.
+It is your responsibility to ensure that the combination of BTS and PA
+still fulfills all regulatory requirements, for example in terms of
+out-of-band emissions, spectrum envelope, phase error, linearity, etc!</td>
+</tr></table>
+</div>
+<div class="imageblock graphviz">
+<div class="content">
+<img src="path_loss_link_budget__4.png" alt="path_loss_link_budget__4.png" />
+</div>
+<div class="title">Figure 2. Addition of a RF Power Amplifier to a GSM BTS Setup</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_antennas">Antennas</h3>
+<div class="paragraph"><p>The Antenna is responsible for converting the electromagnetic waves
+between the coaxial cable and the so-called <em>air interface</em> and
+vice-versa. The properties of an antenna are always symmetric for both
+transmission and reception.</p></div>
+<div class="paragraph"><p>Antennas come in many different types and shapes. Key characteristics
+distinguishing antennas are:</p></div>
+<div class="dlist"><dl class="">
+<dt class="hdlist1">
+Antenna Gain
+</dt>
+<dd>
+<p>
+ Expresses how much more efficient the antenna converts between cable
+ and air interface. Can be expressed in dB compared to a theoretical
+ isotropic radiator (dBi) or compared to a dipole antenna (dBd). Gain
+ usually implies directivity.
+</p>
+</dd>
+<dt class="hdlist1">
+Frequency Band(s)
+</dt>
+<dd>
+<p>
+ Antennas typically have only a relatively narrow band (or multiple
+ narrow bands at which they radiate efficiently. In general, the
+ higher the antenna gain, the lower the usable frequency band of the
+ antenna.
+</p>
+</dd>
+<dt class="hdlist1">
+Directivity
+</dt>
+<dd>
+<p>
+ Antennas radiate the energy in all three dimensions.
+</p>
+</dd>
+<dt class="hdlist1">
+Mechanical Size
+</dt>
+<dd>
+<p>
+ Mechanical Size is an important factor depending on how and where the
+ antenna is mounted. Size also relates to weight and wind-load.
+</p>
+</dd>
+<dt class="hdlist1">
+Wind Load
+</dt>
+<dd>
+<p>
+ Expresses how much mechanical load the antenna will put on its
+ support structure (antenna mast).
+</p>
+</dd>
+<dt class="hdlist1">
+Connector Type
+</dt>
+<dd>
+<p>
+ Your cabling will have to use a compatible connector for the antenna.
+ Outdoor antennas typically use the 7/16 type connector or an N type
+ connector. Indoor antennas either N type or SMA type.
+</p>
+</dd>
+<dt class="hdlist1">
+Environmental Rating
+</dt>
+<dd>
+<p>
+ Indoor antennas cannot be used outdoor, as they do not offer the level
+ of protection against dust and particularly water / humidity /
+ corrosion.
+</p>
+</dd>
+<dt class="hdlist1">
+Down-tilt Capability
+</dt>
+<dd>
+<p>
+ Particularly sector antennas are typically installed with a fixed or
+ (mechanically / electrically) variable down-tilt in order to limit the
+ radius/horizon of the antenna footprint and avoid excess interference
+ with surrounding cells.
+</p>
+</dd>
+<dt class="hdlist1">
+VSWR
+</dt>
+<dd>
+<p>
+ The Voltage Standing Wave Ratio indicates how well the antenna is
+ matched to the coaxial cable, and how much of the to-be-transmitted
+ radio signal is actually converted to radio waves versus reflected
+ back on the RF cable towards the transmitter. An ideal antenna has a
+ VSWR of 1 (sometimes written 1:1). Real antennas are typically in the
+ range of 1.2 to 2.
+</p>
+</dd>
+<dt class="hdlist1">
+Side Lobes
+</dt>
+<dd>
+<p>
+ A directional antenna never radiates only in one direction but always
+ has certain side lobes pointing outside of the main direction of the
+ antenna. The number and strength of side lobes differ from antenna
+ to antenna model.
+</p>
+</dd>
+</dl></div>
+<div class="admonitionblock">
+<table><tr>
+<td class="icon">
+<div class="title">Note</div>
+</td>
+<td class="content">Whenever installing antennas it is important to understand that
+any metallic or otherwise conductive object in their vicinity will
+inevitably alter the antenna performance. This can affect the radiation
+pattern, but also de-tune the antenna and shift its frequency band
+outside the nominal usable frequency band. It is thus best to mount
+antennas as far as practically possible from conductive elements within
+their radiation pattern</td>
+</tr></table>
+</div>
+<div class="sect3">
+<h4 id="_omni_directional_antennas">Omni-directional Antennas</h4>
+<div class="paragraph"><p>Omni-directional antennas are typically thin long dipole antennas covered
+with fiberglass. They radiate with equal strength in all directions and
+thus result in a more or less circular cell footprint (assuming flat
+terrain). The shape of the radiation pattern is a torus (donut) with
+the antenna located in the center of that torus.</p></div>
+<div class="paragraph"><p>Omni-directional antennas come with a variety of gains, typically from 0
+dBd to 3 dBd, 6 dBd and sometimes 9 dBd. This gain is achieved by
+compressing the radiation torus in the vertical plane.</p></div>
+<div class="paragraph"><p>Sometimes, Omni-directional antennas can be obtained with a fixed
+down-tilt to limit the cell radius.</p></div>
+</div>
+<div class="sect3">
+<h4 id="_sector_antennas">Sector Antennas</h4>
+<div class="paragraph"><p>Sector antennas are used in sectorized cell setups. Sector antennas can
+have significantly higher gain than omni-directional antennas.</p></div>
+<div class="paragraph"><p>Instead of mounting a single BTS with an omni-directional antenna to a
+given antenna pole, multiple BTSs with each one sector antenna are
+mounted to the same pole. This results in an overall larger radius due
+to the higher gain of the sector antennas, and also in an overall
+capacity increase, as each sector has the same capacity as a single
+omni-directional cell. And all that benefit still requires only a
+single physical site with antenna pole, power supply, back-haul cabling,
+etc.</p></div>
+<div class="paragraph"><p>Experimentation and simulation has shown that typically the use of three
+sectors with antennas of an opening angle of 65 degrees results in the
+most optimal combination for GSM networks. If more sectors are being
+deployed, there is a lot of overlap between the sectors, and the amount
+of hand-overs between the BTSs is increased.</p></div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="rf-lna">RF Low Noise Amplifier (LNA)</h3>
+<div class="paragraph"><p>A RF Low Noise Amplifier (LNA) is a device that amplifies the weak
+received signal. In general, LNAs are combined with band filters, to
+ensure that only those frequencies within the receive band are
+amplified, and out-of-band interferers are filtered out. A duplexer
+can already be a sufficient band-filter, depending on its
+characteristics.</p></div>
+<div class="paragraph"><p>The use of a LNA typically only makes sense if you
+. have very long and/or lossy coaxial cables from your antenna to the
+ BTS, and
+. can mount the duplexer + LNA close to the antenna, so that the
+ amplification happens before the long/lossy coaxial line to the BTS</p></div>
+<div class="paragraph"><p>Key characteristics of a LNA are:</p></div>
+<div class="dlist"><dl class="">
+<dt class="hdlist1">
+Frequency range
+</dt>
+<dd>
+<p>
+ A LNA is typically designed for a specific frequency range. Only
+ signals inside that range will be properly amplified
+</p>
+</dd>
+<dt class="hdlist1">
+Gain in dB
+</dt>
+<dd>
+<p>
+ This tells you how many dB the low noise amplifier will increase your
+ signal. <code>Pout = Pin + Gain</code>
+</p>
+</dd>
+<dt class="hdlist1">
+Maximum Input Power
+</dt>
+<dd>
+<p>
+ This indicates the maximum RF power at the PA input before saturation.
+</p>
+</dd>
+<dt class="hdlist1">
+Noise Figure
+</dt>
+<dd>
+<p>
+ This indicates how much noise this LNA will add to the signal. This
+ noise will add to the interference as seen by the receiver.
+</p>
+</dd>
+</dl></div>
+<div class="imageblock graphviz">
+<div class="content">
+<img src="path_loss_link_budget__5.png" alt="path_loss_link_budget__5.png" />
+</div>
+<div class="title">Figure 3. Addition of a RF Low Noise Amplifier to the GSM BTS Setup</div>
+</div>
+<div class="imageblock graphviz">
+<div class="content">
+<img src="path_loss_link_budget__6.png" alt="path_loss_link_budget__6.png" />
+</div>
+<div class="title">Figure 4. Addition of a RF LNA + RF PA to the GSM BTS Setup</div>
+</div>
+<div class="paragraph"><p>As any LNA will add noise to the signal, it is generally discouraged to
+add them to the system. Instead, we recommend you to mount the entire
+BTS closer to the antenna, thereby removing the losses created by
+lengthy coaxial wire. The power supply lines and Ethernet connection to
+the BTS are far less critical when it comes to cable length.</p></div>
+</div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_introduction_into_gsm_radio_planning">Introduction into GSM Radio Planning</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>The main focus of the manual you are reading is to document the
+specifics of the Osmocom GSM implementation in terms of configuration,
+system administration and monitoring. That&#8217;s basically all on the
+software part.</p></div>
+<div class="paragraph"><p>However, successful deployment and operation of GSM networks depends to
+a large extent on the proper design on the radio frequency (RF) side,
+including the right cabling, duplexers, antennas, etc.</p></div>
+<div class="paragraph"><p>Planning and implementing GSM deployment is a science (or art) in
+itself, and in most cases it is best to consult with somebody who has
+existing experience in the field.</p></div>
+<div class="paragraph"><p>There are three parts to this:</p></div>
+<div class="dlist"><dl class="">
+<dt class="hdlist1">
+GSM Radio Network Planning
+</dt>
+<dd>
+<p>
+ This includes an analysis of the coverage area, its terrain/geography,
+ the selection of the right sites for your BTSs, the antenna height, a
+ path loss estimate. As a result of that process, it will be clear
+ what amount of transmit power, antenna gain, cable length/type, etc.
+ you should use to obtain the intended coverage.
+</p>
+</dd>
+<dt class="hdlist1">
+GSM Site Installation
+</dt>
+<dd>
+<p>
+ This is the execution of what has been determined in the previous
+ step. The required skills are quite different, as this is about
+ properly assembling RF cables and connections, duplexers, power
+ amplifiers, antennas, etc.
+</p>
+</dd>
+<dt class="hdlist1">
+Coverage testing
+</dt>
+<dd>
+<p>
+ This is typically done by driving or walking in the newly-deployed GSM
+ site, and checking of the coverage is as it was expected.
+</p>
+</dd>
+</dl></div>
+<div class="admonitionblock">
+<table><tr>
+<td class="icon">
+<div class="title">Note</div>
+</td>
+<td class="content">This chapter can only give you the briefest overview about the
+process used, and cannot replace the experience and skill of somebody
+with GSM RF planning and site deployment.</td>
+</tr></table>
+</div>
+<div class="sect2">
+<h3 id="rf-radio-net-plan">GSM Radio Network Planning</h3>
+<div class="paragraph"><p>In GSM Radio Network Planning, the number and location of sites as well
+as type of required equipment is determined based on the coverage
+requirements.</p></div>
+<div class="paragraph"><p>For the coverage of a single BTS, this is a process that takes into
+consideration:</p></div>
+<ul class="">
+<li>
+<span>
+the terrain that needs to be covered
+</span>
+</li>
+<li>
+<span>
+the type of mobile stations to be supported, and particularly the
+ speed of their movement (residential, pedestrians, trains, highways)
+</span>
+</li>
+<li>
+<span>
+the possible locations for cell sites, where BTSs and Antennas can be
+ placed, as well as the possible antenna mounting height
+</span>
+</li>
+<li>
+<span>
+the equipment choices available, including
+</span>
+<ul class="">
+<li>
+<span>
+type and capabilities of BTS. The key criteria here is
+ the downlink transmit power in dBm, and the uplink receive
+ sensitivity.
+</span>
+</li>
+<li>
+<span>
+antenna models, including gain, radiation pattern, etc.
+</span>
+</li>
+<li>
+<span>
+RF cabling, including the key aspect of attenuation per length
+</span>
+</li>
+<li>
+<span>
+RF duplexers, splitting the transmit and receive path
+</span>
+</li>
+<li>
+<span>
+power amplifiers (PAs), increasing the transmit power
+</span>
+</li>
+<li>
+<span>
+low noise amplifiers (LNAs), amplifying the received signal
+</span>
+</li>
+</ul>
+</li>
+</ul>
+<div class="paragraph"><p>For coverage of an actual cellular network consisting of neighboring
+cells, this process also must take into consideration aspects of
+<em>frequency planning</em>, which is the allocation of frequencies (ARFCNs) to
+the individual cells within the network. As part of that, interference
+generated by frequency re-use of other (distant) cells must be taken
+into consideration. The details of this would go beyond this very
+introductory text. There is plenty of literature on this subject
+available.</p></div>
+</div>
+<div class="sect2">
+<h3 id="rf-db">The Decibel (dB) and Decibel-Milliwatt (dBm)</h3>
+<div class="paragraph"><p>RF engineering heavily depends on the Decibel (dB) as a unit to express
+attenuation (losses) or amplification (gain) impacted on radio signals.</p></div>
+<div class="paragraph"><p>The dB is a logarithmic unit, it is used to express the ratio of two
+values of physical quantity. You can thus not express an absolute value
+in dB, only relative.</p></div>
+<div class="admonitionblock">
+<table><tr>
+<td class="icon">
+<div class="title">Note</div>
+</td>
+<td class="content"><strong>Relative loss</strong> (cable, connector, duplexer, splitter) <strong>or gain</strong>
+(amplifiers) are power <strong>is expressed in dB</strong>.</td>
+</tr></table>
+</div>
+<div class="paragraph"><p>In order to express an absolute value, you need to use a unit like
+<em>dBm</em>, which is referencing a power of 1 mW (milli-Watt).</p></div>
+<div class="admonitionblock">
+<table><tr>
+<td class="icon">
+<div class="title">Note</div>
+</td>
+<td class="content"><strong>Absolute power</strong> like transmitter output power or receiver input
+power <strong>is expressed in dBm</strong>.</td>
+</tr></table>
+</div>
+<div class="tableblock">
+<table rules="all"
+width="100%"
+frame="border"
+cellspacing="0" cellpadding="4">
+<caption class="title">Table 3. Example table of dBm values and their corresponding RF Power</caption>
+<col width="15%" />
+<col width="15%" />
+<col width="70%" />
+<thead>
+<tr>
+<th align="left" valign="top">dBm</th>
+<th align="left" valign="top">RF Power</th>
+<th align="left" valign="top">Comment</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td align="left" valign="top"><p class="table">0</p></td>
+<td align="left" valign="top"><p class="table">1 mW</p></td>
+<td align="left" valign="top"><p class="table"></p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">1</p></td>
+<td align="left" valign="top"><p class="table">1.26 mW</p></td>
+<td align="left" valign="top"><p class="table">transmit power of sysmoBTS 1002 when used with <code>max_power_red 22</code></p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">3</p></td>
+<td align="left" valign="top"><p class="table">2 mW</p></td>
+<td align="left" valign="top"><p class="table"></p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">6</p></td>
+<td align="left" valign="top"><p class="table">4 mW</p></td>
+<td align="left" valign="top"><p class="table"></p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">12</p></td>
+<td align="left" valign="top"><p class="table">16 mW</p></td>
+<td align="left" valign="top"><p class="table"></p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">12</p></td>
+<td align="left" valign="top"><p class="table">16 mW</p></td>
+<td align="left" valign="top"><p class="table"></p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">20</p></td>
+<td align="left" valign="top"><p class="table">100 mW</p></td>
+<td align="left" valign="top"><p class="table"></p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">23</p></td>
+<td align="left" valign="top"><p class="table">199 mW</p></td>
+<td align="left" valign="top"><p class="table">Maximum transmit power of indoor sysmoBTS 1002</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">26</p></td>
+<td align="left" valign="top"><p class="table">398 mW</p></td>
+<td align="left" valign="top"><p class="table"></p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">30</p></td>
+<td align="left" valign="top"><p class="table">1 W</p></td>
+<td align="left" valign="top"><p class="table">Maximum transmit power of a MS in 1800/1900 MHz band</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">33</p></td>
+<td align="left" valign="top"><p class="table">2 W</p></td>
+<td align="left" valign="top"><p class="table">Maximum transmit power of a MS in 850/900 MHz band</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">37</p></td>
+<td align="left" valign="top"><p class="table">5 W</p></td>
+<td align="left" valign="top"><p class="table">Maximum transmit power of 1 TRX in sysmoBTS 2050</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">40</p></td>
+<td align="left" valign="top"><p class="table">10 W</p></td>
+<td align="left" valign="top"><p class="table">Maximum transmit power of sysmoBTS 1100</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+<div class="sect2">
+<h3 id="rf-gsm-bands">GSM Frequency Bands</h3>
+<div class="paragraph"><p>GSM can operate in a variety of frequency bands. However,
+internationally only the following four bands have been deployed in
+actual networks:</p></div>
+<div class="tableblock">
+<table rules="all"
+width="100%"
+frame="border"
+cellspacing="0" cellpadding="4">
+<caption class="title">Table 4. Table of GSM Frequency Bands</caption>
+<col width="25%" />
+<col width="25%" />
+<col width="25%" />
+<col width="25%" />
+<thead>
+<tr>
+<th align="left" valign="top">Name</th>
+<th align="left" valign="top">Uplink Band</th>
+<th align="left" valign="top">Downlink Band</th>
+<th align="left" valign="top">ARFCN Range</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td align="left" valign="top"><p class="table">GSM 850</p></td>
+<td align="left" valign="top"><p class="table">824 MHz .. 849 MHz</p></td>
+<td align="left" valign="top"><p class="table">869 MHz .. 894 MHz</p></td>
+<td align="left" valign="top"><p class="table">128 .. 251</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">E-GSM 900</p></td>
+<td align="left" valign="top"><p class="table">880 MHz .. 915 MHz</p></td>
+<td align="left" valign="top"><p class="table">925 MHz .. 960 MHz</p></td>
+<td align="left" valign="top"><p class="table">0 .. 124, 975 .. 1023</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">DCS 1800</p></td>
+<td align="left" valign="top"><p class="table">1710 MHz .. 1785 MHz</p></td>
+<td align="left" valign="top"><p class="table">1805 MHz .. 1880 MHz</p></td>
+<td align="left" valign="top"><p class="table">512 .. 885</p></td>
+</tr>
+<tr>
+<td align="left" valign="top"><p class="table">PCS 1900</p></td>
+<td align="left" valign="top"><p class="table">1850 MHz .. 1910 MHz</p></td>
+<td align="left" valign="top"><p class="table">1930 MHz .. 1990 MHz</p></td>
+<td align="left" valign="top"><p class="table">512 .. 810</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_the_end">The End</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>Questions?</p></div>
+</div>
+</div>
+</body>
+</html>
diff --git a/2017/roadmap-osmocon2017/roadmap.html b/2017/roadmap-osmocon2017/roadmap.html
new file mode 100644
index 0000000..c1950f6
--- /dev/null
+++ b/2017/roadmap-osmocon2017/roadmap.html
@@ -0,0 +1,4448 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>Osmocom Callular Infrastructure Roadmap</title>
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
+<meta name="copyright" content="Copyright &#169; Harald Welte (License: CC-BY-SA)" />
+<meta name="generator" content="AsciiDoc 8.6.9" />
+<style type="text/css">
+/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
+
+/* Default font. */
+body {
+ font-family: Georgia,serif;
+}
+
+/* Title font. */
+h1, h2, h3, h4, h5, h6,
+div.title, caption.title,
+thead, p.table.header,
+#toctitle,
+#author, #revnumber, #revdate, #revremark,
+#footer {
+ font-family: Arial,Helvetica,sans-serif;
+}
+
+body {
+ margin: 1em 5% 1em 5%;
+}
+
+a {
+ color: blue;
+ text-decoration: underline;
+}
+a:visited {
+ color: fuchsia;
+}
+
+em {
+ font-style: italic;
+ color: navy;
+}
+
+strong {
+ font-weight: bold;
+ color: #083194;
+}
+
+h1, h2, h3, h4, h5, h6 {
+ color: #527bbd;
+ margin-top: 1.2em;
+ margin-bottom: 0.5em;
+ line-height: 1.3;
+}
+
+h1, h2, h3 {
+ border-bottom: 2px solid silver;
+}
+h2 {
+ padding-top: 0.5em;
+}
+h3 {
+ float: left;
+}
+h3 + * {
+ clear: left;
+}
+h5 {
+ font-size: 1.0em;
+}
+
+div.sectionbody {
+ margin-left: 0;
+}
+
+hr {
+ border: 1px solid silver;
+}
+
+p {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+ul, ol, li > p {
+ margin-top: 0;
+}
+ul > li { color: #aaa; }
+ul > li > * { color: black; }
+
+.monospaced, code, pre {
+ font-family: "Courier New", Courier, monospace;
+ font-size: inherit;
+ color: navy;
+ padding: 0;
+ margin: 0;
+}
+pre {
+ white-space: pre-wrap;
+}
+
+#author {
+ color: #527bbd;
+ font-weight: bold;
+ font-size: 1.1em;
+}
+#email {
+}
+#revnumber, #revdate, #revremark {
+}
+
+#footer {
+ font-size: small;
+ border-top: 2px solid silver;
+ padding-top: 0.5em;
+ margin-top: 4.0em;
+}
+#footer-text {
+ float: left;
+ padding-bottom: 0.5em;
+}
+#footer-badges {
+ float: right;
+ padding-bottom: 0.5em;
+}
+
+#preamble {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
+div.imageblock, div.exampleblock, div.verseblock,
+div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
+div.admonitionblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.admonitionblock {
+ margin-top: 2.0em;
+ margin-bottom: 2.0em;
+ margin-right: 10%;
+ color: #606060;
+}
+
+div.content { /* Block element content. */
+ padding: 0;
+}
+
+/* Block element titles. */
+div.title, caption.title {
+ color: #527bbd;
+ font-weight: bold;
+ text-align: left;
+ margin-top: 1.0em;
+ margin-bottom: 0.5em;
+}
+div.title + * {
+ margin-top: 0;
+}
+
+td div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content div.title:first-child {
+ margin-top: 0.0em;
+}
+div.content + div.title {
+ margin-top: 0.0em;
+}
+
+div.sidebarblock > div.content {
+ background: #ffffee;
+ border: 1px solid #dddddd;
+ border-left: 4px solid #f0f0f0;
+ padding: 0.5em;
+}
+
+div.listingblock > div.content {
+ border: 1px solid #dddddd;
+ border-left: 5px solid #f0f0f0;
+ background: #f8f8f8;
+ padding: 0.5em;
+}
+
+div.quoteblock, div.verseblock {
+ padding-left: 1.0em;
+ margin-left: 1.0em;
+ margin-right: 10%;
+ border-left: 5px solid #f0f0f0;
+ color: #888;
+}
+
+div.quoteblock > div.attribution {
+ padding-top: 0.5em;
+ text-align: right;
+}
+
+div.verseblock > pre.content {
+ font-family: inherit;
+ font-size: inherit;
+}
+div.verseblock > div.attribution {
+ padding-top: 0.75em;
+ text-align: left;
+}
+/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
+div.verseblock + div.attribution {
+ text-align: left;
+}
+
+div.admonitionblock .icon {
+ vertical-align: top;
+ font-size: 1.1em;
+ font-weight: bold;
+ text-decoration: underline;
+ color: #527bbd;
+ padding-right: 0.5em;
+}
+div.admonitionblock td.content {
+ padding-left: 0.5em;
+ border-left: 3px solid #dddddd;
+}
+
+div.exampleblock > div.content {
+ border-left: 3px solid #dddddd;
+ padding-left: 0.5em;
+}
+
+div.imageblock div.content { padding-left: 0; }
+span.image img { border-style: none; vertical-align: text-bottom; }
+a.image:visited { color: white; }
+
+dl {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+dt {
+ margin-top: 0.5em;
+ margin-bottom: 0;
+ font-style: normal;
+ color: navy;
+}
+dd > *:first-child {
+ margin-top: 0.1em;
+}
+
+ul, ol {
+ list-style-position: outside;
+}
+ol.arabic {
+ list-style-type: decimal;
+}
+ol.loweralpha {
+ list-style-type: lower-alpha;
+}
+ol.upperalpha {
+ list-style-type: upper-alpha;
+}
+ol.lowerroman {
+ list-style-type: lower-roman;
+}
+ol.upperroman {
+ list-style-type: upper-roman;
+}
+
+div.compact ul, div.compact ol,
+div.compact p, div.compact p,
+div.compact div, div.compact div {
+ margin-top: 0.1em;
+ margin-bottom: 0.1em;
+}
+
+tfoot {
+ font-weight: bold;
+}
+td > div.verse {
+ white-space: pre;
+}
+
+div.hdlist {
+ margin-top: 0.8em;
+ margin-bottom: 0.8em;
+}
+div.hdlist tr {
+ padding-bottom: 15px;
+}
+dt.hdlist1.strong, td.hdlist1.strong {
+ font-weight: bold;
+}
+td.hdlist1 {
+ vertical-align: top;
+ font-style: normal;
+ padding-right: 0.8em;
+ color: navy;
+}
+td.hdlist2 {
+ vertical-align: top;
+}
+div.hdlist.compact tr {
+ margin: 0;
+ padding-bottom: 0;
+}
+
+.comment {
+ background: yellow;
+}
+
+.footnote, .footnoteref {
+ font-size: 0.8em;
+}
+
+span.footnote, span.footnoteref {
+ vertical-align: super;
+}
+
+#footnotes {
+ margin: 20px 0 20px 0;
+ padding: 7px 0 0 0;
+}
+
+#footnotes div.footnote {
+ margin: 0 0 5px 0;
+}
+
+#footnotes hr {
+ border: none;
+ border-top: 1px solid silver;
+ height: 1px;
+ text-align: left;
+ margin-left: 0;
+ width: 20%;
+ min-width: 100px;
+}
+
+div.colist td {
+ padding-right: 0.5em;
+ padding-bottom: 0.3em;
+ vertical-align: top;
+}
+div.colist td img {
+ margin-top: 0.3em;
+}
+
+@media print {
+ #footer-badges { display: none; }
+}
+
+#toc {
+ margin-bottom: 2.5em;
+}
+
+#toctitle {
+ color: #527bbd;
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 1.0em;
+ margin-bottom: 0.1em;
+}
+
+div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+div.toclevel2 {
+ margin-left: 2em;
+ font-size: 0.9em;
+}
+div.toclevel3 {
+ margin-left: 4em;
+ font-size: 0.9em;
+}
+div.toclevel4 {
+ margin-left: 6em;
+ font-size: 0.9em;
+}
+
+span.aqua { color: aqua; }
+span.black { color: black; }
+span.blue { color: blue; }
+span.fuchsia { color: fuchsia; }
+span.gray { color: gray; }
+span.green { color: green; }
+span.lime { color: lime; }
+span.maroon { color: maroon; }
+span.navy { color: navy; }
+span.olive { color: olive; }
+span.purple { color: purple; }
+span.red { color: red; }
+span.silver { color: silver; }
+span.teal { color: teal; }
+span.white { color: white; }
+span.yellow { color: yellow; }
+
+span.aqua-background { background: aqua; }
+span.black-background { background: black; }
+span.blue-background { background: blue; }
+span.fuchsia-background { background: fuchsia; }
+span.gray-background { background: gray; }
+span.green-background { background: green; }
+span.lime-background { background: lime; }
+span.maroon-background { background: maroon; }
+span.navy-background { background: navy; }
+span.olive-background { background: olive; }
+span.purple-background { background: purple; }
+span.red-background { background: red; }
+span.silver-background { background: silver; }
+span.teal-background { background: teal; }
+span.white-background { background: white; }
+span.yellow-background { background: yellow; }
+
+span.big { font-size: 2em; }
+span.small { font-size: 0.6em; }
+
+span.underline { text-decoration: underline; }
+span.overline { text-decoration: overline; }
+span.line-through { text-decoration: line-through; }
+
+div.unbreakable { page-break-inside: avoid; }
+
+
+/*
+ * xhtml11 specific
+ *
+ * */
+
+div.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+div.tableblock > table {
+ border: 3px solid #527bbd;
+}
+thead, p.table.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.table {
+ margin-top: 0;
+}
+/* Because the table frame attribute is overriden by CSS in most browsers. */
+div.tableblock > table[frame="void"] {
+ border-style: none;
+}
+div.tableblock > table[frame="hsides"] {
+ border-left-style: none;
+ border-right-style: none;
+}
+div.tableblock > table[frame="vsides"] {
+ border-top-style: none;
+ border-bottom-style: none;
+}
+
+
+/*
+ * html5 specific
+ *
+ * */
+
+table.tableblock {
+ margin-top: 1.0em;
+ margin-bottom: 1.5em;
+}
+thead, p.tableblock.header {
+ font-weight: bold;
+ color: #527bbd;
+}
+p.tableblock {
+ margin-top: 0;
+}
+table.tableblock {
+ border-width: 3px;
+ border-spacing: 0px;
+ border-style: solid;
+ border-color: #527bbd;
+ border-collapse: collapse;
+}
+th.tableblock, td.tableblock {
+ border-width: 1px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #527bbd;
+}
+
+table.tableblock.frame-topbot {
+ border-left-style: hidden;
+ border-right-style: hidden;
+}
+table.tableblock.frame-sides {
+ border-top-style: hidden;
+ border-bottom-style: hidden;
+}
+table.tableblock.frame-none {
+ border-style: hidden;
+}
+
+th.tableblock.halign-left, td.tableblock.halign-left {
+ text-align: left;
+}
+th.tableblock.halign-center, td.tableblock.halign-center {
+ text-align: center;
+}
+th.tableblock.halign-right, td.tableblock.halign-right {
+ text-align: right;
+}
+
+th.tableblock.valign-top, td.tableblock.valign-top {
+ vertical-align: top;
+}
+th.tableblock.valign-middle, td.tableblock.valign-middle {
+ vertical-align: middle;
+}
+th.tableblock.valign-bottom, td.tableblock.valign-bottom {
+ vertical-align: bottom;
+}
+
+
+/*
+ * manpage specific
+ *
+ * */
+
+body.manpage h1 {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
+ border-top: 2px solid silver;
+ border-bottom: 2px solid silver;
+}
+body.manpage h2 {
+ border-style: none;
+}
+body.manpage div.sectionbody {
+ margin-left: 3em;
+}
+
+@media print {
+ body.manpage div#toc { display: none; }
+}
+/* slidy.css
+
+ Copyright (c) 2005-2010 W3C (MIT, ERCIM, Keio), All Rights Reserved.
+ W3C liability, trademark, document use and software licensing
+ rules apply, see:
+
+ http://www.w3.org/Consortium/Legal/copyright-documents
+ http://www.w3.org/Consortium/Legal/copyright-software
+*/
+
+/*
+ SJR: 2010-09-29: Modified for AsciiDoc slidy backend.
+ Mostly just commented out stuff that is handled by AsciiDoc's CSS files.
+*/
+
+body
+{
+ margin: 0 0 0 0;
+ padding: 0 0 0 0;
+ width: 100%;
+ height: 100%;
+ color: black;
+ background-color: white;
+/*
+ font-family: "Gill Sans MT", "Gill Sans", GillSans, sans-serif;
+*/
+ font-size: 14pt;
+}
+
+div.toolbar {
+ position: fixed; z-index: 200;
+ top: auto; bottom: 0; left: 0; right: 0;
+ height: 1.2em; text-align: right;
+ padding-left: 1em;
+ padding-right: 1em;
+ font-size: 60%;
+ color: red;
+ background-color: rgb(240,240,240);
+ border-top: solid 1px rgb(180,180,180);
+}
+
+div.toolbar span.copyright {
+ color: black;
+ margin-left: 0.5em;
+}
+
+div.initial_prompt {
+ position: absolute;
+ z-index: 1000;
+ bottom: 1.2em;
+ width: 90%;
+ background-color: rgb(200,200,200);
+ opacity: 0.35;
+ background-color: rgb(200,200,200, 0.35);
+ cursor: pointer;
+}
+
+div.initial_prompt p.help {
+ text-align: center;
+}
+
+div.initial_prompt p.close {
+ text-align: right;
+ font-style: italic;
+}
+
+div.slidy_toc {
+ position: absolute;
+ z-index: 300;
+ width: 60%;
+ max-width: 30em;
+ height: 30em;
+ overflow: auto;
+ top: auto;
+ right: auto;
+ left: 4em;
+ bottom: 4em;
+ padding: 1em;
+ background: rgb(240,240,240);
+ border-style: solid;
+ border-width: 2px;
+ font-size: 60%;
+}
+
+div.slidy_toc .toc_heading {
+ text-align: center;
+ width: 100%;
+ margin: 0;
+ margin-bottom: 1em;
+ border-bottom-style: solid;
+ border-bottom-color: rgb(180,180,180);
+ border-bottom-width: 1px;
+}
+
+div.slide {
+ z-index: 20;
+ margin: 0 0 0 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ padding-left: 20px;
+ padding-right: 20px;
+ border-width: 0;
+ clear: both;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ line-height: 120%;
+ background-color: transparent;
+}
+
+div.background {
+ display: none;
+}
+
+div.handout {
+ margin-left: 20px;
+ margin-right: 20px;
+}
+
+div.slide.titlepage {
+ text-align: center;
+}
+
+div.slide.titlepage.h1 {
+ padding-top: 10%;
+}
+
+div.slide h1 {
+ padding-left: 0;
+ padding-right: 20pt;
+ padding-top: 4pt;
+ padding-bottom: 4pt;
+ margin-top: 0;
+ margin-left: 0;
+ margin-right: 60pt;
+ margin-bottom: 0.5em;
+ display: block;
+ font-size: 160%;
+ line-height: 1.2em;
+ background: transparent;
+}
+
+div.toc {
+ position: absolute;
+ top: auto;
+ bottom: 4em;
+ left: 4em;
+ right: auto;
+ width: 60%;
+ max-width: 30em;
+ height: 30em;
+ border: solid thin black;
+ padding: 1em;
+ background: rgb(240,240,240);
+ color: black;
+ z-index: 300;
+ overflow: auto;
+ display: block;
+ visibility: visible;
+}
+
+div.toc-heading {
+ width: 100%;
+ border-bottom: solid 1px rgb(180,180,180);
+ margin-bottom: 1em;
+ text-align: center;
+}
+
+/*
+pre {
+ font-size: 80%;
+ font-weight: bold;
+ line-height: 120%;
+ padding-top: 0.2em;
+ padding-bottom: 0.2em;
+ padding-left: 1em;
+ padding-right: 1em;
+ border-style: solid;
+ border-left-width: 1em;
+ border-top-width: thin;
+ border-right-width: thin;
+ border-bottom-width: thin;
+ border-color: #95ABD0;
+ color: #00428C;
+ background-color: #E4E5E7;
+}
+*/
+
+/*
+li pre { margin-left: 0; }
+
+blockquote { font-style: italic }
+
+img { background-color: transparent }
+
+p.copyright { font-size: smaller }
+*/
+
+.center { text-align: center }
+.footnote { font-size: smaller; margin-left: 2em; }
+
+/*
+a img { border-width: 0; border-style: none }
+*/
+
+a:visited { color: navy }
+a:link { color: navy }
+a:hover { color: red; text-decoration: underline }
+a:active { color: red; text-decoration: underline }
+
+a {text-decoration: none}
+.navbar a:link {color: white}
+.navbar a:visited {color: yellow}
+.navbar a:active {color: red}
+.navbar a:hover {color: red}
+
+/*
+ul { list-style-type: square; }
+ul ul { list-style-type: disc; }
+ul ul ul { list-style-type: circle; }
+ul ul ul ul { list-style-type: disc; }
+li { margin-left: 0.5em; margin-top: 0.5em; }
+li li { font-size: 85%; font-style: italic }
+li li li { font-size: 85%; font-style: normal }
+*/
+
+div dt
+{
+ margin-left: 0;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+ font-weight: bold;
+}
+div dd
+{
+ margin-left: 2em;
+ margin-bottom: 0.5em;
+}
+
+
+/*
+p,pre,ul,ol,blockquote,h2,h3,h4,h5,h6,dl,table {
+ margin-left: 1em;
+ margin-right: 1em;
+}
+*/
+
+p.subhead { font-weight: bold; margin-top: 2em; }
+
+.smaller { font-size: smaller }
+.bigger { font-size: 130% }
+
+/*
+td,th { padding: 0.2em }
+*/
+
+ul {
+ margin: 0.5em 1.5em 0.5em 1.5em;
+ padding: 0;
+}
+
+ol {
+ margin: 0.5em 1.5em 0.5em 1.5em;
+ padding: 0;
+}
+
+ul { list-style-type: square; }
+ul ul { list-style-type: disc; }
+ul ul ul { list-style-type: circle; }
+ul ul ul ul { list-style-type: disc; }
+
+/*
+ul li {
+ list-style: square;
+ margin: 0.1em 0em 0.6em 0;
+ padding: 0 0 0 0;
+ line-height: 140%;
+}
+
+ol li {
+ margin: 0.1em 0em 0.6em 1.5em;
+ padding: 0 0 0 0px;
+ line-height: 140%;
+ list-style-type: decimal;
+}
+
+li ul li {
+ font-size: 85%;
+ font-style: italic;
+ list-style-type: disc;
+ background: transparent;
+ padding: 0 0 0 0;
+}
+li li ul li {
+ font-size: 85%;
+ font-style: normal;
+ list-style-type: circle;
+ background: transparent;
+ padding: 0 0 0 0;
+}
+li li li ul li {
+ list-style-type: disc;
+ background: transparent;
+ padding: 0 0 0 0;
+}
+
+li ol li {
+ list-style-type: decimal;
+}
+
+
+li li ol li {
+ list-style-type: decimal;
+}
+*/
+
+/*
+ setting class="outline" on ol or ul makes it behave as an
+ ouline list where blocklevel content in li elements is
+ hidden by default and can be expanded or collapsed with
+ mouse click. Set class="expand" on li to override default
+*/
+
+ol.outline li:hover { cursor: pointer }
+ol.outline li.nofold:hover { cursor: default }
+
+ul.outline li:hover { cursor: pointer }
+ul.outline li.nofold:hover { cursor: default }
+
+ol.outline { list-style:decimal; }
+ol.outline ol { list-style-type:lower-alpha }
+
+ol.outline li.nofold {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/nofold-dim.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.unfolded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold-dim.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.folded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold-dim.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.unfolded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.folded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold.gif) no-repeat 0px 0.5em;
+}
+
+ul.outline li.nofold {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/nofold-dim.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.unfolded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold-dim.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.folded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold-dim.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.unfolded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.folded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold.gif) no-repeat 0px 0.5em;
+}
+
+/* for slides with class "title" in table of contents */
+a.titleslide { font-weight: bold; font-style: italic }
+
+/*
+ hide images for work around for save as bug
+ where browsers fail to save images used by CSS
+*/
+img.hidden { display: none; visibility: hidden }
+div.initial_prompt { display: none; visibility: hidden }
+
+ div.slide {
+ visibility: visible;
+ position: inherit;
+ }
+ div.handout {
+ border-top-style: solid;
+ border-top-width: thin;
+ border-top-color: black;
+ }
+
+@media screen {
+ .hidden { display: none; visibility: visible }
+
+ div.slide.hidden { display: block; visibility: visible }
+ div.handout.hidden { display: block; visibility: visible }
+ div.background { display: none; visibility: hidden }
+ body.single_slide div.initial_prompt { display: block; visibility: visible }
+ body.single_slide div.background { display: block; visibility: visible }
+ body.single_slide div.background.hidden { display: none; visibility: hidden }
+ body.single_slide .invisible { visibility: hidden }
+ body.single_slide .hidden { display: none; visibility: hidden }
+ body.single_slide div.slide { position: absolute }
+ body.single_slide div.handout { display: none; visibility: hidden }
+}
+
+@media print {
+ .hidden { display: block; visibility: visible }
+
+/*
+ div.slide pre { font-size: 60%; padding-left: 0.5em; }
+*/
+ div.toolbar { display: none; visibility: hidden; }
+ div.slidy_toc { display: none; visibility: hidden; }
+ div.background { display: none; visibility: hidden; }
+ div.slide { page-break-before: always }
+ /* :first-child isn't reliable for print media */
+ div.slide.first-slide { page-break-before: avoid }
+}
+
+
+/* SJR: AsciiDoc slidy backend tweaks */
+
+ol, ul {
+ margin: 0.8em 1.5em 0.8em 1.8em;
+}
+li > ul, li > ol {
+ margin-top: 0.5em;
+}
+
+.outline > li.folded,
+.outline > li.unfolded {
+ color: #527bbd;
+}
+ul > li{ color: #aaa; }
+ul > li > *, ol > li > * { color: black; }
+
+li {
+ margin-top: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+
+</style>
+<script type="text/javascript">
+/*<![CDATA[*/
+/* slidy.js
+
+ Copyright (c) 2005-2010 W3C (MIT, ERCIM, Keio), All Rights Reserved.
+ W3C liability, trademark, document use and software licensing
+ rules apply, see:
+
+ http://www.w3.org/Consortium/Legal/copyright-documents
+ http://www.w3.org/Consortium/Legal/copyright-software
+*/
+
+// the slidy object implementation
+var w3c_slidy = {
+ // classify which kind of browser we're running under
+ ns_pos: (typeof window.pageYOffset!='undefined'),
+ khtml: ((navigator.userAgent).indexOf("KHTML") >= 0 ? true : false),
+ opera: ((navigator.userAgent).indexOf("Opera") >= 0 ? true : false),
+ ipad: ((navigator.userAgent).indexOf("iPad") >= 0 ? true : false),
+ iphone: ((navigator.userAgent).indexOf("iPhone") >= 0 ? true : false),
+ ie: (typeof document.all != "undefined" && !this.opera),
+ ie6: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 6") != -1),
+ ie7: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 7") != -1),
+ ie8: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 8") != -1),
+ ie9: (!this.ns_pos && navigator.userAgent.indexOf("MSIE 9") != -1),
+ keyboardless: (this.ipad || this.iphone),
+
+ // are we running as XHTML? (doesn't work on Opera)
+ is_xhtml: /xml/.test(document.contentType),
+
+ slide_number: 0, // integer slide count: 0, 1, 2, ...
+ slide_number_element: null, // element containing slide number
+ slides: [], // set to array of slide div's
+ notes: [], // set to array of handout div's
+ backgrounds: [], // set to array of background div's
+ toolbar: null, // element containing toolbar
+ title: null, // document title
+ last_shown: null, // last incrementally shown item
+ eos: null, // span element for end of slide indicator
+ toc: null, // table of contents
+ outline: null, // outline element with the focus
+ selected_text_len: 0, // length of drag selection on document
+ view_all: 0, // 1 to view all slides + handouts
+ want_toolbar: true, // user preference to show/hide toolbar
+ mouse_click_enabled: true, // enables left click for next slide
+ scroll_hack: 0, // IE work around for position: fixed
+ disable_slide_click: false, // used by clicked anchors
+
+ lang: "en", // updated to language specified by html file
+
+ help_anchor: null, // used for keyboard focus hack in showToolbar()
+ help_page: "http://www.w3.org/Talks/Tools/Slidy2/help/help.html",
+ help_text: "Navigate with mouse click, space bar, Cursor Left/Right, " +
+ "or Pg Up and Pg Dn. Use S and B to change font size.",
+
+ size_index: 0,
+ size_adjustment: 0,
+ sizes: new Array("10pt", "12pt", "14pt", "16pt", "18pt", "20pt",
+ "22pt", "24pt", "26pt", "28pt", "30pt", "32pt"),
+
+ // needed for efficient resizing
+ last_width: 0,
+ last_height: 0,
+
+
+ // Needed for cross browser support for relative width/height on
+ // object elements. The work around is to save width/height attributes
+ // and then to recompute absolute width/height dimensions on resizing
+ objects: [],
+
+ // attach initialiation event handlers
+ set_up: function () {
+ var init = function() { w3c_slidy.init(); };
+ if (typeof window.addEventListener != "undefined")
+ window.addEventListener("load", init, false);
+ else
+ window.attachEvent("onload", init);
+ },
+
+ hide_slides: function () {
+ if (document.body && !w3c_slidy.initialized)
+ document.body.style.visibility = "hidden";
+ else
+ setTimeout(w3c_slidy.hide_slides, 50);
+ },
+
+ // hack to persuade IE to compute correct document height
+ // as needed for simulating fixed positioning of toolbar
+ ie_hack: function () {
+ window.resizeBy(0,-1);
+ window.resizeBy(0, 1);
+ },
+
+ init: function () {
+ //alert("slidy starting test 10");
+ document.body.style.visibility = "visible";
+ w3c_slidy_i18n.init();
+ this.add_toolbar();
+ this.wrap_implicit_slides();
+ this.collect_slides();
+ this.collect_notes();
+ this.collect_backgrounds();
+ this.objects = document.body.getElementsByTagName("object");
+ this.patch_anchors();
+ this.slide_number = this.find_slide_number(location.href);
+ window.offscreenbuffering = true;
+ this.size_adjustment = this.find_size_adjust();
+ this.time_left = this.find_duration();
+ this.hide_image_toolbar(); // suppress IE image toolbar popup
+ this.init_outliner(); // activate fold/unfold support
+ this.title = document.title;
+
+ // work around for opera bug
+ this.is_xhtml = (document.body.tagName == "BODY" ? false : true);
+
+ if (this.slides.length > 0)
+ {
+ var slide = this.slides[this.slide_number];
+
+ if (this.slide_number > 0)
+ {
+ this.set_visibility_all_incremental("visible");
+ this.last_shown = this.previous_incremental_item(null);
+ this.set_eos_status(true);
+ }
+ else
+ {
+ this.last_shown = null;
+ this.set_visibility_all_incremental("hidden");
+ this.set_eos_status(!this.next_incremental_item(this.last_shown));
+ }
+
+ this.set_location();
+ this.add_class(this.slides[0], "first-slide");
+ w3c_slidy.show_slide(slide);
+ }
+
+ this.toc = this.table_of_contents();
+
+ this.add_initial_prompt();
+
+ // bind event handlers without interfering with custom page scripts
+ // Tap events behave too weirdly to support clicks reliably on
+ // iPhone and iPad, so exclude these from click handler
+
+ if (!this.keyboardless)
+ this.add_listener(document.body, "click", this.mouse_button_click);
+
+ this.add_listener(document, "keydown", this.key_down);
+ this.add_listener(document, "keypress", this.key_press);
+ this.add_listener(window, "resize", this.resized);
+ this.add_listener(window, "scroll", this.scrolled);
+ this.add_listener(window, "unload", this.unloaded);
+
+ if (!document.body.onclick)
+ document.body.onclick = function () { };
+
+ this.single_slide_view();
+
+ //this.set_location();
+
+ this.resized();
+
+ if (this.ie7)
+ setTimeout(w3c_slidy.ie_hack, 100);
+
+ this.show_toolbar();
+
+ // for back button detection
+ setInterval(function () { w3c_slidy.check_location(); }, 200);
+ w3c_slidy.initialized = true;
+ },
+
+ // create div element with links to each slide
+ table_of_contents: function () {
+ var toc = this.create_element("div");
+ this.add_class(toc, "slidy_toc hidden");
+ //toc.setAttribute("tabindex", "0");
+
+ var heading = this.create_element("div");
+ this.add_class(heading, "toc-heading");
+ heading.innerHTML = "Table of Contents".localize();
+
+ toc.appendChild(heading);
+ var previous = null;
+
+ for (var i = 0; i < this.slides.length; ++i)
+ {
+ var title = this.has_class(this.slides[i], "title");
+ var num = document.createTextNode((i + 1) + ". ");
+
+ toc.appendChild(num);
+
+ var a = this.create_element("a");
+ a.setAttribute("href", "#(" + (i+1) + ")");
+
+ if (title)
+ this.add_class(a, "titleslide");
+
+ var name = document.createTextNode(this.slide_name(i));
+ a.appendChild(name);
+ a.onclick = w3c_slidy.toc_click;
+ a.onkeydown = w3c_slidy.toc_keydown;
+ a.previous = previous;
+
+ if (previous)
+ previous.next = a;
+
+ toc.appendChild(a);
+
+ if (i == 0)
+ toc.first = a;
+
+ if (i < this.slides.length - 1)
+ {
+ var br = this.create_element("br");
+ toc.appendChild(br);
+ }
+
+ previous = a;
+ }
+
+ toc.focus = function () {
+ if (this.first)
+ this.first.focus();
+ }
+
+ toc.onmouseup = w3c_slidy.mouse_button_up;
+
+ toc.onclick = function (e) {
+ e||(e=window.event);
+
+ if (w3c_slidy.selected_text_len <= 0)
+ w3c_slidy.hide_table_of_contents();
+
+ w3c_slidy.stop_propagation(e);
+
+ if (e.cancel != undefined)
+ e.cancel = true;
+
+ if (e.returnValue != undefined)
+ e.returnValue = false;
+
+ return false;
+ };
+
+ document.body.insertBefore(toc, document.body.firstChild);
+ return toc;
+ },
+
+ is_shown_toc: function () {
+ return !w3c_slidy.has_class(w3c_slidy.toc, "hidden");
+ },
+
+ show_table_of_contents: function () {
+ w3c_slidy.remove_class(w3c_slidy.toc, "hidden");
+ var toc = w3c_slidy.toc;
+ toc.focus();
+
+ if (w3c_slidy.ie7 && w3c_slidy.slide_number == 0)
+ setTimeout(w3c_slidy.ie_hack, 100);
+ },
+
+ hide_table_of_contents: function () {
+ w3c_slidy.add_class(w3c_slidy.toc, "hidden");
+
+ if (!w3c_slidy.opera)
+ w3c_slidy.help_anchor.focus();
+ },
+
+ toggle_table_of_contents: function () {
+ if (w3c_slidy.is_shown_toc())
+ w3c_slidy.hide_table_of_contents();
+ else
+ w3c_slidy.show_table_of_contents();
+ },
+
+ // called on clicking toc entry
+ toc_click: function (e) {
+ if (!e)
+ e = window.event;
+
+ var target = w3c_slidy.get_target(e);
+
+ if (target && target.nodeType == 1)
+ {
+ var uri = target.getAttribute("href");
+
+ if (uri)
+ {
+ //alert("going to " + uri);
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.slide_number = w3c_slidy.find_slide_number(uri);
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_location();
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+ w3c_slidy.show_slide(slide);
+ //target.focus();
+
+ try
+ {
+ if (!w3c_slidy.opera)
+ w3c_slidy.help_anchor.focus();
+ }
+ catch (e)
+ {
+ }
+ }
+ }
+
+ w3c_slidy.hide_table_of_contents(e);
+ if (w3c_slidy.ie7) w3c_slidy.ie_hack();
+ w3c_slidy.stop_propagation(e);
+ return w3c_slidy.cancel(e);
+ },
+
+ // called onkeydown for toc entry
+ toc_keydown: function (event) {
+ var key;
+
+ if (!event)
+ var event = window.event;
+
+ // kludge around NS/IE differences
+ if (window.event)
+ key = window.event.keyCode;
+ else if (event.which)
+ key = event.which;
+ else
+ return true; // Yikes! unknown browser
+
+ // ignore event if key value is zero
+ // as for alt on Opera and Konqueror
+ if (!key)
+ return true;
+
+ // check for concurrent control/command/alt key
+ // but are these only present on mouse events?
+
+ if (event.ctrlKey || event.altKey)
+ return true;
+
+ if (key == 13)
+ {
+ var uri = this.getAttribute("href");
+
+ if (uri)
+ {
+ //alert("going to " + uri);
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.slide_number = w3c_slidy.find_slide_number(uri);
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_location();
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+ w3c_slidy.show_slide(slide);
+ //target.focus();
+
+ try
+ {
+ if (!w3c_slidy.opera)
+ w3c_slidy.help_anchor.focus();
+ }
+ catch (e)
+ {
+ }
+ }
+
+ w3c_slidy.hide_table_of_contents();
+
+ if (self.ie7)
+ w3c_slidy.ie_hack();
+
+ return w3c_slidy.cancel(event);
+ }
+
+ if (key == 40 && this.next)
+ {
+ this.next.focus();
+ return w3c_slidy.cancel(event);
+ }
+
+ if (key == 38 && this.previous)
+ {
+ this.previous.focus();
+ return w3c_slidy.cancel(event);
+ }
+
+ return true;
+ },
+
+
+ // ### OBSOLETE ###
+ before_print: function () {
+ this.show_all_slides();
+ this.hide_toolbar();
+ alert("before print");
+ },
+
+ // ### OBSOLETE ###
+ after_print: function () {
+ if (!this.view_all)
+ {
+ this.single_slide_view();
+ this.show_toolbar();
+ }
+ alert("after print");
+ },
+
+ // ### OBSOLETE ###
+ print_slides: function () {
+ this.before_print();
+ window.print();
+ this.after_print();
+ },
+
+ // ### OBSOLETE ?? ###
+ toggle_view: function () {
+ if (this.view_all)
+ {
+ this.single_slide_view();
+ this.show_toolbar();
+ this.view_all = 0;
+ }
+ else
+ {
+ this.show_all_slides();
+ this.hide_toolbar();
+ this.view_all = 1;
+ }
+ },
+
+ // prepare for printing ### OBSOLETE ###
+ show_all_slides: function () {
+ this.remove_class(document.body, "single_slide");
+ this.set_visibility_all_incremental("visible");
+ },
+
+ // restore after printing ### OBSOLETE ###
+ single_slide_view: function () {
+ this.add_class(document.body, "single_slide");
+ this.set_visibility_all_incremental("visible");
+ this.last_shown = this.previous_incremental_item(null);
+ },
+
+ // suppress IE's image toolbar pop up
+ hide_image_toolbar: function () {
+ if (!this.ns_pos)
+ {
+ var images = document.getElementsByTagName("IMG");
+
+ for (var i = 0; i < images.length; ++i)
+ images[i].setAttribute("galleryimg", "no");
+ }
+ },
+
+ unloaded: function (e) {
+ //alert("unloaded");
+ },
+
+ // Safari and Konqueror don't yet support getComputedStyle()
+ // and they always reload page when location.href is updated
+ is_KHTML: function () {
+ var agent = navigator.userAgent;
+ return (agent.indexOf("KHTML") >= 0 ? true : false);
+ },
+
+ // find slide name from first h1 element
+ // default to document title + slide number
+ slide_name: function (index) {
+ var name = null;
+ var slide = this.slides[index];
+
+ var heading = this.find_heading(slide);
+
+ if (heading)
+ name = this.extract_text(heading);
+
+ if (!name)
+ name = this.title + "(" + (index + 1) + ")";
+
+ name.replace(/\&/g, "&amp;");
+ name.replace(/\</g, "&lt;");
+ name.replace(/\>/g, "&gt;");
+
+ return name;
+ },
+
+ // find first h1 element in DOM tree
+ find_heading: function (node) {
+ if (!node || node.nodeType != 1)
+ return null;
+
+ if (node.nodeName == "H1" || node.nodeName == "h1")
+ return node;
+
+ var child = node.firstChild;
+
+ while (child)
+ {
+ node = this.find_heading(child);
+
+ if (node)
+ return node;
+
+ child = child.nextSibling;
+ }
+
+ return null;
+ },
+
+ // recursively extract text from DOM tree
+ extract_text: function (node) {
+ if (!node)
+ return "";
+
+ // text nodes
+ if (node.nodeType == 3)
+ return node.nodeValue;
+
+ // elements
+ if (node.nodeType == 1)
+ {
+ node = node.firstChild;
+ var text = "";
+
+ while (node)
+ {
+ text = text + this.extract_text(node);
+ node = node.nextSibling;
+ }
+
+ return text;
+ }
+
+ return "";
+ },
+
+ // find copyright text from meta element
+ find_copyright: function () {
+ var name, content;
+ var meta = document.getElementsByTagName("meta");
+
+ for (var i = 0; i < meta.length; ++i)
+ {
+ name = meta[i].getAttribute("name");
+ content = meta[i].getAttribute("content");
+
+ if (name == "copyright")
+ return content;
+ }
+
+ return null;
+ },
+
+ find_size_adjust: function () {
+ var name, content, offset;
+ var meta = document.getElementsByTagName("meta");
+
+ for (var i = 0; i < meta.length; ++i)
+ {
+ name = meta[i].getAttribute("name");
+ content = meta[i].getAttribute("content");
+
+ if (name == "font-size-adjustment")
+ return 1 * content;
+ }
+
+ return 1;
+ },
+
+ // <meta name="duration" content="20" /> for 20 minutes
+ find_duration: function () {
+ var name, content, offset;
+ var meta = document.getElementsByTagName("meta");
+
+ for (var i = 0; i < meta.length; ++i)
+ {
+ name = meta[i].getAttribute("name");
+ content = meta[i].getAttribute("content");
+
+ if (name == "duration")
+ return 60000 * content;
+ }
+
+ return null;
+ },
+
+ replace_by_non_breaking_space: function (str) {
+ for (var i = 0; i < str.length; ++i)
+ str[i] = 160;
+ },
+
+ // ### CHECK ME ### is use of "li" okay for text/html?
+ // for XHTML do we also need to specify namespace?
+ init_outliner: function () {
+ var items = document.getElementsByTagName("li");
+
+ for (var i = 0; i < items.length; ++i)
+ {
+ var target = items[i];
+
+ if (!this.has_class(target.parentNode, "outline"))
+ continue;
+
+ target.onclick = this.outline_click;
+/* ### more work needed for IE6
+ if (!this.ns_pos)
+ {
+ target.onmouseover = this.hover_outline;
+ target.onmouseout = this.unhover_outline;
+ }
+*/
+ if (this.foldable(target))
+ {
+ target.foldable = true;
+ target.onfocus = function () {w3c_slidy.outline = this;};
+ target.onblur = function () {w3c_slidy.outline = null;};
+
+ if (!target.getAttribute("tabindex"))
+ target.setAttribute("tabindex", "0");
+
+ if (this.has_class(target, "expand"))
+ this.unfold(target);
+ else
+ this.fold(target);
+ }
+ else
+ {
+ this.add_class(target, "nofold");
+ target.visible = true;
+ target.foldable = false;
+ }
+ }
+ },
+
+ foldable: function (item) {
+ if (!item || item.nodeType != 1)
+ return false;
+
+ var node = item.firstChild;
+
+ while (node)
+ {
+ if (node.nodeType == 1 && this.is_block(node))
+ return true;
+
+ node = node.nextSibling;
+ }
+
+ return false;
+ },
+
+ // ### CHECK ME ### switch to add/remove "hidden" class
+ fold: function (item) {
+ if (item)
+ {
+ this.remove_class(item, "unfolded");
+ this.add_class(item, "folded");
+ }
+
+ var node = item ? item.firstChild : null;
+
+ while (node)
+ {
+ if (node.nodeType == 1 && this.is_block(node)) // element
+ {
+ w3c_slidy.add_class(node, "hidden");
+ }
+
+ node = node.nextSibling;
+ }
+
+ item.visible = false;
+ },
+
+ // ### CHECK ME ### switch to add/remove "hidden" class
+ unfold: function (item) {
+ if (item)
+ {
+ this.add_class(item, "unfolded");
+ this.remove_class(item, "folded");
+ }
+
+ var node = item ? item.firstChild : null;
+
+ while (node)
+ {
+ if (node.nodeType == 1 && this.is_block(node)) // element
+ {
+ w3c_slidy.remove_class(node, "hidden");
+ }
+
+ node = node.nextSibling;
+ }
+
+ item.visible = true;
+ },
+
+ outline_click: function (e) {
+ if (!e)
+ e = window.event;
+
+ var rightclick = false;
+ var target = w3c_slidy.get_target(e);
+
+ while (target && target.visible == undefined)
+ target = target.parentNode;
+
+ if (!target)
+ return true;
+
+ if (e.which)
+ rightclick = (e.which == 3);
+ else if (e.button)
+ rightclick = (e.button == 2);
+
+ if (!rightclick && target.visible != undefined)
+ {
+ if (target.foldable)
+ {
+ if (target.visible)
+ w3c_slidy.fold(target);
+ else
+ w3c_slidy.unfold(target);
+ }
+
+ w3c_slidy.stop_propagation(e);
+ e.cancel = true;
+ e.returnValue = false;
+ }
+
+ return false;
+ },
+
+ add_initial_prompt: function () {
+ var prompt = this.create_element("div");
+ prompt.setAttribute("class", "initial_prompt");
+
+ var p1 = this.create_element("p");
+ prompt.appendChild(p1);
+ p1.setAttribute("class", "help");
+
+ if (this.keyboardless)
+ p1.innerHTML = "Tap footer to move to next slide";
+ else
+ p1.innerHTML = "Space or Right Arrow to move to next " +
+ "slide, click help below for more details";
+
+ this.add_listener(prompt, "click", function (e) {
+ document.body.removeChild(prompt);
+ w3c_slidy.stop_propagation(e);
+
+ if (e.cancel != undefined)
+ e.cancel = true;
+
+ if (e.returnValue != undefined)
+ e.returnValue = false;
+
+ return false;
+ });
+
+ document.body.appendChild(prompt);
+ this.initial_prompt = prompt;
+ setTimeout(function() {document.body.removeChild(prompt);}, 5000);
+ },
+
+ add_toolbar: function () {
+ var counter, page;
+
+ this.toolbar = this.create_element("div");
+ this.toolbar.setAttribute("class", "toolbar");
+
+ // a reasonably behaved browser
+ if (this.ns_pos || !this.ie6)
+ {
+ var right = this.create_element("div");
+ right.setAttribute("style", "float: right; text-align: right");
+
+ counter = this.create_element("span")
+ counter.innerHTML = "slide".localize() + " n/m";
+ right.appendChild(counter);
+ this.toolbar.appendChild(right);
+
+ var left = this.create_element("div");
+ left.setAttribute("style", "text-align: left");
+
+ // global end of slide indicator
+ this.eos = this.create_element("span");
+ this.eos.innerHTML = "* ";
+ left.appendChild(this.eos);
+
+ var help = this.create_element("a");
+ help.setAttribute("href", this.help_page);
+ help.setAttribute("title", this.help_text.localize());
+ help.innerHTML = "help?".localize();
+ left.appendChild(help);
+ this.help_anchor = help; // save for focus hack
+
+ var gap1 = document.createTextNode(" ");
+ left.appendChild(gap1);
+
+ var contents = this.create_element("a");
+ contents.setAttribute("href", "javascript:w3c_slidy.toggle_table_of_contents()");
+ contents.setAttribute("title", "table of contents".localize());
+ contents.innerHTML = "contents?".localize();
+ left.appendChild(contents);
+
+ var gap2 = document.createTextNode(" ");
+ left.appendChild(gap2);
+
+ var copyright = this.find_copyright();
+
+ if (copyright)
+ {
+ var span = this.create_element("span");
+ span.className = "copyright";
+ span.innerHTML = copyright;
+ left.appendChild(span);
+ }
+
+ this.toolbar.setAttribute("tabindex", "0");
+ this.toolbar.appendChild(left);
+ }
+ else // IE6 so need to work around its poor CSS support
+ {
+ this.toolbar.style.position = (this.ie7 ? "fixed" : "absolute");
+ this.toolbar.style.zIndex = "200";
+ this.toolbar.style.width = "99.9%";
+ this.toolbar.style.height = "1.2em";
+ this.toolbar.style.top = "auto";
+ this.toolbar.style.bottom = "0";
+ this.toolbar.style.left = "0";
+ this.toolbar.style.right = "0";
+ this.toolbar.style.textAlign = "left";
+ this.toolbar.style.fontSize = "60%";
+ this.toolbar.style.color = "red";
+ this.toolbar.borderWidth = 0;
+ this.toolbar.className = "toolbar";
+ this.toolbar.style.background = "rgb(240,240,240)";
+
+ // would like to have help text left aligned
+ // and page counter right aligned, floating
+ // div's don't work, so instead use nested
+ // absolutely positioned div's.
+
+ var sp = this.create_element("span");
+ sp.innerHTML = "&nbsp;&nbsp;*&nbsp;";
+ this.toolbar.appendChild(sp);
+ this.eos = sp; // end of slide indicator
+
+ var help = this.create_element("a");
+ help.setAttribute("href", this.help_page);
+ help.setAttribute("title", this.help_text.localize());
+ help.innerHTML = "help?".localize();
+ this.toolbar.appendChild(help);
+ this.help_anchor = help; // save for focus hack
+
+ var gap1 = document.createTextNode(" ");
+ this.toolbar.appendChild(gap1);
+
+ var contents = this.create_element("a");
+ contents.setAttribute("href", "javascript:toggleTableOfContents()");
+ contents.setAttribute("title", "table of contents".localize());
+ contents.innerHTML = "contents?".localize();
+ this.toolbar.appendChild(contents);
+
+ var gap2 = document.createTextNode(" ");
+ this.toolbar.appendChild(gap2);
+
+ var copyright = this.find_copyright();
+
+ if (copyright)
+ {
+ var span = this.create_element("span");
+ span.innerHTML = copyright;
+ span.style.color = "black";
+ span.style.marginLeft = "0.5em";
+ this.toolbar.appendChild(span);
+ }
+
+ counter = this.create_element("div")
+ counter.style.position = "absolute";
+ counter.style.width = "auto"; //"20%";
+ counter.style.height = "1.2em";
+ counter.style.top = "auto";
+ counter.style.bottom = 0;
+ counter.style.right = "0";
+ counter.style.textAlign = "right";
+ counter.style.color = "red";
+ counter.style.background = "rgb(240,240,240)";
+
+ counter.innerHTML = "slide".localize() + " n/m";
+ this.toolbar.appendChild(counter);
+ }
+
+ // ensure that click isn't passed through to the page
+ this.toolbar.onclick =
+ function (e) {
+ if (!e)
+ e = window.event;
+
+ var target = e.target;
+
+ if (!target && e.srcElement)
+ target = e.srcElement;
+
+ // work around Safari bug
+ if (target && target.nodeType == 3)
+ target = target.parentNode;
+
+ w3c_slidy.stop_propagation(e);
+
+ if (target && target.nodeName.toLowerCase() != "a")
+ w3c_slidy.mouse_button_click(e);
+ };
+
+ this.slide_number_element = counter;
+ this.set_eos_status(false);
+ document.body.appendChild(this.toolbar);
+ },
+
+ // wysiwyg editors make it hard to use div elements
+ // e.g. amaya loses the div when you copy and paste
+ // this function wraps div elements around implicit
+ // slides which start with an h1 element and continue
+ // up to the next heading or div element
+ wrap_implicit_slides: function () {
+ var i, heading, node, next, div;
+ var headings = document.getElementsByTagName("h1");
+
+ if (!headings)
+ return;
+
+ for (i = 0; i < headings.length; ++i)
+ {
+ heading = headings[i];
+
+ if (heading.parentNode != document.body)
+ continue;
+
+ node = heading.nextSibling;
+
+ div = document.createElement("div");
+ this.add_class(div, "slide");
+ document.body.replaceChild(div, heading);
+ div.appendChild(heading);
+
+ while (node)
+ {
+ if (node.nodeType == 1 && // an element
+ (node.nodeName == "H1" ||
+ node.nodeName == "h1" ||
+ node.nodeName == "DIV" ||
+ node.nodeName == "div"))
+ break;
+
+ next = node.nextSibling;
+ node = document.body.removeChild(node);
+ div.appendChild(node);
+ node = next;
+ }
+ }
+ },
+
+// return new array of all slides
+ collect_slides: function () {
+ var slides = new Array();
+ var divs = document.body.getElementsByTagName("div");
+
+ for (var i = 0; i < divs.length; ++i)
+ {
+ div = divs.item(i);
+
+ if (this.has_class(div, "slide"))
+ {
+ // add slide to collection
+ slides[slides.length] = div;
+
+ // hide each slide as it is found
+ this.add_class(div, "hidden");
+
+ // add dummy <br/> at end for scrolling hack
+ var node1 = document.createElement("br");
+ div.appendChild(node1);
+ var node2 = document.createElement("br");
+ div.appendChild(node2);
+ }
+ else if (this.has_class(div, "background"))
+ { // work around for Firefox SVG reload bug
+ // which otherwise replaces 1st SVG graphic with 2nd
+ div.style.display = "block";
+ }
+ }
+
+ this.slides = slides;
+ },
+
+ // return new array of all <div class="handout">
+ collect_notes: function () {
+ var notes = new Array();
+ var divs = document.body.getElementsByTagName("div");
+
+ for (var i = 0; i < divs.length; ++i)
+ {
+ div = divs.item(i);
+
+ if (this.has_class(div, "handout"))
+ {
+ // add note to collection
+ notes[notes.length] = div;
+
+ // and hide it
+ this.add_class(div, "hidden");
+ }
+ }
+
+ this.notes = notes;
+ },
+
+ // return new array of all <div class="background">
+ // including named backgrounds e.g. class="background titlepage"
+ collect_backgrounds: function () {
+ var backgrounds = new Array();
+ var divs = document.body.getElementsByTagName("div");
+
+ for (var i = 0; i < divs.length; ++i)
+ {
+ div = divs.item(i);
+
+ if (this.has_class(div, "background"))
+ {
+ // add background to collection
+ backgrounds[backgrounds.length] = div;
+
+ // and hide it
+ this.add_class(div, "hidden");
+ }
+ }
+
+ this.backgrounds = backgrounds;
+ },
+
+ // set click handlers on all anchors
+ patch_anchors: function () {
+ var self = w3c_slidy;
+ var handler = function (event) {
+ // compare this.href with location.href
+ // for link to another slide in this doc
+
+ if (self.page_address(this.href) == self.page_address(location.href))
+ {
+ // yes, so find new slide number
+ var newslidenum = self.find_slide_number(this.href);
+
+ if (newslidenum != self.slide_number)
+ {
+ var slide = self.slides[self.slide_number];
+ self.hide_slide(slide);
+ self.slide_number = newslidenum;
+ slide = self.slides[self.slide_number];
+ self.show_slide(slide);
+ self.set_location();
+ }
+ }
+ else if (this.target == null)
+ location.href = this.href;
+
+ this.blur();
+ self.disable_slide_click = true;
+ };
+
+ var anchors = document.body.getElementsByTagName("a");
+
+ for (var i = 0; i < anchors.length; ++i)
+ {
+ if (window.addEventListener)
+ anchors[i].addEventListener("click", handler, false);
+ else
+ anchors[i].attachEvent("onclick", handler);
+ }
+ },
+
+ // ### CHECK ME ### see which functions are invoked via setTimeout
+ // either directly or indirectly for use of w3c_slidy vs this
+ show_slide_number: function () {
+ var timer = w3c_slidy.get_timer();
+ w3c_slidy.slide_number_element.innerHTML = timer + "slide".localize() + " " +
+ (w3c_slidy.slide_number + 1) + "/" + w3c_slidy.slides.length;
+ },
+
+ // every 200mS check if the location has been changed as a
+ // result of the user activating the Back button/menu item
+ // doesn't work for Opera < 9.5
+ check_location: function () {
+ var hash = location.hash;
+
+ if (w3c_slidy.slide_number > 0 && (hash == "" || hash == "#"))
+ w3c_slidy.goto_slide(0);
+ else if (hash.length > 2 && hash != "#("+(w3c_slidy.slide_number+1)+")")
+ {
+ var num = parseInt(location.hash.substr(2));
+
+ if (!isNaN(num))
+ w3c_slidy.goto_slide(num-1);
+ }
+
+ if (w3c_slidy.time_left && w3c_slidy.slide_number > 0)
+ {
+ w3c_slidy.show_slide_number();
+
+ if (w3c_slidy.time_left > 0)
+ w3c_slidy.time_left -= 200;
+ }
+ },
+
+ get_timer: function () {
+ var timer = "";
+ if (w3c_slidy.time_left)
+ {
+ var mins, secs;
+ secs = Math.floor(w3c_slidy.time_left/1000);
+ mins = Math.floor(secs / 60);
+ secs = secs % 60;
+ timer = (mins ? mins+"m" : "") + secs + "s ";
+ }
+
+ return timer;
+ },
+
+ // this doesn't push location onto history stack for IE
+ // for which a hidden iframe hack is needed: load page into
+ // the iframe with script that set's parent's location.hash
+ // but that won't work for standalone use unless we can
+ // create the page dynamically via a javascript: URL
+ set_location: function () {
+ var uri = w3c_slidy.page_address(location.href);
+ var hash = "#(" + (w3c_slidy.slide_number+1) + ")";
+
+ if (w3c_slidy.slide_number >= 0)
+ uri = uri + hash;
+
+ if (w3c_slidy.ie && !w3c_slidy.ie8)
+ w3c_slidy.push_hash(hash);
+
+ if (uri != location.href) // && !khtml
+ location.href = uri;
+
+ if (this.khtml)
+ hash = "(" + (w3c_slidy.slide_number+1) + ")";
+
+ if (!this.ie && location.hash != hash && location.hash != "")
+ location.hash = hash;
+
+ document.title = w3c_slidy.title + " (" + (w3c_slidy.slide_number+1) + ")";
+ w3c_slidy.show_slide_number();
+ },
+
+ page_address: function (uri) {
+ var i = uri.indexOf("#");
+
+ if (i < 0)
+ i = uri.indexOf("%23");
+
+ // check if anchor is entire page
+
+ if (i < 0)
+ return uri; // yes
+
+ return uri.substr(0, i);
+ },
+
+ // only used for IE6 and IE7
+ on_frame_loaded: function (hash) {
+ location.hash = hash;
+ var uri = w3c_slidy.page_address(location.href);
+ location.href = uri + hash;
+ },
+
+ // history hack with thanks to Bertrand Le Roy
+ push_hash: function (hash) {
+ if (hash == "") hash = "#(1)";
+ window.location.hash = hash;
+
+ var doc = document.getElementById("historyFrame").contentWindow.document;
+ doc.open("javascript:'<html></html>'");
+ // PWL modified this string literal to break the close script tag
+ // which otherwise gets parsed when incorporated
+ doc.write("<html><head><script type=\"text/javascript\">window.parent.w3c_slidy.on_frame_loaded('"+
+ (hash) + "');</" + "script></head><body>hello mum</body></html>");
+ doc.close();
+ },
+
+ // find current slide based upon location
+ // first find target anchor and then look
+ // for associated div element enclosing it
+ // finally map that to slide number
+ find_slide_number: function (uri) {
+ // first get anchor from page location
+
+ var i = uri.indexOf("#");
+
+ // check if anchor is entire page
+ if (i < 0)
+ return 0; // yes
+
+ var anchor = unescape(uri.substr(i+1));
+
+ // now use anchor as XML ID to find target
+ var target = document.getElementById(anchor);
+
+ if (!target)
+ {
+ // does anchor look like "(2)" for slide 2 ??
+ // where first slide is (1)
+ var re = /\((\d)+\)/;
+
+ if (anchor.match(re))
+ {
+ var num = parseInt(anchor.substring(1, anchor.length-1));
+
+ if (num > this.slides.length)
+ num = 1;
+
+ if (--num < 0)
+ num = 0;
+
+ return num;
+ }
+
+ // accept [2] for backwards compatibility
+ re = /\[(\d)+\]/;
+
+ if (anchor.match(re))
+ {
+ var num = parseInt(anchor.substring(1, anchor.length-1));
+
+ if (num > this.slides.length)
+ num = 1;
+
+ if (--num < 0)
+ num = 0;
+
+ return num;
+ }
+
+ // oh dear unknown anchor
+ return 0;
+ }
+
+ // search for enclosing slide
+
+ while (true)
+ {
+ // browser coerces html elements to uppercase!
+ if (target.nodeName.toLowerCase() == "div" &&
+ this.has_class(target, "slide"))
+ {
+ // found the slide element
+ break;
+ }
+
+ // otherwise try parent element if any
+
+ target = target.parentNode;
+
+ if (!target)
+ {
+ return 0; // no luck!
+ }
+ };
+
+ for (i = 0; i < slides.length; ++i)
+ {
+ if (slides[i] == target)
+ return i; // success
+ }
+
+ // oh dear still no luck
+ return 0;
+ },
+
+ previous_slide: function (incremental) {
+ if (!w3c_slidy.view_all)
+ {
+ var slide;
+
+ if ((incremental || w3c_slidy.slide_number == 0) && w3c_slidy.last_shown != null)
+ {
+ w3c_slidy.last_shown = w3c_slidy.hide_previous_item(w3c_slidy.last_shown);
+ w3c_slidy.set_eos_status(false);
+ }
+ else if (w3c_slidy.slide_number > 0)
+ {
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+
+ w3c_slidy.slide_number = w3c_slidy.slide_number - 1;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.set_visibility_all_incremental("visible");
+ w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null);
+ w3c_slidy.set_eos_status(true);
+ w3c_slidy.show_slide(slide);
+ }
+
+ w3c_slidy.set_location();
+
+ if (!w3c_slidy.ns_pos)
+ w3c_slidy.refresh_toolbar(200);
+ }
+ },
+
+ next_slide: function (incremental) {
+ if (!w3c_slidy.view_all)
+ {
+ var slide, last = w3c_slidy.last_shown;
+
+ if (incremental || w3c_slidy.slide_number == w3c_slidy.slides.length - 1)
+ w3c_slidy.last_shown = w3c_slidy.reveal_next_item(w3c_slidy.last_shown);
+
+ if ((!incremental || w3c_slidy.last_shown == null) &&
+ w3c_slidy.slide_number < w3c_slidy.slides.length - 1)
+ {
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+
+ w3c_slidy.slide_number = w3c_slidy.slide_number + 1;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.show_slide(slide);
+ }
+ else if (!w3c_slidy.last_shown)
+ {
+ if (last && incremental)
+ w3c_slidy.last_shown = last;
+ }
+
+ w3c_slidy.set_location();
+
+ w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+
+ if (!w3c_slidy.ns_pos)
+ w3c_slidy.refresh_toolbar(200);
+ }
+ },
+
+ // to first slide with nothing revealed
+ // i.e. state at start of presentation
+ first_slide: function () {
+ if (!w3c_slidy.view_all)
+ {
+ var slide;
+
+ if (w3c_slidy.slide_number != 0)
+ {
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+
+ w3c_slidy.slide_number = 0;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.show_slide(slide);
+ }
+
+ w3c_slidy.set_eos_status(
+ !w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+ w3c_slidy.set_location();
+ }
+ },
+
+ // goto last slide with everything revealed
+ // i.e. state at end of presentation
+ last_slide: function () {
+ if (!w3c_slidy.view_all)
+ {
+ var slide;
+
+ w3c_slidy.last_shown = null; //revealNextItem(lastShown);
+
+ if (w3c_slidy.last_shown == null &&
+ w3c_slidy.slide_number < w3c_slidy.slides.length - 1)
+ {
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.slide_number = w3c_slidy.slides.length - 1;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.set_visibility_all_incremental("visible");
+ w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null);
+
+ w3c_slidy.show_slide(slide);
+ }
+ else
+ {
+ w3c_slidy.set_visibility_all_incremental("visible");
+ w3c_slidy.last_shown = w3c_slidy.previous_incremental_item(null);
+ }
+
+ w3c_slidy.set_eos_status(true);
+ w3c_slidy.set_location();
+ }
+ },
+
+
+ // ### check this and consider add/remove class
+ set_eos_status: function (state) {
+ if (this.eos)
+ this.eos.style.color = (state ? "rgb(240,240,240)" : "red");
+ },
+
+ // first slide is 0
+ goto_slide: function (num) {
+ //alert("going to slide " + (num+1));
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.slide_number = num;
+ slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.last_shown = null;
+ w3c_slidy.set_visibility_all_incremental("hidden");
+ w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));
+ document.title = w3c_slidy.title + " (" + (w3c_slidy.slide_number+1) + ")";
+ w3c_slidy.show_slide(slide);
+ w3c_slidy.show_slide_number();
+ },
+
+
+ show_slide: function (slide) {
+ this.sync_background(slide);
+ window.scrollTo(0,0);
+ this.remove_class(slide, "hidden");
+ },
+
+ hide_slide: function (slide) {
+ this.add_class(slide, "hidden");
+ },
+
+ // show just the backgrounds pertinent to this slide
+ // when slide background-color is transparent
+ // this should now work with rgba color values
+ sync_background: function (slide) {
+ var background;
+ var bgColor;
+
+ if (slide.currentStyle)
+ bgColor = slide.currentStyle["backgroundColor"];
+ else if (document.defaultView)
+ {
+ var styles = document.defaultView.getComputedStyle(slide,null);
+
+ if (styles)
+ bgColor = styles.getPropertyValue("background-color");
+ else // broken implementation probably due Safari or Konqueror
+ {
+ //alert("defective implementation of getComputedStyle()");
+ bgColor = "transparent";
+ }
+ }
+ else
+ bgColor == "transparent";
+
+ if (bgColor == "transparent" ||
+ bgColor.indexOf("rgba") >= 0 ||
+ bgColor.indexOf("opacity") >= 0)
+ {
+ var slideClass = this.get_class_list(slide);
+
+ for (var i = 0; i < this.backgrounds.length; i++)
+ {
+ background = this.backgrounds[i];
+
+ var bgClass = this.get_class_list(background);
+
+ if (this.matching_background(slideClass, bgClass))
+ this.remove_class(background, "hidden");
+ else
+ this.add_class(background, "hidden");
+ }
+ }
+ else // forcibly hide all backgrounds
+ this.hide_backgrounds();
+ },
+
+ hide_backgrounds: function () {
+ for (var i = 0; i < this.backgrounds.length; i++)
+ {
+ background = this.backgrounds[i];
+ this.add_class(background, "hidden");
+ }
+ },
+
+ // compare classes for slide and background
+ matching_background: function (slideClass, bgClass) {
+ var i, count, pattern, result;
+
+ // define pattern as regular expression
+ pattern = /\w+/g;
+
+ // check background class names
+ result = bgClass.match(pattern);
+
+ for (i = count = 0; i < result.length; i++)
+ {
+ if (result[i] == "hidden")
+ continue;
+
+ if (result[i] == "background")
+ continue;
+
+ ++count;
+ }
+
+ if (count == 0) // default match
+ return true;
+
+ // check for matches and place result in array
+ result = slideClass.match(pattern);
+
+ // now check if desired name is present for background
+ for (i = count = 0; i < result.length; i++)
+ {
+ if (result[i] == "hidden")
+ continue;
+
+ if (this.has_token(bgClass, result[i]))
+ return true;
+ }
+
+ return false;
+ },
+
+ resized: function () {
+ var width = 0;
+
+ if ( typeof( window.innerWidth ) == 'number' )
+ width = window.innerWidth; // Non IE browser
+ else if (document.documentElement && document.documentElement.clientWidth)
+ width = document.documentElement.clientWidth; // IE6
+ else if (document.body && document.body.clientWidth)
+ width = document.body.clientWidth; // IE4
+
+ var height = 0;
+
+ if ( typeof( window.innerHeight ) == 'number' )
+ height = window.innerHeight; // Non IE browser
+ else if (document.documentElement && document.documentElement.clientHeight)
+ height = document.documentElement.clientHeight; // IE6
+ else if (document.body && document.body.clientHeight)
+ height = document.body.clientHeight; // IE4
+
+ if (height && (width/height > 1.05*1024/768))
+ {
+ width = height * 1024.0/768;
+ }
+
+ // IE fires onresize even when only font size is changed!
+ // so we do a check to avoid blocking < and > actions
+ if (width != w3c_slidy.last_width || height != w3c_slidy.last_height)
+ {
+ if (width >= 1100)
+ w3c_slidy.size_index = 5; // 4
+ else if (width >= 1000)
+ w3c_slidy.size_index = 4; // 3
+ else if (width >= 800)
+ w3c_slidy.size_index = 3; // 2
+ else if (width >= 600)
+ w3c_slidy.size_index = 2; // 1
+ else if (width)
+ w3c_slidy.size_index = 0;
+
+ // add in font size adjustment from meta element e.g.
+ // <meta name="font-size-adjustment" content="-2" />
+ // useful when slides have too much content ;-)
+
+ if (0 <= w3c_slidy.size_index + w3c_slidy.size_adjustment &&
+ w3c_slidy.size_index + w3c_slidy.size_adjustment < w3c_slidy.sizes.length)
+ w3c_slidy.size_index = w3c_slidy.size_index + w3c_slidy.size_adjustment;
+
+ // enables cross browser use of relative width/height
+ // on object elements for use with SVG and Flash media
+ w3c_slidy.adjust_object_dimensions(width, height);
+
+ if (document.body.style.fontSize != w3c_slidy.sizes[w3c_slidy.size_index])
+ {
+ document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index];
+ }
+
+ w3c_slidy.last_width = width;
+ w3c_slidy.last_height = height;
+
+ // force reflow to work around Mozilla bug
+ if (w3c_slidy.ns_pos)
+ {
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.show_slide(slide);
+ }
+
+ // force correct positioning of toolbar
+ w3c_slidy.refresh_toolbar(200);
+ }
+ },
+
+ scrolled: function () {
+ if (w3c_slidy.toolbar && !w3c_slidy.ns_pos && !w3c_slidy.ie7)
+ {
+ w3c_slidy.hack_offset = w3c_slidy.scroll_x_offset();
+ // hide toolbar
+ w3c_slidy.toolbar.style.display = "none";
+
+ // make it reappear later
+ if (w3c_slidy.scrollhack == 0 && !w3c_slidy.view_all)
+ {
+ setTimeout(function () {w3c_slidy.show_toolbar(); }, 1000);
+ w3c_slidy.scrollhack = 1;
+ }
+ }
+ },
+
+ hide_toolbar: function () {
+ w3c_slidy.add_class(w3c_slidy.toolbar, "hidden");
+ window.focus();
+ },
+
+ // used to ensure IE refreshes toolbar in correct position
+ refresh_toolbar: function (interval) {
+ if (!w3c_slidy.ns_pos && !w3c_slidy.ie7)
+ {
+ w3c_slidy.hide_toolbar();
+ setTimeout(function () {w3c_slidy.show_toolbar(); }, interval);
+ }
+ },
+
+ // restores toolbar after short delay
+ show_toolbar: function () {
+ if (w3c_slidy.want_toolbar)
+ {
+ w3c_slidy.toolbar.style.display = "block";
+
+ if (!w3c_slidy.ns_pos)
+ {
+ // adjust position to allow for scrolling
+ var xoffset = w3c_slidy.scroll_x_offset();
+ w3c_slidy.toolbar.style.left = xoffset;
+ w3c_slidy.toolbar.style.right = xoffset;
+
+ // determine vertical scroll offset
+ //var yoffset = scrollYOffset();
+
+ // bottom is doc height - window height - scroll offset
+ //var bottom = documentHeight() - lastHeight - yoffset
+
+ //if (yoffset > 0 || documentHeight() > lastHeight)
+ // bottom += 16; // allow for height of scrollbar
+
+ w3c_slidy.toolbar.style.bottom = 0; //bottom;
+ }
+
+ w3c_slidy.remove_class(w3c_slidy.toolbar, "hidden");
+ }
+
+ w3c_slidy.scrollhack = 0;
+
+
+ // set the keyboard focus to the help link on the
+ // toolbar to ensure that document has the focus
+ // IE doesn't always work with window.focus()
+ // and this hack has benefit of Enter for help
+
+ try
+ {
+ if (!w3c_slidy.opera)
+ w3c_slidy.help_anchor.focus();
+ }
+ catch (e)
+ {
+ }
+ },
+
+// invoked via F key
+ toggle_toolbar: function () {
+ if (!w3c_slidy.view_all)
+ {
+ if (w3c_slidy.has_class(w3c_slidy.toolbar, "hidden"))
+ {
+ w3c_slidy.remove_class(w3c_slidy.toolbar, "hidden")
+ w3c_slidy.want_toolbar = 1;
+ }
+ else
+ {
+ w3c_slidy.add_class(w3c_slidy.toolbar, "hidden")
+ w3c_slidy.want_toolbar = 0;
+ }
+ }
+ },
+
+ scroll_x_offset: function () {
+ if (window.pageXOffset)
+ return self.pageXOffset;
+
+ if (document.documentElement &&
+ document.documentElement.scrollLeft)
+ return document.documentElement.scrollLeft;
+
+ if (document.body)
+ return document.body.scrollLeft;
+
+ return 0;
+ },
+
+ scroll_y_offset: function () {
+ if (window.pageYOffset)
+ return self.pageYOffset;
+
+ if (document.documentElement &&
+ document.documentElement.scrollTop)
+ return document.documentElement.scrollTop;
+
+ if (document.body)
+ return document.body.scrollTop;
+
+ return 0;
+ },
+
+ // looking for a way to determine height of slide content
+ // the slide itself is set to the height of the window
+ optimize_font_size: function () {
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+
+ //var dh = documentHeight(); //getDocHeight(document);
+ var dh = slide.scrollHeight;
+ var wh = getWindowHeight();
+ var u = 100 * dh / wh;
+
+ alert("window utilization = " + u + "% (doc "
+ + dh + " win " + wh + ")");
+ },
+
+ // from document object
+ get_doc_height: function (doc) {
+ if (!doc)
+ doc = document;
+
+ if (doc && doc.body && doc.body.offsetHeight)
+ return doc.body.offsetHeight; // ns/gecko syntax
+
+ if (doc && doc.body && doc.body.scrollHeight)
+ return doc.body.scrollHeight;
+
+ alert("couldn't determine document height");
+ },
+
+ get_window_height: function () {
+ if ( typeof( window.innerHeight ) == 'number' )
+ return window.innerHeight; // Non IE browser
+
+ if (document.documentElement && document.documentElement.clientHeight)
+ return document.documentElement.clientHeight; // IE6
+
+ if (document.body && document.body.clientHeight)
+ return document.body.clientHeight; // IE4
+ },
+
+ document_height: function () {
+ var sh, oh;
+
+ sh = document.body.scrollHeight;
+ oh = document.body.offsetHeight;
+
+ if (sh && oh)
+ {
+ return (sh > oh ? sh : oh);
+ }
+
+ // no idea!
+ return 0;
+ },
+
+ smaller: function () {
+ if (w3c_slidy.size_index > 0)
+ {
+ --w3c_slidy.size_index;
+ }
+
+ w3c_slidy.toolbar.style.display = "none";
+ document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index];
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.show_slide(slide);
+ setTimeout(function () {w3c_slidy.show_toolbar(); }, 50);
+ },
+
+ bigger: function () {
+ if (w3c_slidy.size_index < w3c_slidy.sizes.length - 1)
+ {
+ ++w3c_slidy.size_index;
+ }
+
+ w3c_slidy.toolbar.style.display = "none";
+ document.body.style.fontSize = w3c_slidy.sizes[w3c_slidy.size_index];
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+ w3c_slidy.hide_slide(slide);
+ w3c_slidy.show_slide(slide);
+ setTimeout(function () {w3c_slidy.show_toolbar(); }, 50);
+ },
+
+ // enables cross browser use of relative width/height
+ // on object elements for use with SVG and Flash media
+ // with thanks to Ivan Herman for the suggestion
+ adjust_object_dimensions: function (width, height) {
+ for( var i = 0; i < w3c_slidy.objects.length; i++ )
+ {
+ var obj = this.objects[i];
+ var mimeType = obj.getAttribute("type");
+
+ if (mimeType == "image/svg+xml" || mimeType == "application/x-shockwave-flash")
+ {
+ if ( !obj.initialWidth )
+ obj.initialWidth = obj.getAttribute("width");
+
+ if ( !obj.initialHeight )
+ obj.initialHeight = obj.getAttribute("height");
+
+ if ( obj.initialWidth && obj.initialWidth.charAt(obj.initialWidth.length-1) == "%" )
+ {
+ var w = parseInt(obj.initialWidth.slice(0, obj.initialWidth.length-1));
+ var newW = width * (w/100.0);
+ obj.setAttribute("width",newW);
+ }
+
+ if ( obj.initialHeight &&
+ obj.initialHeight.charAt(obj.initialHeight.length-1) == "%" )
+ {
+ var h = parseInt(obj.initialHeight.slice(0, obj.initialHeight.length-1));
+ var newH = height * (h/100.0);
+ obj.setAttribute("height", newH);
+ }
+ }
+ }
+ },
+
+ // needed for Opera to inhibit default behavior
+ // since Opera delivers keyPress even if keyDown
+ // was cancelled
+ key_press: function (event) {
+ if (!event)
+ event = window.event;
+
+ if (!w3c_slidy.key_wanted)
+ return w3c_slidy.cancel(event);
+
+ return true;
+ },
+
+ // See e.g. http://www.quirksmode.org/js/events/keys.html for keycodes
+ key_down: function (event) {
+ var key;
+
+ w3c_slidy.key_wanted = true;
+
+ if (!event)
+ event = window.event;
+
+ // kludge around NS/IE differences
+ if (window.event)
+ key = window.event.keyCode;
+ else if (event.which)
+ key = event.which;
+ else
+ return true; // Yikes! unknown browser
+
+ // ignore event if key value is zero
+ // as for alt on Opera and Konqueror
+ if (!key)
+ return true;
+
+ // check for concurrent control/command/alt key
+ // but are these only present on mouse events?
+
+ if (event.ctrlKey || event.altKey || event.metaKey)
+ return true;
+
+ // dismiss table of contents if visible
+ if (w3c_slidy.is_shown_toc() && key != 9 && key != 16 && key != 38 && key != 40)
+ {
+ w3c_slidy.hide_table_of_contents();
+
+ if (key == 27 || key == 84 || key == 67)
+ return w3c_slidy.cancel(event);
+ }
+
+ if (key == 34) // Page Down
+ {
+ if (w3c_slidy.view_all)
+ return true;
+
+ w3c_slidy.next_slide(false);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 33) // Page Up
+ {
+ if (w3c_slidy.view_all)
+ return true;
+
+ w3c_slidy.previous_slide(false);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 32) // space bar
+ {
+ w3c_slidy.next_slide(true);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 37) // Left arrow
+ {
+ w3c_slidy.previous_slide(!event.shiftKey);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 36) // Home
+ {
+ w3c_slidy.first_slide();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 35) // End
+ {
+ w3c_slidy.last_slide();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 39) // Right arrow
+ {
+ w3c_slidy.next_slide(!event.shiftKey);
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 13) // Enter
+ {
+ if (w3c_slidy.outline)
+ {
+ if (w3c_slidy.outline.visible)
+ w3c_slidy.fold(w3c_slidy.outline);
+ else
+ w3c_slidy.unfold(w3c_slidy.outline);
+
+ return w3c_slidy.cancel(event);
+ }
+ }
+ else if (key == 188) // < for smaller fonts
+ {
+ w3c_slidy.smaller();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 190) // > for larger fonts
+ {
+ w3c_slidy.bigger();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 189 || key == 109) // - for smaller fonts
+ {
+ w3c_slidy.smaller();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 187 || key == 191 || key == 107) // = + for larger fonts
+ {
+ w3c_slidy.bigger();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 83) // S for smaller fonts
+ {
+ w3c_slidy.smaller();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 66) // B for larger fonts
+ {
+ w3c_slidy.bigger();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 90) // Z for last slide
+ {
+ w3c_slidy.last_slide();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 70) // F for toggle toolbar
+ {
+ w3c_slidy.toggle_toolbar();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 65) // A for toggle view single/all slides
+ {
+ w3c_slidy.toggle_view();
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 75) // toggle action of left click for next page
+ {
+ w3c_slidy.mouse_click_enabled = !w3c_slidy.mouse_click_enabled;
+ var alert_msg = (w3c_slidy.mouse_click_enabled ?
+ "enabled" : "disabled") + " mouse click advance";
+
+ alert(alert_msg.localize());
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 84 || key == 67) // T or C for table of contents
+ {
+ if (w3c_slidy.toc)
+ w3c_slidy.toggle_table_of_contents();
+
+ return w3c_slidy.cancel(event);
+ }
+ else if (key == 72) // H for help
+ {
+ window.location = w3c_slidy.help_page;
+ return w3c_slidy.cancel(event);
+ }
+ //else alert("key code is "+ key);
+
+ return true;
+ },
+
+ // safe for both text/html and application/xhtml+xml
+ create_element: function (name) {
+ if (this.xhtml && (typeof document.createElementNS != 'undefined'))
+ return document.createElementNS("http://www.w3.org/1999/xhtml", name)
+
+ return document.createElement(name);
+ },
+
+ get_element_style: function (elem, IEStyleProp, CSSStyleProp) {
+ if (elem.currentStyle)
+ {
+ return elem.currentStyle[IEStyleProp];
+ }
+ else if (window.getComputedStyle)
+ {
+ var compStyle = window.getComputedStyle(elem, "");
+ return compStyle.getPropertyValue(CSSStyleProp);
+ }
+ return "";
+ },
+
+ // the string str is a whitespace separated list of tokens
+ // test if str contains a particular token, e.g. "slide"
+ has_token: function (str, token) {
+ if (str)
+ {
+ // define pattern as regular expression
+ var pattern = /\w+/g;
+
+ // check for matches
+ // place result in array
+ var result = str.match(pattern);
+
+ // now check if desired token is present
+ for (var i = 0; i < result.length; i++)
+ {
+ if (result[i] == token)
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ get_class_list: function (element) {
+ if (typeof element.className != 'undefined')
+ return element.className;
+
+ return element.getAttribute("class");
+ },
+
+ has_class: function (element, name) {
+ if (element.nodeType != 1)
+ return false;
+
+ var regexp = new RegExp("(^| )" + name + "\W*");
+
+ if (typeof element.className != 'undefined')
+ return regexp.test(element.className);
+
+ return regexp.test(element.getAttribute("class"));
+ },
+
+ remove_class: function (element, name) {
+ var regexp = new RegExp("(^| )" + name + "\W*");
+ var clsval = "";
+
+ if (typeof element.className != 'undefined')
+ {
+ clsval = element.className;
+
+ if (clsval)
+ {
+ clsval = clsval.replace(regexp, "");
+ element.className = clsval;
+ }
+ }
+ else
+ {
+ clsval = element.getAttribute("class");
+
+ if (clsval)
+ {
+ clsval = clsval.replace(regexp, "");
+ element.setAttribute("class", clsval);
+ }
+ }
+ },
+
+ add_class: function (element, name) {
+ if (!this.has_class(element, name))
+ {
+ if (typeof element.className != 'undefined')
+ element.className += " " + name;
+ else
+ {
+ var clsval = element.getAttribute("class");
+ clsval = clsval ? clsval + " " + name : name;
+ element.setAttribute("class", clsval);
+ }
+ }
+ },
+
+ // HTML elements that can be used with class="incremental"
+ // note that you can also put the class on containers like
+ // up, ol, dl, and div to make their contents appear
+ // incrementally. Upper case is used since this is what
+ // browsers report for HTML node names (text/html).
+ incremental_elements: null,
+ okay_for_incremental: function (name) {
+ if (!this.incremental_elements)
+ {
+ var inclist = new Array();
+ inclist["p"] = true;
+ inclist["pre"] = true;
+ inclist["li"] = true;
+ inclist["blockquote"] = true;
+ inclist["dt"] = true;
+ inclist["dd"] = true;
+ inclist["h2"] = true;
+ inclist["h3"] = true;
+ inclist["h4"] = true;
+ inclist["h5"] = true;
+ inclist["h6"] = true;
+ inclist["span"] = true;
+ inclist["address"] = true;
+ inclist["table"] = true;
+ inclist["tr"] = true;
+ inclist["th"] = true;
+ inclist["td"] = true;
+ inclist["img"] = true;
+ inclist["object"] = true;
+ this.incremental_elements = inclist;
+ }
+ return this.incremental_elements[name.toLowerCase()];
+ },
+
+ next_incremental_item: function (node) {
+ var br = this.is_xhtml ? "br" : "BR";
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+
+ for (;;)
+ {
+ node = w3c_slidy.next_node(slide, node);
+
+ if (node == null || node.parentNode == null)
+ break;
+
+ if (node.nodeType == 1) // ELEMENT
+ {
+ if (node.nodeName == br)
+ continue;
+
+ if (w3c_slidy.has_class(node, "incremental")
+ && w3c_slidy.okay_for_incremental(node.nodeName))
+ return node;
+
+ if (w3c_slidy.has_class(node.parentNode, "incremental")
+ && !w3c_slidy.has_class(node, "non-incremental"))
+ return node;
+ }
+ }
+
+ return node;
+ },
+
+ previous_incremental_item: function (node) {
+ var br = this.is_xhtml ? "br" : "BR";
+ var slide = w3c_slidy.slides[w3c_slidy.slide_number];
+
+ for (;;)
+ {
+ node = w3c_slidy.previous_node(slide, node);
+
+ if (node == null || node.parentNode == null)
+ break;
+
+ if (node.nodeType == 1)
+ {
+ if (node.nodeName == br)
+ continue;
+
+ if (w3c_slidy.has_class(node, "incremental")
+ && w3c_slidy.okay_for_incremental(node.nodeName))
+ return node;
+
+ if (w3c_slidy.has_class(node.parentNode, "incremental")
+ && !w3c_slidy.has_class(node, "non-incremental"))
+ return node;
+ }
+ }
+
+ return node;
+ },
+
+ // set visibility for all elements on current slide with
+ // a parent element with attribute class="incremental"
+ set_visibility_all_incremental: function (value) {
+ var node = this.next_incremental_item(null);
+
+ if (value == "hidden")
+ {
+ while (node)
+ {
+ w3c_slidy.add_class(node, "invisible");
+ node = w3c_slidy.next_incremental_item(node);
+ }
+ }
+ else // value == "visible"
+ {
+ while (node)
+ {
+ w3c_slidy.remove_class(node, "invisible");
+ node = w3c_slidy.next_incremental_item(node);
+ }
+ }
+ },
+
+ // reveal the next hidden item on the slide
+ // node is null or the node that was last revealed
+ reveal_next_item: function (node) {
+ node = w3c_slidy.next_incremental_item(node);
+
+ if (node && node.nodeType == 1) // an element
+ w3c_slidy.remove_class(node, "invisible");
+
+ return node;
+ },
+
+ // exact inverse of revealNextItem(node)
+ hide_previous_item: function (node) {
+ if (node && node.nodeType == 1) // an element
+ w3c_slidy.add_class(node, "invisible");
+
+ return this.previous_incremental_item(node);
+ },
+
+ // left to right traversal of root's content
+ next_node: function (root, node) {
+ if (node == null)
+ return root.firstChild;
+
+ if (node.firstChild)
+ return node.firstChild;
+
+ if (node.nextSibling)
+ return node.nextSibling;
+
+ for (;;)
+ {
+ node = node.parentNode;
+
+ if (!node || node == root)
+ break;
+
+ if (node && node.nextSibling)
+ return node.nextSibling;
+ }
+
+ return null;
+ },
+
+ // right to left traversal of root's content
+ previous_node: function (root, node) {
+ if (node == null)
+ {
+ node = root.lastChild;
+
+ if (node)
+ {
+ while (node.lastChild)
+ node = node.lastChild;
+ }
+
+ return node;
+ }
+
+ if (node.previousSibling)
+ {
+ node = node.previousSibling;
+
+ while (node.lastChild)
+ node = node.lastChild;
+
+ return node;
+ }
+
+ if (node.parentNode != root)
+ return node.parentNode;
+
+ return null;
+ },
+
+ previous_sibling_element: function (el) {
+ el = el.previousSibling;
+
+ while (el && el.nodeType != 1)
+ el = el.previousSibling;
+
+ return el;
+ },
+
+ next_sibling_element: function (el) {
+ el = el.nextSibling;
+
+ while (el && el.nodeType != 1)
+ el = el.nextSibling;
+
+ return el;
+ },
+
+ first_child_element: function (el) {
+ var node;
+
+ for (node = el.firstChild; node; node = node.nextSibling)
+ {
+ if (node.nodeType == 1)
+ break;
+ }
+
+ return node;
+ },
+
+ first_tag: function (element, tag) {
+ var node;
+
+ if (!this.is_xhtml)
+ tag = tag.toUpperCase();
+
+ for (node = element.firstChild; node; node = node.nextSibling)
+ {
+ if (node.nodeType == 1 && node.nodeName == tag)
+ break;
+ }
+
+ return node;
+ },
+
+ hide_selection: function () {
+ if (window.getSelection) // Firefox, Chromium, Safari, Opera
+ {
+ var selection = window.getSelection();
+
+ if (selection.rangeCount > 0)
+ {
+ var range = selection.getRangeAt(0);
+ range.collapse (false);
+ }
+ }
+ else // Internet Explorer
+ {
+ var textRange = document.selection.createRange ();
+ textRange.collapse (false);
+ }
+ },
+
+ get_selected_text: function () {
+ try
+ {
+ if (window.getSelection)
+ return window.getSelection().toString();
+
+ if (document.getSelection)
+ return document.getSelection().toString();
+
+ if (document.selection)
+ return document.selection.createRange().text;
+ }
+ catch (e)
+ {
+ }
+
+ return "";
+ },
+
+ // make note of length of selected text
+ // as this evaluates to zero in click event
+ mouse_button_up: function (e) {
+ w3c_slidy.selected_text_len = w3c_slidy.get_selected_text().length;
+ },
+
+ // right mouse button click is reserved for context menus
+ // it is more reliable to detect rightclick than leftclick
+ mouse_button_click: function (e) {
+ var rightclick = false;
+ var leftclick = false;
+ var middleclick = false;
+ var target;
+
+ if (!e)
+ var e = window.event;
+
+ if (e.target)
+ target = e.target;
+ else if (e.srcElement)
+ target = e.srcElement;
+
+ // work around Safari bug
+ if (target.nodeType == 3)
+ target = target.parentNode;
+
+ if (e.which) // all browsers except IE
+ {
+ leftclick = (e.which == 1);
+ middleclick = (e.which == 2);
+ rightclick = (e.which == 3);
+ }
+ else if (e.button)
+ {
+ // Konqueror gives 1 for left, 4 for middle
+ // IE6 gives 0 for left and not 1 as I expected
+
+ if (e.button == 4)
+ middleclick = true;
+
+ // all browsers agree on 2 for right button
+ rightclick = (e.button == 2);
+ }
+ else leftclick = true;
+/*
+ alert("you clicked over a " + target.nodeName + " element\n" +
+ "w3c_slidy.mouse_click_enabled = " + w3c_slidy.mouse_click_enabled + "\n" +
+ "leftclick = " + leftclick + "\n" +
+ "selected text length = " + w3c_slidy.selected_text_len);
+ //alert("selected text length = " + w3c_slidy.selected_text_len);
+*/
+ if (w3c_slidy.selected_text_len > 0)
+ {
+ w3c_slidy.stop_propagation(e);
+ e.cancel = true;
+ e.returnValue = false;
+ return false;
+ }
+
+ // dismiss table of contents
+ w3c_slidy.hide_table_of_contents();
+
+ // check if target is something that probably want's clicks
+ // e.g. a, embed, object, input, textarea, select, option
+ var tag = target.nodeName.toLowerCase();
+
+ if (w3c_slidy.mouse_click_enabled && leftclick &&
+ tag != "a" &&
+ tag != "embed" &&
+ tag != "object" &&
+ tag != "video" &&
+ tag != "input" &&
+ tag != "textarea" &&
+ tag != "select" &&
+ tag != "option" &&
+ !target.onclick)
+ {
+ w3c_slidy.next_slide(true);
+ w3c_slidy.stop_propagation(e);
+ e.cancel = true;
+ e.returnValue = false;
+ return false;
+ }
+ },
+
+ get_key: function (e)
+ {
+ var key;
+
+ // kludge around NS/IE differences
+ if (typeof window.event != "undefined")
+ key = window.event.keyCode;
+ else if (e.which)
+ key = e.which;
+
+ return key;
+ },
+
+ get_target: function (e) {
+ var target;
+
+ if (!e)
+ e = window.event;
+
+ if (e.target)
+ target = e.target;
+ else if (e.srcElement)
+ target = e.srcElement;
+
+ if (target.nodeType != 1)
+ target = target.parentNode;
+
+ return target;
+ },
+
+ // does display property provide correct defaults?
+ is_block: function (elem) {
+ var tag = elem.nodeName.toLowerCase();
+
+ return tag == "ol" || tag == "ul" || tag == "p" ||
+ tag == "li" || tag == "table" || tag == "pre" ||
+ tag == "h1" || tag == "h2" || tag == "h3" ||
+ tag == "h4" || tag == "h5" || tag == "h6" ||
+ tag == "blockquote" || tag == "address";
+ },
+
+ add_listener: function (element, event, handler) {
+ if (window.addEventListener)
+ element.addEventListener(event, handler, false);
+ else
+ element.attachEvent("on"+event, handler);
+ },
+
+ // used to prevent event propagation from field controls
+ stop_propagation: function (event) {
+ event = event ? event : window.event;
+ event.cancelBubble = true; // for IE
+
+ if (event.stopPropagation)
+ event.stopPropagation();
+
+ return true;
+ },
+
+ cancel: function (event) {
+ if (event)
+ {
+ event.cancel = true;
+ event.returnValue = false;
+
+ if (event.preventDefault)
+ event.preventDefault();
+ }
+
+ w3c_slidy.key_wanted = false;
+ return false;
+ }
+};
+
+// for each language define an associative array
+// and also the help text which is longer
+
+var w3c_slidy_i18n = {
+ strings_es: {
+ "slide":"pág.",
+ "help?":"Ayuda",
+ "contents?":"Índice",
+ "table of contents":"tabla de contenidos",
+ "Table of Contents":"Tabla de Contenidos",
+ "restart presentation":"Reiniciar presentación",
+ "restart?":"Inicio"
+ },
+ help_es:
+ "Utilice el ratón, barra espaciadora, teclas Izda/Dcha, " +
+ "o Re pág y Av pág. Use S y B para cambiar el tamaño de fuente.",
+
+ strings_ca: {
+ "slide":"pàg..",
+ "help?":"Ajuda",
+ "contents?":"Índex",
+ "table of contents":"taula de continguts",
+ "Table of Contents":"Taula de Continguts",
+ "restart presentation":"Reiniciar presentació",
+ "restart?":"Inici"
+ },
+ help_ca:
+ "Utilitzi el ratolí, barra espaiadora, tecles Esq./Dta. " +
+ "o Re pàg y Av pàg. Usi S i B per canviar grandària de font.",
+
+ strings_cs: {
+ "slide":"snímek",
+ "help?":"nápověda",
+ "contents?":"obsah",
+ "table of contents":"obsah prezentace",
+ "Table of Contents":"Obsah prezentace",
+ "restart presentation":"znovu spustit prezentaci",
+ "restart?":"restart"
+ },
+ help_cs:
+ "Prezentaci můžete procházet pomocí kliknutí myši, mezerníku, " +
+ "šipek vlevo a vpravo nebo kláves PageUp a PageDown. Písmo se " +
+ "dá zvětšit a zmenšit pomocí kláves B a S.",
+
+ strings_nl: {
+ "slide":"pagina",
+ "help?":"Help?",
+ "contents?":"Inhoud?",
+ "table of contents":"inhoudsopgave",
+ "Table of Contents":"Inhoudsopgave",
+ "restart presentation":"herstart presentatie",
+ "restart?":"Herstart?"
+ },
+ help_nl:
+ "Navigeer d.m.v. het muis, spatiebar, Links/Rechts toetsen, " +
+ "of PgUp en PgDn. Gebruik S en B om de karaktergrootte te veranderen.",
+
+ strings_de: {
+ "slide":"Seite",
+ "help?":"Hilfe",
+ "contents?":"Übersicht",
+ "table of contents":"Inhaltsverzeichnis",
+ "Table of Contents":"Inhaltsverzeichnis",
+ "restart presentation":"Präsentation neu starten",
+ "restart?":"Neustart"
+ },
+ help_de:
+ "Benutzen Sie die Maus, Leerschlag, die Cursortasten links/rechts oder " +
+ "Page up/Page Down zum Wechseln der Seiten und S und B für die Schriftgrösse.",
+
+ strings_pl: {
+ "slide":"slajd",
+ "help?":"pomoc?",
+ "contents?":"spis treści?",
+ "table of contents":"spis treści",
+ "Table of Contents":"Spis Treści",
+ "restart presentation":"Restartuj prezentację",
+ "restart?":"restart?"
+ },
+ help_pl:
+ "Zmieniaj slajdy klikając myszą, naciskając spację, strzałki lewo/prawo" +
+ "lub PgUp / PgDn. Użyj klawiszy S i B, aby zmienić rozmiar czczionki.",
+
+ strings_fr: {
+ "slide":"page",
+ "help?":"Aide",
+ "contents?":"Index",
+ "table of contents":"table des matières",
+ "Table of Contents":"Table des matières",
+ "restart presentation":"Recommencer l'exposé",
+ "restart?":"Début"
+ },
+ help_fr:
+ "Naviguez avec la souris, la barre d'espace, les flèches " +
+ "gauche/droite ou les touches Pg Up, Pg Dn. Utilisez " +
+ "les touches S et B pour modifier la taille de la police.",
+
+ strings_hu: {
+ "slide":"oldal",
+ "help?":"segítség",
+ "contents?":"tartalom",
+ "table of contents":"tartalomjegyzék",
+ "Table of Contents":"Tartalomjegyzék",
+ "restart presentation":"bemutató újraindítása",
+ "restart?":"újraindítás"
+ },
+ help_hu:
+ "Az oldalak közti lépkedéshez kattintson az egérrel, vagy " +
+ "használja a szóköz, a bal, vagy a jobb nyíl, illetve a Page Down, " +
+ "Page Up billentyűket. Az S és a B billentyűkkel változtathatja " +
+ "a szöveg méretét.",
+
+ strings_it: {
+ "slide":"pag.",
+ "help?":"Aiuto",
+ "contents?":"Indice",
+ "table of contents":"indice",
+ "Table of Contents":"Indice",
+ "restart presentation":"Ricominciare la presentazione",
+ "restart?":"Inizio"
+ },
+ help_it:
+ "Navigare con mouse, barra spazio, frecce sinistra/destra o " +
+ "PgUp e PgDn. Usare S e B per cambiare la dimensione dei caratteri.",
+
+ strings_el: {
+ "slide":"σελίδα",
+ "help?":"βοήθεια;",
+ "contents?":"περιεχόμενα;",
+ "table of contents":"πίνακας περιεχομένων",
+ "Table of Contents":"Πίνακας Περιεχομένων",
+ "restart presentation":"επανεκκίνηση παρουσίασης",
+ "restart?":"επανεκκίνηση;"
+ },
+ help_el:
+ "Πλοηγηθείτε με το κλίκ του ποντικιού, το space, τα βέλη αριστερά/δεξιά, " +
+ "ή Page Up και Page Down. Χρησιμοποιήστε τα πλήκτρα S και B για να αλλάξετε " +
+ "το μέγεθος της γραμματοσειράς.",
+
+ strings_ja: {
+ "slide":"スライド",
+ "help?":"ヘルプ",
+ "contents?":"目次",
+ "table of contents":"目次を表示",
+ "Table of Contents":"目次",
+ "restart presentation":"最初から再生",
+ "restart?":"最初から"
+ },
+ help_ja:
+ "マウス左クリック ・ スペース ・ 左右キー " +
+ "または Page Up ・ Page Downで操作, S ・ Bでフォントサイズ変更",
+
+ strings_zh: {
+ "slide":"幻灯片",
+ "help?":"帮助?",
+ "contents?":"内容?",
+ "table of contents":"目录",
+ "Table of Contents":"目录",
+ "restart presentation":"重新启动展示",
+ "restart?":"重新启动?"
+ },
+ help_zh:
+ "用鼠标点击, 空格条, 左右箭头, Pg Up 和 Pg Dn 导航. " +
+ "用 S, B 改变字体大小.",
+
+ strings_ru: {
+ "slide":"слайд",
+ "help?":"помощь?",
+ "contents?":"содержание?",
+ "table of contents":"оглавление",
+ "Table of Contents":"Оглавление",
+ "restart presentation":"перезапустить презентацию",
+ "restart?":"перезапуск?"
+ },
+ help_ru:
+ "Перемещайтесь кликая мышкой, используя клавишу пробел, стрелки" +
+ "влево/вправо или Pg Up и Pg Dn. Клавиши S и B меняют размер шрифта.",
+
+ strings_sv: {
+ "slide":"sida",
+ "help?":"hjälp",
+ "contents?":"innehåll",
+ "table of contents":"innehållsförteckning",
+ "Table of Contents":"Innehållsförteckning",
+ "restart presentation":"visa presentationen från början",
+ "restart?":"börja om"
+ },
+ help_sv:
+ "Bläddra med ett klick med vänstra musknappen, mellanslagstangenten, " +
+ "vänster- och högerpiltangenterna eller tangenterna Pg Up, Pg Dn. " +
+ "Använd tangenterna S och B för att ändra textens storlek.",
+
+// each such language array is declared in the localize array
+// which is set on string prototype and used as in "foo".localize();
+ localize: {
+ "es":this.strings_es,
+ "ca":this.strings_ca,
+ "cs":this.strings_cs,
+ "nl":this.strings_nl,
+ "de":this.strings_de,
+ "pl":this.strings_pl,
+ "fr":this.strings_fr,
+ "hu":this.strings_hu,
+ "it":this.strings_it,
+ "el":this.strings_el,
+ "jp":this.strings_ja,
+ "zh":this.strings_zh,
+ "ru":this.strings_ru,
+ "sv":this.strings_sv
+ },
+
+ init: function () {
+ var i18n = w3c_slidy_i18n;
+ var help_text = w3c_slidy.help_text;
+ i18n.strings_es[help_text] = i18n.help_es;
+ i18n.strings_ca[help_text] = i18n.help_ca;
+ i18n.strings_cs[help_text] = i18n.help_cs;
+ i18n.strings_nl[help_text] = i18n.help_nl;
+ i18n.strings_de[help_text] = i18n.help_de;
+ i18n.strings_pl[help_text] = i18n.help_pl;
+ i18n.strings_fr[help_text] = i18n.help_fr;
+ i18n.strings_hu[help_text] = i18n.help_hu;
+ i18n.strings_it[help_text] = i18n.help_it;
+ i18n.strings_el[help_text] = i18n.help_el;
+ i18n.strings_ja[help_text] = i18n.help_ja;
+ i18n.strings_zh[help_text] = i18n.help_zh;
+ i18n.strings_ru[help_text] = i18n.help_ru;
+ i18n.strings_sv[help_text] = i18n.help_sv;
+
+ w3c_slidy.lang = document.body.parentNode.getAttribute("lang");
+
+ if (!w3c_slidy.lang)
+ w3c_slidy.lang = document.body.parentNode.getAttribute("xml:lang");
+
+ if (!w3c_slidy.lang)
+ w3c_slidy.lang = "en";
+
+ // add localize method to all strings
+ // for use as in "contents".localize()
+ String.prototype.localize = function() {
+ if (this == "")
+ return this;
+
+ // try full language code, e.g. en-US
+ var s, lookup = w3c_slidy_i18n.localize[w3c_slidy.lang];
+
+ if (lookup)
+ {
+ s = lookup[this];
+
+ if (s)
+ return s;
+ }
+
+ // strip country code suffix, e.g.
+ // try en if undefined for en-US
+ var lg = w3c_slidy.lang.split("-");
+
+ if (lg.length > 1)
+ {
+ lookup = w3c_slidy_i18n.localize[lg[0]];
+
+ if (lookup)
+ {
+ s = lookup[this];
+
+ if (s)
+ return s;
+ }
+ }
+
+ // otherwise string as is
+ return this;
+ };
+ }
+};
+
+// hack for back button behavior
+if (w3c_slidy.ie6 || w3c_slidy.ie7)
+{
+ document.write("<iframe id='historyFrame' " +
+ "src='javascript:\"<html"+"></"+"html>\"' " +
+ "height='1' width='1' " +
+ "style='position:absolute;left:-800px'></iframe>");
+}
+
+// attach event listeners for initialization
+w3c_slidy.set_up();
+
+// hide the slides as soon as body element is available
+// to reduce annoying screen mess before the onload event
+setTimeout(w3c_slidy.hide_slides, 50);
+
+/*]]>*/
+</script>
+</head>
+<body class="article" style="max-width:45em">
+<div id="header" class="slide">
+<h1>Osmocom Callular Infrastructure Roadmap</h1>
+<span id="author">Harald Welte</span><br />
+</div>
+<div class="sect1 slide">
+<h1 id="_disclaimer">Disclaimer</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>People like Dieter, Holger, Daniel and I have invested lots of our
+spare time in the early years. So funding for that came from other
+paid work, and Osmocom projects were a hobby. It was a lot of fun, but
+it&#8217;s not a sustainable basis for the scope of the projects at this
+time.</p></div>
+<div class="paragraph"><p>Today, our development is driven by</p></div>
+<ul class="">
+<li>
+<span>
+what people contribute patches for, and/or
+</span>
+</li>
+<li>
+<span>
+what companies and consultants in the project get development
+ contracts for (e.g. sysmocom customers)
+</span>
+</li>
+</ul>
+<div class="paragraph"><p>This means in general that <strong>very little will happen, unless somebody
+commits to putting resources at it!</strong></p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_major_roadmap_areas">Major Roadmap Areas</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+Splitting up the NITB
+</span>
+</li>
+<li>
+<span>
+Code Quality
+</span>
+</li>
+<li>
+<span>
+Testing
+</span>
+</li>
+<li>
+<span>
+Integration between 2G and 3G
+</span>
+</li>
+<li>
+<span>
+External Interfaces
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_osmonitb">OsmoNITB</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+has been at the heart of most Osmocom based cellular networks
+</span>
+</li>
+<li>
+<span>
+is generally doing a good job, but suffers from some issues
+</span>
+</li>
+<li>
+<span>
+NITB includes BSC, but BSC code also used to build OsmoBSC
+</span>
+<ul class="">
+<li>
+<span>
+No way to test OsmoBSC without a proprietary MSC :(
+</span>
+</li>
+</ul>
+</li>
+<li>
+<span>
+NITB includes sqlite3 based HLR
+</span>
+<ul class="">
+<li>
+<span>
+synchronous/blocking access from single-threaded OsmoNITB
+</span>
+</li>
+<li>
+<span>
+sqlite3 (particularly via DBI) scalability issues
+</span>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_rip_nitb_long_live_osmomsc">RIP NITB; Long Live OsmoMSC</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+New <strong>OsmoMSC = OsmoNITB - BSC - HLR</strong>
+</span>
+</li>
+<li>
+<span>
+New OsmoHLR (GSUP interface only)
+</span>
+</li>
+<li>
+<span>
+3GPP A-over-IP for OsmoBSC + OsmoMSC
+</span>
+<ul class="">
+<li>
+<span>
+New SCCP+M3UA stack, libosmo-sigtran
+</span>
+</li>
+</ul>
+</li>
+<li>
+<span>
+M3UA based IuCS/IuPS in HNB-GW, MSC, SGSN
+</span>
+<ul class="">
+<li>
+<span>
+used to be SUA, as it was simpler initially
+</span>
+</li>
+</ul>
+</li>
+<li>
+<span>
+Single code base/branch for 2G and 3G
+</span>
+</li>
+</ul>
+<div class="paragraph"><p>&#8594; typical 2G setup will become <strong>OsmoBSC + OsmoMSC + OsmoHLR</strong></p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_osmostp">OsmoSTP</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>Signal Transfer Point, part of libosmo-sccp</p></div>
+<ul class="">
+<li>
+<span>
+M3UA + SUA support
+</span>
+</li>
+<li>
+<span>
+Connectionless and Conenction Oriented SCCP
+</span>
+</li>
+<li>
+<span>
+Used primarily for RAN-CN interface (A, Iu) so far
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_osmo_fsm_osmo_prim">osmo_fsm + osmo_prim</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="dlist"><dl class="">
+<dt class="hdlist1">
+osmo_fsm
+</dt>
+<dd>
+<p>
+structured approach to state machines
+</p>
+</dd>
+<dt class="hdlist1">
+osmo_prim
+</dt>
+<dd>
+<p>
+structured approach towards primitives at SAP between layers
+</p>
+</dd>
+</dl></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_osmo_fsm">osmo_fsm</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>Generalized finite state machine (FSM) abstraction</p></div>
+<ul class="">
+<li>
+<span>
+pure C language, no pre-processor / code-generator
+</span>
+</li>
+<li>
+<span>
+description of states, permitted events in a state, permitted
+ output states
+</span>
+</li>
+<li>
+<span>
+buit-in timer support. Default action on expiry: Destroy FSM
+</span>
+</li>
+<li>
+<span>
+parent/children relationship, allows hierarchy of FSMs
+</span>
+</li>
+</ul>
+<div class="paragraph"><p>Much more maintainable and deterministic than the many implicit or
+non-existing state machines in older code</p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_osmo_fsm_so_far">osmo_fsm so far</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+Ericsson OM2000 managed objects
+</span>
+</li>
+<li>
+<span>
+Connection-Oriented SCCP
+</span>
+</li>
+<li>
+<span>
+M3UA/SUA ASP + AS state machine
+</span>
+</li>
+<li>
+<span>
+All VLR FSMs (LU, Auth, &#8230;) in OsmoMSC
+</span>
+</li>
+<li>
+<span>
+AMR DTX in OsmoBTS
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_osmo_fsm_candidates">osmo_fsm candidates</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+LAPD + LAPDm code
+</span>
+</li>
+<li>
+<span>
+A-bis OML managed objects
+</span>
+</li>
+<li>
+<span>
+GSM Call Control (maybe even CAMEL-like FSMs?)
+</span>
+</li>
+</ul>
+<div class="paragraph"><p>More osmo_fsm Would greatly improve code quality, testability and
+maintainability</p></div>
+<ul class="">
+<li>
+<span>
+but who wants to invest in that? Any volunteers?
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_testing">Testing</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+unit test coverage of most code is poor, needs attention
+</span>
+<ul class="">
+<li>
+<span>
+coverage of new code much better than old code
+</span>
+</li>
+</ul>
+</li>
+<li>
+<span>
+osmo_fsm state introspection via CTRL enables better testing
+</span>
+</li>
+<li>
+<span>
+end-to-end system testing software: <strong>osmo-gsm-tester</strong>
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_osmo_gsm_tester">osmo-gsm-tester</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+python language for managing BTSs + Modems
+</span>
+<ul class="">
+<li>
+<span>
+supports different BTS models
+</span>
+</li>
+<li>
+<span>
+can execute suites of test cases on each software version for all BTS models
+</span>
+</li>
+</ul>
+</li>
+<li>
+<span>
+RF cabling between BTSs and Modems to avoid RF interference
+</span>
+</li>
+</ul>
+<div class="paragraph"><p>&#8594; GOAL: Daily functional testing on all supported platforms/configs</p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_osmo_gsm_tester_2">osmo-gsm-tester</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+core python infrastructure working
+</span>
+</li>
+<li>
+<span>
+jenkins integration for testing new builds working
+</span>
+</li>
+<li>
+<span>
+modem hardware being replaced due to poor ofono support for SL8082
+</span>
+</li>
+</ul>
+<div class="paragraph"><p>TODO:</p></div>
+<ul class="">
+<li>
+<span>
+modem integration using better supported hardware
+</span>
+</li>
+<li>
+<span>
+more actual test cases beyond SMS + LU
+</span>
+</li>
+<li>
+<span>
+3G support
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_external_interfaces">External Interfaces</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+<strong>VTY</strong> is a human interface, not intended for consumption by software
+</span>
+<ul class="">
+<li>
+<span>
+text output syntax not guaranteed stable
+</span>
+</li>
+<li>
+<span>
+inefficient
+</span>
+</li>
+<li>
+<span>
+commands get added during development to help developers
+</span>
+</li>
+</ul>
+</li>
+<li>
+<span>
+<strong>CTRL</strong> interface is the programmatic interface
+</span>
+<ul class="">
+<li>
+<span>
+but developers don&#8217;t need it during development
+</span>
+</li>
+<li>
+<span>
+all commands so far added due to user request/requirement
+</span>
+<ul class="">
+<li>
+<span>
+let us know what you need exposed!
+</span>
+</li>
+</ul>
+</li>
+<li>
+<span>
+only way to fundamentally change this is to automatically export things without extra effort
+</span>
+</li>
+</ul>
+</li>
+</ul>
+<div class="paragraph"><p>&#8658; Roadmap is to put more effort into CTRL completeness</p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_grand_unified_config_theory">Grand Unified Config Theory</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>Big Wishlist item:</p></div>
+<ul class="">
+<li>
+<span>
+Unified configuration store / MIB with
+</span>
+<ul class="">
+<li>
+<span>
+automatic VTY printer/parser generation
+</span>
+</li>
+<li>
+<span>
+automatic CTRL interface exposure
+</span>
+</li>
+<li>
+<span>
+telnet/VTY process + MIB daemon outside actual applications
+</span>
+</li>
+</ul>
+</li>
+</ul>
+<div class="paragraph"><p>But who will fund this / put resources at it?</p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_integration_between_2g_and_3g">Integration between 2G and 3G</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+so far, 2G and 3G live separate to each other
+</span>
+</li>
+<li>
+<span>
+we want integration
+</span>
+<ul class="">
+<li>
+<span>
+cross-advertisement of neighbor cells
+</span>
+</li>
+<li>
+<span>
+inter-RAT mobility
+</span>
+</li>
+<li>
+<span>
+inter-RAT hand-over
+</span>
+</li>
+</ul>
+</li>
+<li>
+<span>
+combined PS + CS attach
+</span>
+</li>
+<li>
+<span>
+SMS over packet switched
+</span>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_operation_maintenance">Operation / Maintenance</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+generation of Alarms in BTS + PCU (done)
+</span>
+</li>
+<li>
+<span>
+report via CTRL TRAP as well as A-bis OML (done)
+</span>
+</li>
+<li>
+<span>
+centralized reporting / collections of Alarms (tbd)
+</span>
+</li>
+</ul>
+<div class="paragraph"><p>&#8594; we need to generate more alarms in abnormal situations</p></div>
+<ul class="">
+<li>
+<span>
+generation of more stat, counters / KPIs
+</span>
+<ul class="">
+<li>
+<span>
+lots of work spent in 2016 on this alrady
+</span>
+</li>
+</ul>
+</li>
+</ul>
+<div class="paragraph"><p>&#8594; we need aggregation/interpretation/analysis of that data</p></div>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_further_wishlist">Further Wishlist</h1>
+<div class="sectionbody" style="max-width:45em">
+<ul class="">
+<li>
+<span>
+move SMSC out of OsmoMSC
+</span>
+</li>
+<li>
+<span>
+GSUP to MAP gateway
+</span>
+</li>
+<li>
+<span>
+billing interfaces
+</span>
+</li>
+<li>
+<span>
+LTE MME/S-GW-/P-GW
+</span>
+<ul class="">
+<li>
+<span>
+biggest issue is lack of good FOSS asn.1 tools for C
+</span>
+</li>
+<li>
+<span>
+we either have to ditch C, or invest lots of time in tools :/
+</span>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect1 slide">
+<h1 id="_eof">EOF</h1>
+<div class="sectionbody" style="max-width:45em">
+<div class="paragraph"><p>End of File</p></div>
+</div>
+</div>
+</body>
+</html>
diff --git a/2017/running_osmo_gsm-osmocon2017/Gsm_structures.svg b/2017/running_osmo_gsm-osmocon2017/Gsm_structures.svg
new file mode 100644
index 0000000..cd68155
--- /dev/null
+++ b/2017/running_osmo_gsm-osmocon2017/Gsm_structures.svg
@@ -0,0 +1,15874 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="868.44971"
+ height="528.51886"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.48.3.1 r9886"
+ sodipodi:docname="GSM_structures.svg"
+ style="display:inline"
+ inkscape:export-filename="/media/data/gsm/pictures/raster/UMTS_structure.png"
+ inkscape:export-xdpi="150.02303"
+ inkscape:export-ydpi="150.02303">
+ <title
+ id="title2938">GSM structure</title>
+ <defs
+ id="defs4">
+ <marker
+ inkscape:stockid="Arrow2Lstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Lstart"
+ style="overflow:visible">
+ <path
+ id="path6083"
+ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="matrix(1.1,0,0,1.1,1.1,0)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="19.9375"
+ x2="26.5"
+ y1="7.6875"
+ x1="21.8125"
+ id="linearGradient7094"
+ xlink:href="#linearGradient7088"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="41"
+ x2="64.5"
+ y1="42.625"
+ x1="64.5625"
+ gradientTransform="matrix(1,0,0,-1,-38,50.0585)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6122"
+ xlink:href="#linearGradient8012"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="41"
+ x2="64.5"
+ y1="42.625"
+ x1="64.5625"
+ gradientTransform="matrix(1,0,0,-1,-40,50.0585)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6118"
+ xlink:href="#linearGradient8000"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="41"
+ x2="64.5"
+ y1="42.625"
+ x1="64.5625"
+ gradientTransform="matrix(1,0,0,-1,-40,50.0585)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6116"
+ xlink:href="#linearGradient8012"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="52.811184"
+ x2="28.087311"
+ y1="25.375"
+ x1="24.375"
+ id="linearGradient7532"
+ xlink:href="#linearGradient7526"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="22.53125"
+ x2="23.749973"
+ y1="32.21875"
+ x1="27.53125"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7511"
+ xlink:href="#linearGradient8357"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="32.313343"
+ x2="44.0625"
+ y1="30.5"
+ x1="43.5"
+ gradientTransform="translate(-20,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7491"
+ xlink:href="#linearGradient7215"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="35.4375"
+ x2="44"
+ y1="33.46875"
+ x1="43.53125"
+ gradientTransform="translate(-20,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7488"
+ xlink:href="#linearGradient7223"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="38.4375"
+ x2="43.988625"
+ y1="36.505032"
+ x1="43.480392"
+ gradientTransform="translate(-20,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7485"
+ xlink:href="#linearGradient7231"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="26.4375"
+ x2="38.947304"
+ y1="24.541054"
+ x1="38.491497"
+ gradientTransform="translate(-20,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7482"
+ xlink:href="#linearGradient7199"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="26.4375"
+ x2="44"
+ y1="24.486135"
+ x1="43.493069"
+ gradientTransform="translate(-20,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7479"
+ xlink:href="#linearGradient7199"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="26.4375"
+ x2="48.976982"
+ y1="24.508232"
+ x1="48.478554"
+ gradientTransform="translate(-20,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7476"
+ xlink:href="#linearGradient7199"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="26.4375"
+ x2="38.947304"
+ y1="24.541054"
+ x1="38.491497"
+ gradientTransform="translate(-20,3)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7473"
+ xlink:href="#linearGradient7199"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="26.4375"
+ x2="44"
+ y1="24.486135"
+ x1="43.493069"
+ gradientTransform="translate(-20,3)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7470"
+ xlink:href="#linearGradient7199"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="26.4375"
+ x2="48.976982"
+ y1="24.508232"
+ x1="48.478554"
+ gradientTransform="translate(-20,3)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7467"
+ xlink:href="#linearGradient7199"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="32.500843"
+ x2="39"
+ y1="30.5"
+ x1="38.5"
+ gradientTransform="translate(-20,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7464"
+ xlink:href="#linearGradient7215"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="32.4375"
+ x2="49"
+ y1="30.46875"
+ x1="48.5"
+ gradientTransform="translate(-20,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7461"
+ xlink:href="#linearGradient7215"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="35.4375"
+ x2="49"
+ y1="33.46875"
+ x1="48.53125"
+ gradientTransform="translate(-20,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7458"
+ xlink:href="#linearGradient7223"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="35.497356"
+ x2="39.0625"
+ y1="33.5625"
+ x1="38.5"
+ gradientTransform="translate(-20,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7455"
+ xlink:href="#linearGradient7223"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="38.440475"
+ x2="40.01115"
+ y1="36.460838"
+ x1="39.502918"
+ gradientTransform="translate(-20,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7452"
+ xlink:href="#linearGradient7231"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="38.4375"
+ x2="48.982567"
+ y1="36.460838"
+ x1="48.496433"
+ gradientTransform="translate(-20,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7449"
+ xlink:href="#linearGradient7231"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="44.788391"
+ x2="29.249495"
+ y1="21.108738"
+ x1="26.499495"
+ id="linearGradient7287"
+ xlink:href="#linearGradient7281"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(0,-1)"
+ gradientUnits="userSpaceOnUse"
+ y2="28.203257"
+ x2="23.334524"
+ y1="12.556273"
+ x1="23.334524"
+ id="linearGradient8242"
+ xlink:href="#linearGradient8236"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(-40,0)"
+ gradientUnits="userSpaceOnUse"
+ y2="5.5714717"
+ x2="71.739273"
+ y1="2.2823277"
+ x1="71.739273"
+ id="linearGradient8222"
+ xlink:href="#linearGradient8216"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.32813,0,0,7.00602,-61.1646,-173.012)"
+ r="10.5"
+ fy="29.797501"
+ fx="64.5"
+ cy="29.797501"
+ cx="64.5"
+ id="radialGradient8054"
+ xlink:href="#linearGradient8046"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(1,0,0,-1,-39,83.0585)"
+ gradientUnits="userSpaceOnUse"
+ y2="41"
+ x2="64.5"
+ y1="42.625"
+ x1="64.5625"
+ id="linearGradient8010"
+ xlink:href="#linearGradient8012"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(1,0,0,-1,-39,83.0585)"
+ gradientUnits="userSpaceOnUse"
+ y2="41"
+ x2="64.5"
+ y1="42.625"
+ x1="64.5625"
+ id="linearGradient8006"
+ xlink:href="#linearGradient8000"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(-89,-1)"
+ gradientUnits="userSpaceOnUse"
+ y2="23.438053"
+ x2="64.375"
+ y1="9.3125"
+ x1="64.375"
+ id="linearGradient7998"
+ xlink:href="#linearGradient7992"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(-40,-1)"
+ gradientUnits="userSpaceOnUse"
+ y2="10.6875"
+ x2="65.4375"
+ y1="19.690521"
+ x1="65.4375"
+ id="linearGradient7978"
+ xlink:href="#linearGradient7972"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(-40,0)"
+ gradientUnits="userSpaceOnUse"
+ y2="92.265244"
+ x2="87.042259"
+ y1="8.375"
+ x1="59.510406"
+ id="linearGradient7923"
+ xlink:href="#linearGradient7917"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient7917"
+ inkscape:collect="always">
+ <stop
+ id="stop7919"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop7921"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7972">
+ <stop
+ id="stop7974"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop7976"
+ offset="1"
+ style="stop-color: rgb(238, 238, 236); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7992">
+ <stop
+ id="stop7994"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop7996"
+ offset="1"
+ style="stop-color: rgb(211, 215, 207); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8000"
+ inkscape:collect="always">
+ <stop
+ id="stop8002"
+ offset="0"
+ style="stop-color: rgb(46, 52, 54); stop-opacity: 1;" />
+ <stop
+ id="stop8004"
+ offset="1"
+ style="stop-color: rgb(136, 138, 133); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8012">
+ <stop
+ style="stop-color: rgb(46, 52, 54); stop-opacity: 1;"
+ offset="0"
+ id="stop8014" />
+ <stop
+ style="stop-color: rgb(136, 138, 133); stop-opacity: 1;"
+ offset="1"
+ id="stop8016" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8046">
+ <stop
+ id="stop8048"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop8050"
+ offset="1"
+ style="stop-color: rgb(136, 138, 133); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8216">
+ <stop
+ id="stop8218"
+ offset="0"
+ style="stop-color: rgb(136, 138, 133); stop-opacity: 1;" />
+ <stop
+ id="stop8220"
+ offset="1"
+ style="stop-color: rgb(186, 189, 182); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8236"
+ inkscape:collect="always">
+ <stop
+ id="stop8238"
+ offset="0"
+ style="stop-color: rgb(0, 0, 0); stop-opacity: 1;" />
+ <stop
+ id="stop8240"
+ offset="1"
+ style="stop-color: rgb(0, 0, 0); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8357">
+ <stop
+ id="stop8359"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop8361"
+ offset="1"
+ style="stop-color: rgb(136, 138, 133); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7199"
+ inkscape:collect="always">
+ <stop
+ id="stop7201"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop7203"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7215"
+ inkscape:collect="always">
+ <stop
+ id="stop7217"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop7219"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7223"
+ inkscape:collect="always">
+ <stop
+ id="stop7225"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop7227"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7231"
+ inkscape:collect="always">
+ <stop
+ id="stop7233"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop7235"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7281">
+ <stop
+ id="stop7283"
+ offset="0"
+ style="stop-color: rgb(46, 52, 54); stop-opacity: 1;" />
+ <stop
+ id="stop7285"
+ offset="1"
+ style="stop-color: rgb(136, 138, 133); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7526"
+ inkscape:collect="always">
+ <stop
+ id="stop7528"
+ offset="0"
+ style="stop-color: rgb(136, 138, 133); stop-opacity: 1;" />
+ <stop
+ id="stop7530"
+ offset="1"
+ style="stop-color: rgb(211, 215, 207); stop-opacity: 0.498039;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7088"
+ inkscape:collect="always">
+ <stop
+ id="stop7090"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop7092"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3042">
+ <stop
+ style="stop-color: black; stop-opacity: 0;"
+ offset="0"
+ id="stop3044" />
+ <stop
+ id="stop3050-0"
+ offset="0.5"
+ style="stop-color: black; stop-opacity: 1;" />
+ <stop
+ style="stop-color: black; stop-opacity: 0;"
+ offset="1"
+ id="stop3046" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3028">
+ <stop
+ style="stop-color: black; stop-opacity: 1;"
+ offset="0"
+ id="stop3030" />
+ <stop
+ style="stop-color: black; stop-opacity: 0;"
+ offset="1"
+ id="stop3032" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient1558">
+ <stop
+ style="stop-color: rgb(186, 189, 182);"
+ offset="0"
+ id="stop1560" />
+ <stop
+ style="stop-color: rgb(238, 238, 236);"
+ offset="1"
+ id="stop1562" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient11400">
+ <stop
+ id="stop11402"
+ offset="0"
+ style="stop-color: rgb(0, 0, 0); stop-opacity: 1;" />
+ <stop
+ id="stop11404"
+ offset="1"
+ style="stop-color: rgb(0, 0, 0); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6240"
+ inkscape:collect="always">
+ <stop
+ id="stop6242"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop6244"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5137">
+ <stop
+ id="stop5139"
+ offset="0"
+ style="stop-color: rgb(238, 238, 236); stop-opacity: 1;" />
+ <stop
+ id="stop5141"
+ offset="1"
+ style="stop-color: rgb(230, 230, 227); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5225"
+ inkscape:collect="always">
+ <stop
+ id="stop5227"
+ offset="0"
+ style="stop-color: black; stop-opacity: 1;" />
+ <stop
+ id="stop5229"
+ offset="1"
+ style="stop-color: black; stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5233">
+ <stop
+ id="stop5235"
+ offset="0"
+ style="stop-color: rgb(114, 159, 207); stop-opacity: 1;" />
+ <stop
+ id="stop5237"
+ offset="1"
+ style="stop-color: rgb(50, 97, 148); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3899"
+ inkscape:collect="always">
+ <stop
+ id="stop3901"
+ offset="0"
+ style="stop-color: rgb(238, 238, 236);" />
+ <stop
+ id="stop3903"
+ offset="1"
+ style="stop-color: rgb(211, 215, 207);" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3907">
+ <stop
+ id="stop3909"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop3911"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4196">
+ <stop
+ id="stop4198"
+ offset="0"
+ style="stop-color: black; stop-opacity: 1;" />
+ <stop
+ id="stop4200"
+ offset="1"
+ style="stop-color: black; stop-opacity: 0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5225"
+ id="radialGradient5236"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.24763,0,32.1168)"
+ cx="23.9375"
+ cy="42.6875"
+ fx="23.9375"
+ fy="42.6875"
+ r="23.75956" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4196"
+ id="linearGradient5238"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(24,0)"
+ x1="37.484837"
+ y1="38.267769"
+ x2="37.295498"
+ y2="33.637787" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5137"
+ id="linearGradient5240"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.992781,0,-2.71803)"
+ x1="31.743324"
+ y1="37.842293"
+ x2="31.86105"
+ y2="43.82579" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient11400"
+ id="linearGradient5242"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.00419,0,0,1,-0.12454,-3.01177)"
+ x1="23.154902"
+ y1="34.572548"
+ x2="23.529411"
+ y2="40.219608" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5137"
+ id="linearGradient5244"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.999303,0,0,0.998527,0.00306125,-2.97132)"
+ x1="17.247635"
+ y1="6.3760414"
+ x2="39.904388"
+ y2="38.876041" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5233"
+ id="radialGradient5246"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.23263,0,0,0.778392,-5.59058,-0.847446)"
+ cx="24.006104"
+ cy="32.997028"
+ fx="24.006104"
+ fy="32.997028"
+ r="19.00016" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6240"
+ id="linearGradient5248"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-0.0235294,-3.03922)"
+ x1="20.156862"
+ y1="5.0996137"
+ x2="20.156862"
+ y2="26.039215" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3028"
+ id="radialGradient5250"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.750002,1.33333,0,-40.2857,35)"
+ cx="2.9999995"
+ cy="33.214287"
+ fx="2.9999995"
+ fy="33.214287"
+ r="3" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3028"
+ id="radialGradient5252"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0,-0.750002,1.33333,0,-88.2857,-30.5)"
+ cx="2.9999995"
+ cy="33.214287"
+ fx="2.9999995"
+ fy="33.214287"
+ r="3" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3042"
+ id="linearGradient5254"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.888889,0,3.83333)"
+ x1="37.03125"
+ y1="35.062885"
+ x2="37.03125"
+ y2="29.995127" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3899"
+ id="linearGradient5256"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.753044,-48,12.2525)"
+ x1="26.5"
+ y1="43.249905"
+ x2="26.5"
+ y2="35.75" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1558"
+ id="linearGradient5258"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.833169,-48,19.0825)"
+ x1="16.396038"
+ y1="19.659277"
+ x2="16.396038"
+ y2="32.448051" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5260"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5262"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5264"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5266"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5268"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5270"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5272"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5274"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5280"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5282"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5284"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5286"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5288"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5290"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5292"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5294"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5296"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5298"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5300"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5302"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5304"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5306"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5308"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5310"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5312"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5314"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5316"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5318"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5320"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5322"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5324"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5326"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5328"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5330"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5332"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5334"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5336"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5338"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5340"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5342"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5344"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5346"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5348"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5350"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5352"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5354"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5356"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5358"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5360"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5362"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5364"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5366"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5368"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5370"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5372"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5374"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5376"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5378"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3907"
+ id="radialGradient5380"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.3826,3.5814e-5,0,0.171503,-6.72968,34.0972)"
+ cx="20.913568"
+ cy="47.045319"
+ fx="20.913568"
+ fy="47.045319"
+ r="19.5" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="10.934953"
+ x2="39.421204"
+ y1="28.5"
+ x1="39.06765"
+ id="linearGradient6985"
+ xlink:href="#linearGradient6979"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="21.041553"
+ x2="21.036427"
+ y1="44.528019"
+ x1="24.837126"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient7121"
+ xlink:href="#linearGradient7101"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient7101">
+ <stop
+ style="stop-color: rgb(186, 189, 182); stop-opacity: 1;"
+ offset="0"
+ id="stop7103" />
+ <stop
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"
+ offset="1"
+ id="stop7105" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6979">
+ <stop
+ id="stop6981"
+ offset="0"
+ style="stop-color: rgb(136, 138, 133); stop-opacity: 1;" />
+ <stop
+ id="stop6983"
+ offset="1"
+ style="stop-color: rgb(85, 87, 83); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="40.441154"
+ x2="21.8125"
+ y1="13.249833"
+ x1="21.8125"
+ id="linearGradient2960"
+ xlink:href="#linearGradient2954"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="29.010038"
+ x2="17.5625"
+ y1="20.996099"
+ x1="17.5625"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4074"
+ xlink:href="#linearGradient4055"
+ inkscape:collect="always" />
+ <radialGradient
+ r="2"
+ fy="26"
+ fx="13.006094"
+ cy="26"
+ cx="13.006094"
+ gradientTransform="matrix(-9.45807e-7,-2.00001,2.00305,-1.68422e-6,-86.5731,1.01229)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient4072"
+ xlink:href="#linearGradient4033"
+ inkscape:collect="always" />
+ <radialGradient
+ r="2"
+ fy="26"
+ fx="13.006094"
+ cy="26"
+ cx="13.006094"
+ gradientTransform="matrix(-9.45807e-7,-2.00001,2.00305,-1.68422e-6,-38.5731,51.0123)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient4070"
+ xlink:href="#linearGradient4033"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.96731,-1.03151e-7,0,-1.13646,83.2333,33.6702)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3017"
+ xlink:href="#linearGradient6256"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.96731,-1.03151e-7,0,-1.13646,88.3242,33.6702)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3013"
+ xlink:href="#linearGradient6256"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.96731,-1.03151e-7,0,-1.13646,93.4151,33.6702)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3009"
+ xlink:href="#linearGradient6256"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.75536,-1.03151e-7,0,-1.13646,79.0024,30.6702)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3002"
+ xlink:href="#linearGradient6256"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.75536,-1.03151e-7,0,-1.13646,83.7296,30.6702)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2998"
+ xlink:href="#linearGradient6256"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.75536,-1.03151e-7,0,-1.13646,88.4569,30.6702)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2994"
+ xlink:href="#linearGradient6256"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.54341,-1.03151e-7,0,-1.13646,74.7714,27.6702)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2987"
+ xlink:href="#linearGradient6256"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.54341,-1.03151e-7,0,-1.13646,79.135,27.6702)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2983"
+ xlink:href="#linearGradient6256"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.54341,-1.03151e-7,0,-1.13646,83.4987,27.6702)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2979"
+ xlink:href="#linearGradient6256"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.33146,-1.03151e-7,0,-1.13646,78.5405,24.6702)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2972"
+ xlink:href="#linearGradient6256"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.33146,-1.03151e-7,0,-1.13646,74.5405,24.6702)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2968"
+ xlink:href="#linearGradient6256"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.33146,-1.03151e-7,0,-1.13646,70.5405,24.6702)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient6264"
+ xlink:href="#linearGradient6256"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.72079,-0.0389865,0.00176461,0.123227,-33.0387,12.786)"
+ r="16.031172"
+ fy="3.5110793"
+ fx="16.030262"
+ cy="3.5110793"
+ cx="16.030262"
+ id="radialGradient4068"
+ xlink:href="#linearGradient4062"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.04444,-0.123888,0.0146767,0.242354,-19.8863,13.6194)"
+ r="16.994591"
+ fy="6.5931005"
+ fx="17.04607"
+ cy="6.5931005"
+ cx="17.04607"
+ id="radialGradient4024"
+ xlink:href="#linearGradient4038"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="18.257809"
+ x2="23.994669"
+ y1="13.842071"
+ x1="23.994669"
+ id="linearGradient3404"
+ xlink:href="#linearGradient4044"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(1.00031,0,0,1,-0.00361429,0.972209)"
+ y2="20.639368"
+ x2="28.260429"
+ y1="8.7648172"
+ x1="28.260429"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1616"
+ xlink:href="#linearGradient4044"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="29.477005"
+ x2="24.414724"
+ y1="25.463402"
+ x1="24.414724"
+ gradientTransform="matrix(1.00031,0,0,1,0.00705191,-4.00001)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1614"
+ xlink:href="#linearGradient4038"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="17.53454"
+ x2="25.189993"
+ y1="24.504593"
+ x1="24.160858"
+ gradientTransform="matrix(-1.00031,0,0,1,48.0127,-4.00001)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1601"
+ xlink:href="#linearGradient2513"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="8.361702"
+ x2="24.010672"
+ y1="24.81731"
+ x1="24.834204"
+ gradientTransform="matrix(0.921903,0,0,0.877945,1.86967,-1.02471)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1598"
+ xlink:href="#linearGradient4070"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2513">
+ <stop
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"
+ offset="0"
+ id="stop2515" />
+ <stop
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0.217899;"
+ offset="1"
+ id="stop2517" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4038">
+ <stop
+ style="stop-color: rgb(114, 159, 207); stop-opacity: 1;"
+ offset="0"
+ id="stop4040" />
+ <stop
+ style="stop-color: rgb(52, 101, 164); stop-opacity: 1;"
+ offset="1"
+ id="stop4042" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4044">
+ <stop
+ id="stop4046"
+ offset="0"
+ style="stop-color: rgb(52, 101, 164); stop-opacity: 1;" />
+ <stop
+ id="stop4048"
+ offset="1"
+ style="stop-color: rgb(32, 74, 135); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4062">
+ <stop
+ id="stop4064"
+ offset="0"
+ style="stop-color: white; stop-opacity: 1;" />
+ <stop
+ id="stop4066"
+ offset="1"
+ style="stop-color: white; stop-opacity: 0.297619;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4070">
+ <stop
+ style="stop-color: white; stop-opacity: 0.428571;"
+ offset="0"
+ id="stop4072" />
+ <stop
+ style="stop-color: white; stop-opacity: 1;"
+ offset="1"
+ id="stop4074" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6256">
+ <stop
+ style="stop-color: white; stop-opacity: 1;"
+ offset="0"
+ id="stop6258" />
+ <stop
+ style="stop-color: rgb(204, 206, 201); stop-opacity: 1;"
+ offset="1"
+ id="stop6260" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4033"
+ inkscape:collect="always">
+ <stop
+ id="stop4035"
+ offset="0"
+ style="stop-color: black; stop-opacity: 1;" />
+ <stop
+ id="stop4037"
+ offset="1"
+ style="stop-color: black; stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4055">
+ <stop
+ id="stop4057"
+ offset="0"
+ style="stop-color: black; stop-opacity: 0;" />
+ <stop
+ style="stop-color: black; stop-opacity: 1;"
+ offset="0.5"
+ id="stop4063" />
+ <stop
+ id="stop4059"
+ offset="1"
+ style="stop-color: black; stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4961">
+ <stop
+ id="stop4963"
+ offset="0"
+ style="stop-color: rgb(85, 87, 83); stop-opacity: 1;" />
+ <stop
+ id="stop4965"
+ offset="1"
+ style="stop-color: rgb(186, 189, 182); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2954"
+ inkscape:collect="always">
+ <stop
+ id="stop2956"
+ offset="0"
+ style="stop-color: rgb(52, 101, 164); stop-opacity: 1;" />
+ <stop
+ id="stop2958"
+ offset="1"
+ style="stop-color: rgb(52, 101, 164); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient6299"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient6301"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient6303"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient6305"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient6307"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient6309"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient6311"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient6313"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient6315"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient6317"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient6319"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient6321"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ id="linearGradient5048">
+ <stop
+ id="stop5050"
+ offset="0"
+ style="stop-color: black; stop-opacity: 0;" />
+ <stop
+ style="stop-color: black; stop-opacity: 1;"
+ offset="0.5"
+ id="stop5056" />
+ <stop
+ id="stop5052"
+ offset="1"
+ style="stop-color: black; stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5060"
+ inkscape:collect="always">
+ <stop
+ id="stop5062"
+ offset="0"
+ style="stop-color: black; stop-opacity: 1;" />
+ <stop
+ id="stop5064"
+ offset="1"
+ style="stop-color: black; stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient6499">
+ <stop
+ style="stop-color: rgb(114, 159, 207); stop-opacity: 1;"
+ offset="0"
+ id="stop6501" />
+ <stop
+ style="stop-color: rgb(52, 101, 164); stop-opacity: 1;"
+ offset="1"
+ id="stop6503" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6642"
+ inkscape:collect="always">
+ <stop
+ id="stop6644"
+ offset="0"
+ style="stop-color: rgb(211, 215, 207); stop-opacity: 1;" />
+ <stop
+ id="stop6646"
+ offset="1"
+ style="stop-color: rgb(136, 138, 133); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6794"
+ inkscape:collect="always">
+ <stop
+ id="stop6796"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop6798"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6820"
+ inkscape:collect="always">
+ <stop
+ id="stop6822"
+ offset="0"
+ style="stop-color: rgb(114, 159, 207); stop-opacity: 1;" />
+ <stop
+ id="stop6824"
+ offset="1"
+ style="stop-color: rgb(114, 159, 207); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6843"
+ inkscape:collect="always">
+ <stop
+ id="stop6845"
+ offset="0"
+ style="stop-color: rgb(254, 192, 101); stop-opacity: 1;" />
+ <stop
+ id="stop6847"
+ offset="1"
+ style="stop-color: rgb(252, 175, 62); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6851"
+ inkscape:collect="always">
+ <stop
+ id="stop6853"
+ offset="0"
+ style="stop-color: rgb(253, 238, 119); stop-opacity: 1;" />
+ <stop
+ id="stop6855"
+ offset="1"
+ style="stop-color: rgb(252, 233, 79); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6859"
+ inkscape:collect="always">
+ <stop
+ id="stop6861"
+ offset="0"
+ style="stop-color: rgb(158, 231, 87); stop-opacity: 1;" />
+ <stop
+ id="stop6863"
+ offset="1"
+ style="stop-color: rgb(138, 226, 52); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6881"
+ inkscape:collect="always">
+ <stop
+ id="stop6883"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop6885"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8918">
+ <stop
+ id="stop8920"
+ offset="0"
+ style="stop-color: rgb(206, 225, 75);" />
+ <stop
+ id="stop8922"
+ offset="1"
+ style="stop-color: rgb(157, 176, 41);" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8912">
+ <stop
+ style="stop-color: rgb(206, 225, 75);"
+ offset="0"
+ id="stop8914" />
+ <stop
+ style="stop-color: rgb(157, 176, 41);"
+ offset="1"
+ id="stop8916" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8930">
+ <stop
+ id="stop8932"
+ offset="0"
+ style="stop-color: rgb(206, 225, 75);" />
+ <stop
+ id="stop8934"
+ offset="1"
+ style="stop-color: rgb(157, 176, 41);" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8924">
+ <stop
+ id="stop8926"
+ offset="0"
+ style="stop-color: rgb(206, 225, 75);" />
+ <stop
+ id="stop8928"
+ offset="1"
+ style="stop-color: rgb(157, 176, 41);" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8740">
+ <stop
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"
+ offset="0"
+ id="stop8742" />
+ <stop
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;"
+ offset="1"
+ id="stop8744" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient8647">
+ <stop
+ style="stop-color: rgb(143, 177, 220); stop-opacity: 1;"
+ offset="0"
+ id="stop8649" />
+ <stop
+ style="stop-color: rgb(52, 101, 164); stop-opacity: 1;"
+ offset="1"
+ id="stop8651" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8838">
+ <stop
+ style="stop-color: rgb(0, 0, 0); stop-opacity: 1;"
+ offset="0"
+ id="stop8840" />
+ <stop
+ style="stop-color: rgb(0, 0, 0); stop-opacity: 0;"
+ offset="1"
+ id="stop8842" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4873"
+ inkscape:collect="always">
+ <stop
+ id="stop4875"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop4877"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8838"
+ id="radialGradient7184"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.341176,0,3.04706)"
+ cx="62.625"
+ cy="4.625"
+ fx="62.625"
+ fy="4.625"
+ r="10.625" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8647"
+ id="radialGradient7186"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.12235,0,0,1.12238,-7.61047,1.06772)"
+ cx="62.200352"
+ cy="-8.7256308"
+ fx="62.200352"
+ fy="-8.7256308"
+ r="9.7552834" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4873"
+ id="linearGradient7188"
+ gradientUnits="userSpaceOnUse"
+ x1="63.397362"
+ y1="-9.3832779"
+ x2="68.910904"
+ y2="16.839214" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient7194"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient7202"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient7208"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient7216"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient7224"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,0.79739)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient7230"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8924"
+ id="radialGradient7254"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.0682288,2.45967,-1.7549,0.0486843,55.1288,-46.8219)"
+ cx="24.652573"
+ cy="18.94449"
+ fx="24.652485"
+ fy="18.944481"
+ r="8.6174498" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient7256"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.891018,0,0,0.828854,1.57952,2.39052)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8930"
+ id="radialGradient7262"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.159592,5.75333,-0.8072,0.0223703,32.8731,-130.867)"
+ cx="25.135374"
+ cy="14.542349"
+ fx="25.135332"
+ fy="14.542329"
+ r="4.1347499" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient7264"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,0.589884)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8912"
+ id="radialGradient7270"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.222034,8.00438,-0.597156,0.0165609,29.8566,-181.6)"
+ cx="24.478569"
+ cy="17.573915"
+ fx="24.478539"
+ fy="17.573889"
+ r="2.9719501" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient7272"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0.311259,0.486131)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8918"
+ id="radialGradient7278"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.0616815,2.22364,-1.49597,0.0414803,50.5112,-44.5084)"
+ cx="25.969097"
+ cy="17.257854"
+ fx="25.968998"
+ fy="17.257843"
+ r="9.8222504" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient7280"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.918134,0,0,0.854079,2.42976,1.4901)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8838"
+ id="radialGradient8513"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.341176,0,3.04706)"
+ cx="62.625"
+ cy="4.625"
+ fx="62.625"
+ fy="4.625"
+ r="10.625" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8647"
+ id="radialGradient8515"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.12235,0,0,1.12238,-7.61047,1.06772)"
+ cx="62.200352"
+ cy="-8.7256308"
+ fx="62.200352"
+ fy="-8.7256308"
+ r="9.7552834" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4873"
+ id="linearGradient8517"
+ gradientUnits="userSpaceOnUse"
+ x1="63.397362"
+ y1="-9.3832779"
+ x2="68.910904"
+ y2="16.839214" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8519"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8521"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8523"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8525"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8527"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8529"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8531"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8533"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8535"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8537"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8539"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8541"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8543"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8545"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8547"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8549"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8551"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8553"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,0.79739)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8555"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8557"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8559"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8561"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8563"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8565"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8567"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8569"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8571"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8573"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8575"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8577"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8579"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8581"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8924"
+ id="radialGradient8583"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.0682288,2.45967,-1.7549,0.0486843,55.1288,-46.8219)"
+ cx="24.652573"
+ cy="18.94449"
+ fx="24.652485"
+ fy="18.944481"
+ r="8.6174498" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8585"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.891018,0,0,0.828854,1.57952,2.39052)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8924"
+ id="radialGradient8587"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.0765739,2.76052,-1.96955,0.0546389,60.099,-55.4718)"
+ cx="24.652573"
+ cy="18.94449"
+ fx="24.652485"
+ fy="18.944481"
+ r="8.6174498" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8589"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8930"
+ id="radialGradient8591"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.159592,5.75333,-0.8072,0.0223703,32.8731,-130.867)"
+ cx="25.135374"
+ cy="14.542349"
+ fx="25.135332"
+ fy="14.542329"
+ r="4.1347499" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8593"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,0.589884)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8930"
+ id="radialGradient8595"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.159592,5.75333,-0.8072,0.0223703,32.8731,-131.697)"
+ cx="25.135374"
+ cy="14.542349"
+ fx="25.135332"
+ fy="14.542329"
+ r="4.1347499" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8597"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8912"
+ id="radialGradient8599"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.222034,8.00438,-0.597156,0.0165609,29.8566,-181.6)"
+ cx="24.478569"
+ cy="17.573915"
+ fx="24.478539"
+ fy="17.573889"
+ r="2.9719501" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8601"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0.311259,0.486131)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8912"
+ id="radialGradient8603"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.222034,8.00438,-0.597156,0.0165609,29.5454,-182.327)"
+ cx="24.478569"
+ cy="17.573915"
+ fx="24.478539"
+ fy="17.573889"
+ r="2.9719501" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8605"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8918"
+ id="radialGradient8607"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.0616815,2.22364,-1.49597,0.0414803,50.5112,-44.5084)"
+ cx="25.969097"
+ cy="17.257854"
+ fx="25.968998"
+ fy="17.257843"
+ r="9.8222504" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8609"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.918134,0,0,0.854079,2.42976,1.4901)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8918"
+ id="radialGradient8611"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.0671814,2.42191,-1.62936,0.0451789,52.3687,-50.3401)"
+ cx="25.969097"
+ cy="17.257854"
+ fx="25.968998"
+ fy="17.257843"
+ r="9.8222504" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient8613"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961"
+ id="linearGradient9568"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9570"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9572"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9574"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9576"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9578"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9580"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9582"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9584"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9586"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9588"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9590"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9592"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9594"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9596"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9598"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9600"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9602"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9604"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9606"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9608"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9610"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9612"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9614"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9616"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9618"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9620"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8924"
+ id="radialGradient9622"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.0765739,2.76052,-1.96955,0.0546389,60.099,-55.4718)"
+ cx="24.652573"
+ cy="18.94449"
+ fx="24.652485"
+ fy="18.944481"
+ r="8.6174498" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9624"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8930"
+ id="radialGradient9626"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.159592,5.75333,-0.8072,0.0223703,32.8731,-131.697)"
+ cx="25.135374"
+ cy="14.542349"
+ fx="25.135332"
+ fy="14.542329"
+ r="4.1347499" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9628"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8912"
+ id="radialGradient9630"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.222034,8.00438,-0.597156,0.0165609,29.5454,-182.327)"
+ cx="24.478569"
+ cy="17.573915"
+ fx="24.478539"
+ fy="17.573889"
+ r="2.9719501" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9632"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8918"
+ id="radialGradient9634"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.0671814,2.42191,-1.62936,0.0451789,52.3687,-50.3401)"
+ cx="25.969097"
+ cy="17.257854"
+ fx="25.968998"
+ fy="17.257843"
+ r="9.8222504" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8740"
+ id="radialGradient9636"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.930233,0,-0.240141)"
+ cx="62.225391"
+ cy="-3.4420195"
+ fx="62.225391"
+ fy="-3.4420195"
+ r="10.081216" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5048"
+ id="linearGradient9874"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.77439,0,0,1.96971,-1892.18,-872.885)"
+ x1="302.85715"
+ y1="366.64789"
+ x2="302.85715"
+ y2="609.50507" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient9876"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.77439,0,0,1.96971,-1891.63,-872.885)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060"
+ id="radialGradient9878"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-2.77439,0,0,1.96971,112.762,-872.885)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6642"
+ id="radialGradient9880"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.32797,0,-0.467771,1.60701,3.48927,-5.75381)"
+ cx="4.4339509"
+ cy="8.3226004"
+ fx="4.4339509"
+ fy="8.3226004"
+ r="6" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6642"
+ id="radialGradient9882"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.32797,0,-0.467771,1.60701,3.48927,-5.75381)"
+ cx="4.4339509"
+ cy="8.3226004"
+ fx="4.4339509"
+ fy="8.3226004"
+ r="6" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6642"
+ id="radialGradient9884"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.32797,0,-0.467771,1.60701,3.48927,-5.75381)"
+ cx="4.4339509"
+ cy="8.3226004"
+ fx="4.4339509"
+ fy="8.3226004"
+ r="6" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6642"
+ id="radialGradient9886"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.32797,0,-0.467771,1.60701,3.48927,-5.75381)"
+ cx="4.4339509"
+ cy="8.3226004"
+ fx="4.4339509"
+ fy="8.3226004"
+ r="6" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6642"
+ id="radialGradient9888"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.32797,0,-0.467771,1.60701,3.48927,-5.75381)"
+ cx="4.4339509"
+ cy="8.3226004"
+ fx="4.4339509"
+ fy="8.3226004"
+ r="6" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6642"
+ id="radialGradient9890"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.32797,0,-0.467771,1.60701,3.48927,-5.75381)"
+ cx="4.4339509"
+ cy="8.3226004"
+ fx="4.4339509"
+ fy="8.3226004"
+ r="6" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6859"
+ id="radialGradient9892"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.786718,0,0,1.44232,-51.0422,-5.89968)"
+ cx="42"
+ cy="15.814279"
+ fx="42"
+ fy="15.814279"
+ r="3" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6794"
+ id="linearGradient9894"
+ gradientUnits="userSpaceOnUse"
+ x1="42.875"
+ y1="30.9375"
+ x2="39.919209"
+ y2="51.062393" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6851"
+ id="radialGradient9896"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.821325,0,0,1.00384,-52.3505,0.173875)"
+ cx="42.8125"
+ cy="25.727272"
+ fx="42.8125"
+ fy="25.727272"
+ r="4.5" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6843"
+ id="radialGradient9898"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.745238,0,0,0.910847,-49.1726,3.63873)"
+ cx="42.5"
+ cy="36.307945"
+ fx="42.5"
+ fy="36.307945"
+ r="4.5" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6794"
+ id="linearGradient9900"
+ gradientUnits="userSpaceOnUse"
+ x1="42.875"
+ y1="30.9375"
+ x2="39.919209"
+ y2="51.062393" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6794"
+ id="linearGradient9902"
+ gradientUnits="userSpaceOnUse"
+ x1="42.875"
+ y1="30.9375"
+ x2="39.919209"
+ y2="51.062393" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6499"
+ id="linearGradient9904"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.88856,0,0,1,-55.4867,0)"
+ x1="17.077137"
+ y1="14.375"
+ x2="41.06271"
+ y2="56.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6820"
+ id="linearGradient9906"
+ gradientUnits="userSpaceOnUse"
+ x1="24.75"
+ y1="43.927441"
+ x2="24.75"
+ y2="35.790096" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6881"
+ id="linearGradient9908"
+ gradientUnits="userSpaceOnUse"
+ x1="17.353554"
+ y1="7.9356604"
+ x2="28.035534"
+ y2="81.759773" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6642"
+ id="radialGradient9910"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.52618,0,0,1.40054,-2.79535,-3.40699)"
+ cx="5.312501"
+ cy="8.1713457"
+ fx="5.312501"
+ fy="8.1713457"
+ r="6" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6642"
+ id="radialGradient9912"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.52618,0,0,1.40054,-2.79535,-3.40699)"
+ cx="5.312501"
+ cy="8.1713457"
+ fx="5.312501"
+ fy="8.1713457"
+ r="6" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6642"
+ id="radialGradient9914"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.52618,0,0,1.40054,-2.79535,-3.40699)"
+ cx="5.312501"
+ cy="8.1713457"
+ fx="5.312501"
+ fy="8.1713457"
+ r="6" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6642"
+ id="radialGradient9916"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.52618,0,0,1.40054,-2.79535,-3.40699)"
+ cx="5.312501"
+ cy="8.1713457"
+ fx="5.312501"
+ fy="8.1713457"
+ r="6" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6642"
+ id="radialGradient9918"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.52618,0,0,1.40054,-2.79535,-3.40699)"
+ cx="5.312501"
+ cy="8.1713457"
+ fx="5.312501"
+ fy="8.1713457"
+ r="6" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6642"
+ id="radialGradient9920"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.52618,0,0,1.40054,-2.79535,-3.40699)"
+ cx="5.312501"
+ cy="8.1713457"
+ fx="5.312501"
+ fy="8.1713457"
+ r="6" />
+ <linearGradient
+ id="linearGradient3276-4-9">
+ <stop
+ id="stop3278-5-0"
+ offset="0"
+ style="stop-color: rgb(175, 207, 255); stop-opacity: 1;" />
+ <stop
+ id="stop3280-4-7"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3284-2-9">
+ <stop
+ id="stop3286-2-3"
+ offset="0"
+ style="stop-color: rgb(255, 212, 42); stop-opacity: 1;" />
+ <stop
+ id="stop3288-4-3"
+ offset="1"
+ style="stop-color: rgb(255, 241, 163); stop-opacity: 1;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3276-4-9"
+ id="linearGradient4274"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-1,0,0,1,1054.98,9.00005)"
+ x1="298.49658"
+ y1="540.21155"
+ x2="625.77783"
+ y2="540.21155" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3284-2-9"
+ id="linearGradient4276"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6.70711,9)"
+ x1="474.26663"
+ y1="483.6463"
+ x2="573.2616"
+ y2="589.20721" />
+ <linearGradient
+ y2="31.250401"
+ x2="57.49662"
+ y1="38.277283"
+ x1="57.49662"
+ gradientTransform="translate(10,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2351"
+ xlink:href="#linearGradient4241"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="31.250401"
+ x2="57.49662"
+ y1="38.277283"
+ x1="57.49662"
+ gradientTransform="translate(8,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2349"
+ xlink:href="#linearGradient4241"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="31.250401"
+ x2="57.49662"
+ y1="38.277283"
+ x1="57.49662"
+ gradientTransform="translate(6,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2347"
+ xlink:href="#linearGradient4241"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="31.250401"
+ x2="57.49662"
+ y1="38.277283"
+ x1="57.49662"
+ gradientTransform="translate(4,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2345"
+ xlink:href="#linearGradient4241"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="31.250401"
+ x2="57.49662"
+ y1="38.277283"
+ x1="57.49662"
+ gradientTransform="translate(2,0)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2343"
+ xlink:href="#linearGradient4241"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="31.250401"
+ x2="57.49662"
+ y1="38.277283"
+ x1="57.49662"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2341"
+ xlink:href="#linearGradient4241"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(-40,-1)"
+ y2="6.5458651"
+ x2="53.61911"
+ y1="6.5458651"
+ x1="73.05397"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2339"
+ xlink:href="#linearGradient3859"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(-40,-1)"
+ y2="72.082878"
+ x2="60.426777"
+ y1="18.520107"
+ x1="60.426777"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2335"
+ xlink:href="#linearGradient4175"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="10.868282"
+ x2="24.92893"
+ y1="12.001067"
+ x1="24.92893"
+ gradientTransform="matrix(0.882353,0,0,1,2.70589,1)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2332"
+ xlink:href="#linearGradient4233"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="17.762573"
+ x2="24.92893"
+ y1="19.00001"
+ x1="24.960155"
+ gradientTransform="matrix(0.882353,0,0,1,2.70589,1)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2329"
+ xlink:href="#linearGradient4227"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.374992"
+ x2="12.500004"
+ y1="32.593761"
+ x1="10.249995"
+ gradientTransform="matrix(0.999998,0,0,1.000003,6.00003,-7.000134)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2325"
+ xlink:href="#linearGradient2833"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(-40,-1)"
+ y2="37.256325"
+ x2="53.5625"
+ y1="4.4916701"
+ x1="53.5625"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2319"
+ xlink:href="#linearGradient3942"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient2809">
+ <stop
+ style="stop-color:#d3d7cf;stop-opacity:1;"
+ offset="0"
+ id="stop2811" />
+ <stop
+ style="stop-color:#eeeeec;stop-opacity:0;"
+ offset="1"
+ id="stop2813" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3942">
+ <stop
+ id="stop3944"
+ offset="0"
+ style="stop-color:#888a85;stop-opacity:1" />
+ <stop
+ id="stop3946"
+ offset="1"
+ style="stop-color:#eeeeec;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3859">
+ <stop
+ id="stop3861"
+ offset="0"
+ style="stop-color:#d3d7cf;stop-opacity:1" />
+ <stop
+ id="stop3037"
+ offset="0.30973485"
+ style="stop-color:#eeeeec;stop-opacity:1;" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0.88648254"
+ id="stop3039" />
+ <stop
+ id="stop3863"
+ offset="1"
+ style="stop-color:#d3d7cf;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ y2="24.500002"
+ x2="0.055013988"
+ y1="24.500002"
+ x1="6.5030808"
+ gradientTransform="matrix(-0.909091,0,0,1,46.04546,1.999997)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6849"
+ xlink:href="#linearGradient4391"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="27.499998"
+ x2="1.0550151"
+ y1="27.499998"
+ x1="7.5030818"
+ gradientTransform="matrix(-0.909091,0,0,1,46.95455,-0.999999)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6847"
+ xlink:href="#linearGradient2809"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(0.909091,0,0,1,1.954541,1.999997)"
+ gradientUnits="userSpaceOnUse"
+ y2="24.500002"
+ x2="0.055013988"
+ y1="24.500002"
+ x1="6.5030808"
+ id="linearGradient6843-4"
+ xlink:href="#linearGradient6837"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(0.909091,0,0,1,1.045449,-1)"
+ y2="27.499998"
+ x2="1.0550151"
+ y1="27.499998"
+ x1="7.5030818"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6835"
+ xlink:href="#linearGradient2809"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient6837"
+ inkscape:collect="always">
+ <stop
+ id="stop6839"
+ offset="0"
+ style="stop-color:#729fcf;stop-opacity:1" />
+ <stop
+ id="stop6841"
+ offset="1"
+ style="stop-color:#729fcf;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ y2="609.50507"
+ x2="302.85715"
+ y1="366.64789"
+ x1="302.85715"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient6715"
+ xlink:href="#linearGradient5048-1"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient5048-1">
+ <stop
+ id="stop5050-4"
+ offset="0"
+ style="stop-color:black;stop-opacity:0;" />
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0.5"
+ id="stop5056-5" />
+ <stop
+ id="stop5052-0"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ r="117.14286"
+ fy="486.64789"
+ fx="605.71429"
+ cy="486.64789"
+ cx="605.71429"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient6717"
+ xlink:href="#linearGradient5060-8"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient5060-8"
+ inkscape:collect="always">
+ <stop
+ id="stop5062-7"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-5"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ r="117.14286"
+ fy="486.64789"
+ fx="605.71429"
+ cy="486.64789"
+ cx="605.71429"
+ gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient6719"
+ xlink:href="#linearGradient5060-8"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient2833">
+ <stop
+ style="stop-color:#959595;stop-opacity:1;"
+ offset="0"
+ id="stop2835" />
+ <stop
+ style="stop-color:white;stop-opacity:0.85576922;"
+ offset="1"
+ id="stop2837" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4175"
+ inkscape:collect="always">
+ <stop
+ id="stop4177"
+ offset="0"
+ style="stop-color:#d3d7cf;stop-opacity:1" />
+ <stop
+ id="stop4179"
+ offset="1"
+ style="stop-color:#eeeeec;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4227">
+ <stop
+ style="stop-color:#d7d7d7;stop-opacity:1;"
+ offset="0"
+ id="stop4229" />
+ <stop
+ style="stop-color:#eeeeec;stop-opacity:1"
+ offset="1"
+ id="stop4231" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4233">
+ <stop
+ style="stop-color:#d7d7d7;stop-opacity:1;"
+ offset="0"
+ id="stop4235" />
+ <stop
+ style="stop-color:#eeeeec;stop-opacity:1"
+ offset="1"
+ id="stop4237" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4241"
+ inkscape:collect="always">
+ <stop
+ id="stop4243"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop4245"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4391">
+ <stop
+ style="stop-color:#729fcf;stop-opacity:1"
+ offset="0"
+ id="stop4393" />
+ <stop
+ style="stop-color:#729fcf;stop-opacity:0"
+ offset="1"
+ id="stop4395" />
+ </linearGradient>
+ <filter
+ id="filter5406"
+ inkscape:collect="always"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ id="feGaussianBlur5408"
+ stdDeviation="0.78208031"
+ inkscape:collect="always" />
+ </filter>
+ <filter
+ id="filter5386"
+ inkscape:collect="always"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ id="feGaussianBlur5388"
+ stdDeviation="0.26293105"
+ inkscape:collect="always" />
+ </filter>
+ <linearGradient
+ id="linearGradient6991">
+ <stop
+ id="stop6993"
+ offset="0"
+ style="stop-color:#d3d7cf;stop-opacity:1" />
+ <stop
+ id="stop6995"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7186">
+ <stop
+ id="stop7188"
+ offset="0"
+ style="stop-color:#888a85;stop-opacity:1;" />
+ <stop
+ id="stop7190"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7237">
+ <stop
+ id="stop7239"
+ offset="0"
+ style="stop-color:#eeeeec;stop-opacity:1" />
+ <stop
+ id="stop7241"
+ offset="1"
+ style="stop-color:#babdb6;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7245">
+ <stop
+ id="stop7247"
+ offset="0"
+ style="stop-color:#eeeeec;stop-opacity:1;" />
+ <stop
+ id="stop7249"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7257">
+ <stop
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0"
+ id="stop7259" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop7261" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7263">
+ <stop
+ style="stop-color:#adb0a8;stop-opacity:1;"
+ offset="0"
+ id="stop7265" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="1"
+ id="stop7267" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7269">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop7271" />
+ <stop
+ style="stop-color:#d3d7cf;stop-opacity:1"
+ offset="1"
+ id="stop7273" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7277">
+ <stop
+ id="stop7279"
+ offset="0"
+ style="stop-color:#555753;stop-opacity:1" />
+ <stop
+ id="stop7281"
+ offset="1"
+ style="stop-color:#d3d7cf;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7340">
+ <stop
+ id="stop7342"
+ offset="0"
+ style="stop-color:#2e3436;stop-opacity:1;" />
+ <stop
+ id="stop7344"
+ offset="1"
+ style="stop-color:#555753;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7422"
+ inkscape:collect="always">
+ <stop
+ id="stop7424"
+ offset="0"
+ style="stop-color:#edd400;stop-opacity:1;" />
+ <stop
+ id="stop7426"
+ offset="1"
+ style="stop-color:#edd400;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7430"
+ inkscape:collect="always">
+ <stop
+ id="stop7432"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop7434"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7438"
+ inkscape:collect="always">
+ <stop
+ id="stop7440"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop7442"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7576"
+ inkscape:collect="always">
+ <stop
+ id="stop7578"
+ offset="0"
+ style="stop-color:#3465a4;stop-opacity:1" />
+ <stop
+ id="stop7580"
+ offset="1"
+ style="stop-color:#3465a4;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7652"
+ inkscape:collect="always">
+ <stop
+ id="stop7654"
+ offset="0"
+ style="stop-color:#729fcf;stop-opacity:1;" />
+ <stop
+ id="stop7656"
+ offset="1"
+ style="stop-color:#729fcf;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7660"
+ inkscape:collect="always">
+ <stop
+ id="stop7662"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop7664"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7688"
+ inkscape:collect="always">
+ <stop
+ id="stop7690"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop7692"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7812"
+ inkscape:collect="always">
+ <stop
+ id="stop7814"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop7816"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7822"
+ inkscape:collect="always">
+ <stop
+ id="stop7824"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop7826"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7822"
+ id="radialGradient6685"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.6884422,0,10.837832)"
+ cx="14.363107"
+ cy="34.785942"
+ fx="14.363107"
+ fy="34.785942"
+ r="8.7946405" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6991"
+ id="linearGradient6687"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.0000002,0,0,1.9333333,43.500004,0.533333)"
+ x1="-7.975069"
+ y1="25.357235"
+ x2="-11.005972"
+ y2="-6.5683565" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7438"
+ id="linearGradient6689"
+ gradientUnits="userSpaceOnUse"
+ x1="-7.8516631"
+ y1="3.7545938"
+ x2="-5.5098634"
+ y2="18.937717" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7688"
+ id="linearGradient6691"
+ gradientUnits="userSpaceOnUse"
+ x1="28.625"
+ y1="41.125"
+ x2="30.5"
+ y2="47.8125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7263"
+ id="linearGradient6693"
+ gradientUnits="userSpaceOnUse"
+ x1="1.6256078"
+ y1="55.219357"
+ x2="0.82206726"
+ y2="54.415817" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7269"
+ id="linearGradient6695"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9642856,0,0,0.9722222,-0.2500008,1.6944444)"
+ x1="-4.2208939"
+ y1="59.878922"
+ x2="-4.2208939"
+ y2="54.707691" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7257"
+ id="linearGradient6697"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4,-24)"
+ x1="-1.9887378"
+ y1="51.137787"
+ x2="-3.3587573"
+ y2="54" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7237"
+ id="linearGradient6699"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4,-24)"
+ x1="-4.6845822"
+ y1="52.640388"
+ x2="0.88388348"
+ y2="50.563263" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7245"
+ id="linearGradient6701"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4,-24)"
+ x1="-5.0823302"
+ y1="50.51907"
+ x2="0.26516503"
+ y2="49.458408" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7186"
+ id="linearGradient6703"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-4,-24)"
+ x1="-5.96875"
+ y1="52.875"
+ x2="-5.96875"
+ y2="51.812416" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7277"
+ id="linearGradient6705"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.0285717,-4,-25.142872)"
+ x1="-3.5355339"
+ y1="55.866562"
+ x2="-3.5355339"
+ y2="59.444622" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7340"
+ id="linearGradient6707"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0874899,0,0,1.086371,-1.5809531,-8.9433469)"
+ x1="32.8125"
+ y1="21"
+ x2="32.8125"
+ y2="26.204767" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7430"
+ id="linearGradient6709"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(1,-7)"
+ x1="28.875"
+ y1="29"
+ x2="29"
+ y2="16" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7422"
+ id="linearGradient6711"
+ gradientUnits="userSpaceOnUse"
+ x1="30.3125"
+ y1="27.313059"
+ x2="30.3125"
+ y2="24.6875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7422"
+ id="linearGradient6713"
+ gradientUnits="userSpaceOnUse"
+ x1="30.3125"
+ y1="27.313059"
+ x2="30.3125"
+ y2="24.6875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7422"
+ id="linearGradient6716"
+ gradientUnits="userSpaceOnUse"
+ x1="30.3125"
+ y1="27.313059"
+ x2="30.3125"
+ y2="24.6875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7422"
+ id="linearGradient6718"
+ gradientUnits="userSpaceOnUse"
+ x1="30.3125"
+ y1="27.313059"
+ x2="30.3125"
+ y2="24.6875" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7652"
+ id="linearGradient6722"
+ gradientUnits="userSpaceOnUse"
+ x1="37.625"
+ y1="40.3125"
+ x2="38.875"
+ y2="45.0625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7576"
+ id="linearGradient6724"
+ gradientUnits="userSpaceOnUse"
+ x1="38.75"
+ y1="40.625"
+ x2="40.125"
+ y2="46.5625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7660"
+ id="linearGradient6726"
+ gradientUnits="userSpaceOnUse"
+ x1="41.1875"
+ y1="38.3125"
+ x2="42.123722"
+ y2="42.9375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7269"
+ id="linearGradient6728"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1249999,0,0,1.1666666,15.874999,-34.135417)"
+ x1="-4.1097827"
+ y1="58.807774"
+ x2="-4.1097827"
+ y2="55.000004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7812"
+ id="linearGradient6730"
+ gradientUnits="userSpaceOnUse"
+ x1="-6.40625"
+ y1="32.4375"
+ x2="-7.78125"
+ y2="34.5625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5048-1"
+ id="linearGradient7016"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
+ x1="302.85715"
+ y1="366.64789"
+ x2="302.85715"
+ y2="609.50507" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-8"
+ id="radialGradient7018"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5060-8"
+ id="radialGradient7020"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
+ cx="605.71429"
+ cy="486.64789"
+ fx="605.71429"
+ fy="486.64789"
+ r="117.14286" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2809"
+ id="linearGradient7022"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.909091,0,0,1,46.95455,-0.999999)"
+ x1="7.5030818"
+ y1="27.499998"
+ x2="1.0550151"
+ y2="27.499998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4391"
+ id="linearGradient7024"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.909091,0,0,1,46.04546,1.999997)"
+ x1="6.5030808"
+ y1="24.500002"
+ x2="0.055013988"
+ y2="24.500002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2809"
+ id="linearGradient7026"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.909091,0,0,1,1.045449,-1)"
+ x1="7.5030818"
+ y1="27.499998"
+ x2="1.0550151"
+ y2="27.499998" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6837"
+ id="linearGradient7028"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.909091,0,0,1,1.954541,1.999997)"
+ x1="6.5030808"
+ y1="24.500002"
+ x2="0.055013988"
+ y2="24.500002" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3859"
+ id="linearGradient7030"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-40,-1)"
+ x1="73.05397"
+ y1="6.5458651"
+ x2="53.61911"
+ y2="6.5458651" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4175"
+ id="linearGradient7032"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-40,-1)"
+ x1="60.426777"
+ y1="18.520107"
+ x2="60.426777"
+ y2="72.082878" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4233"
+ id="linearGradient7034"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.882353,0,0,1,2.70589,1)"
+ x1="24.92893"
+ y1="12.001067"
+ x2="24.92893"
+ y2="10.868282" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4227"
+ id="linearGradient7036"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.882353,0,0,1,2.70589,1)"
+ x1="24.960155"
+ y1="19.00001"
+ x2="24.92893"
+ y2="17.762573" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2833"
+ id="linearGradient7038"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.999998,0,0,1.000003,6.00003,-7.000134)"
+ x1="10.249995"
+ y1="32.593761"
+ x2="12.500004"
+ y2="36.374992" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3942"
+ id="linearGradient7040"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-40,-1)"
+ x1="53.5625"
+ y1="4.4916701"
+ x2="53.5625"
+ y2="37.256325" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4241"
+ id="linearGradient7042"
+ gradientUnits="userSpaceOnUse"
+ x1="57.49662"
+ y1="38.277283"
+ x2="57.49662"
+ y2="31.250401" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4241"
+ id="linearGradient7044"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2,0)"
+ x1="57.49662"
+ y1="38.277283"
+ x2="57.49662"
+ y2="31.250401" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4241"
+ id="linearGradient7046"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(4,0)"
+ x1="57.49662"
+ y1="38.277283"
+ x2="57.49662"
+ y2="31.250401" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4241"
+ id="linearGradient7048"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,0)"
+ x1="57.49662"
+ y1="38.277283"
+ x2="57.49662"
+ y2="31.250401" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4241"
+ id="linearGradient7050"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(8,0)"
+ x1="57.49662"
+ y1="38.277283"
+ x2="57.49662"
+ y2="31.250401" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4241"
+ id="linearGradient7052"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(10,0)"
+ x1="57.49662"
+ y1="38.277283"
+ x2="57.49662"
+ y2="31.250401" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7422"
+ id="linearGradient7060"
+ gradientUnits="userSpaceOnUse"
+ x1="30.3125"
+ y1="27.313059"
+ x2="30.3125"
+ y2="24.6875" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="40.441154"
+ x2="21.8125"
+ y1="13.249833"
+ x1="21.8125"
+ id="linearGradient2960-6"
+ xlink:href="#linearGradient2954-1"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="39.3125"
+ x2="33.5625"
+ y1="34"
+ x1="33.5"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2077"
+ xlink:href="#linearGradient5302"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="39.3125"
+ x2="33.5625"
+ y1="34"
+ x1="33.5"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2073"
+ xlink:href="#linearGradient5302"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="39.3125"
+ x2="33.5625"
+ y1="34"
+ x1="33.5"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2069"
+ xlink:href="#linearGradient5302"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="39.3125"
+ x2="33.5625"
+ y1="34"
+ x1="33.5"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2065"
+ xlink:href="#linearGradient5302"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="39.3125"
+ x2="33.5625"
+ y1="34"
+ x1="33.5"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2061"
+ xlink:href="#linearGradient5302"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="39.3125"
+ x2="33.5625"
+ y1="34"
+ x1="33.5"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient2057"
+ xlink:href="#linearGradient5302"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="21.997721"
+ x2="5.25"
+ y1="35.75"
+ x1="5.25"
+ id="linearGradient2164"
+ xlink:href="#linearGradient2158"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(1.571428,0,0,1,-7.714286,0)"
+ y2="29.010038"
+ x2="17.5625"
+ y1="20.996099"
+ x1="17.5625"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5322"
+ xlink:href="#linearGradient4055-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="2"
+ fy="26"
+ fx="13.006094"
+ cy="26"
+ cx="13.006094"
+ gradientTransform="matrix(-9.458067e-7,-2.000005,2.003046,-1.684215e-6,-98.5731,1.012286)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient5320-2"
+ xlink:href="#linearGradient4033-7"
+ inkscape:collect="always" />
+ <radialGradient
+ r="2"
+ fy="26"
+ fx="13.006094"
+ cy="26"
+ cx="13.006094"
+ gradientTransform="matrix(-9.458067e-7,-2.000005,2.003046,-1.684215e-6,-38.5731,51.01229)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient5318-5"
+ xlink:href="#linearGradient4033-7"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="33.375"
+ x2="10.5"
+ y1="36.75"
+ x1="12.5"
+ gradientTransform="translate(12,1)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5201"
+ xlink:href="#linearGradient5187"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(6,1)"
+ y2="33.375"
+ x2="10.5"
+ y1="36.75"
+ x1="12.5"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5197"
+ xlink:href="#linearGradient5209"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="translate(0,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="33.375"
+ x2="10.5"
+ y1="36.75"
+ x1="12.5"
+ id="linearGradient5193"
+ xlink:href="#linearGradient5203"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="36.65625"
+ x2="10"
+ y1="34.9375"
+ x1="10"
+ gradientTransform="matrix(1,0,0,0.666666,13,12.1667)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5101"
+ xlink:href="#linearGradient5111"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(1,0,0,0.666666,7,12.1667)"
+ y2="36.65625"
+ x2="10"
+ y1="34.9375"
+ x1="10"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient5095"
+ xlink:href="#linearGradient5105"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(1,0,0,0.666662,1,12.16683)"
+ gradientUnits="userSpaceOnUse"
+ y2="36.65625"
+ x2="10"
+ y1="34.9375"
+ x1="10"
+ id="linearGradient5091"
+ xlink:href="#linearGradient5085"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(0.944444,0,0,0.999999,1.333333,0)"
+ gradientUnits="userSpaceOnUse"
+ y2="42"
+ x2="20.875"
+ y1="33"
+ x1="19"
+ id="linearGradient4975"
+ xlink:href="#linearGradient4969"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="29.010038"
+ x2="17.5625"
+ y1="20.996099"
+ x1="17.5625"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient4074-1"
+ xlink:href="#linearGradient4055-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="2"
+ fy="26"
+ fx="13.006094"
+ cy="26"
+ cx="13.006094"
+ gradientTransform="matrix(-9.458067e-7,-2.000005,2.003046,-1.684215e-6,-86.5731,1.012286)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient4072-4"
+ xlink:href="#linearGradient4033-7"
+ inkscape:collect="always" />
+ <radialGradient
+ r="2"
+ fy="26"
+ fx="13.006094"
+ cy="26"
+ cx="13.006094"
+ gradientTransform="matrix(-9.458067e-7,-2.000005,2.003046,-1.684215e-6,-38.5731,51.01229)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient4070-6"
+ xlink:href="#linearGradient4033-7"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.96731,-1.031509e-7,0,-1.136461,83.23332,33.67016)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3017-3"
+ xlink:href="#linearGradient6256-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.96731,-1.031509e-7,0,-1.136461,88.32422,33.67016)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3013-2"
+ xlink:href="#linearGradient6256-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.96731,-1.031509e-7,0,-1.136461,93.41513,33.67016)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3009-6"
+ xlink:href="#linearGradient6256-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.755359,-1.031509e-7,0,-1.136461,79.00237,30.67016)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient3002-6"
+ xlink:href="#linearGradient6256-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.755359,-1.031509e-7,0,-1.136461,83.72964,30.67016)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2998-7"
+ xlink:href="#linearGradient6256-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.755359,-1.031509e-7,0,-1.136461,88.45691,30.67016)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2994-4"
+ xlink:href="#linearGradient6256-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.543409,-1.031509e-7,0,-1.136461,74.77142,27.67016)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2987-3"
+ xlink:href="#linearGradient6256-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.543409,-1.031509e-7,0,-1.136461,79.13505,27.67016)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2983-6"
+ xlink:href="#linearGradient6256-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.543409,-1.031509e-7,0,-1.136461,83.49869,27.67016)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2979-8"
+ xlink:href="#linearGradient6256-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.331458,-1.031509e-7,0,-1.136461,78.54047,24.67016)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2972-2"
+ xlink:href="#linearGradient6256-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.331458,-1.031509e-7,0,-1.136461,74.54047,24.67016)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient2968-2"
+ xlink:href="#linearGradient6256-4"
+ inkscape:collect="always" />
+ <radialGradient
+ r="1.5"
+ fy="11.602475"
+ fx="21.530191"
+ cy="11.602475"
+ cx="21.530191"
+ gradientTransform="matrix(-2.331458,-1.031509e-7,0,-1.136461,70.54047,24.67016)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient6264-1"
+ xlink:href="#linearGradient6256-4"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.720795,-0.03898649,0.00176461,0.123227,-33.03868,12.78605)"
+ r="16.031172"
+ fy="3.5110793"
+ fx="16.030262"
+ cy="3.5110793"
+ cx="16.030262"
+ id="radialGradient4068-8"
+ xlink:href="#linearGradient4062-9"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(2.04444,-0.123888,0.01467675,0.242354,-19.8863,13.61936)"
+ r="16.994591"
+ fy="6.5931005"
+ fx="17.04607"
+ cy="6.5931005"
+ cx="17.04607"
+ id="radialGradient4024-0"
+ xlink:href="#linearGradient4038-5"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="18.257809"
+ x2="23.994669"
+ y1="13.842071"
+ x1="23.994669"
+ id="linearGradient3404-2"
+ xlink:href="#linearGradient4044-9"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(1.000314,0,0,1,-0.00361429,0.972209)"
+ y2="20.639368"
+ x2="28.260429"
+ y1="8.7648172"
+ x1="28.260429"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1616-2"
+ xlink:href="#linearGradient4044-9"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="29.477005"
+ x2="24.414724"
+ y1="25.463402"
+ x1="24.414724"
+ gradientTransform="matrix(1.000314,0,0,1,0.00705191,-4.000006)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1614-1"
+ xlink:href="#linearGradient4038-5"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="17.53454"
+ x2="25.189993"
+ y1="24.504593"
+ x1="24.160858"
+ gradientTransform="matrix(-1.000314,0,0,1,48.01271,-4.000006)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1601-3"
+ xlink:href="#linearGradient2513-0"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="8.361702"
+ x2="24.010672"
+ y1="24.81731"
+ x1="24.834204"
+ gradientTransform="matrix(0.921903,0,0,0.877945,1.869671,-1.024713)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1598-1"
+ xlink:href="#linearGradient4070-0"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2513-0">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop2515-3" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.21789883"
+ offset="1"
+ id="stop2517-9" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4038-5">
+ <stop
+ style="stop-color:#729fcf;stop-opacity:1"
+ offset="0"
+ id="stop4040-3" />
+ <stop
+ style="stop-color:#3465a4;stop-opacity:1"
+ offset="1"
+ id="stop4042-4" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4044-9">
+ <stop
+ id="stop4046-5"
+ offset="0"
+ style="stop-color:#3465a4;stop-opacity:1" />
+ <stop
+ id="stop4048-5"
+ offset="1"
+ style="stop-color:#204a87;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4062-9">
+ <stop
+ id="stop4064-2"
+ offset="0"
+ style="stop-color:white;stop-opacity:1;" />
+ <stop
+ id="stop4066-6"
+ offset="1"
+ style="stop-color:white;stop-opacity:0.29761904;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4070-0">
+ <stop
+ style="stop-color:white;stop-opacity:0.42857143;"
+ offset="0"
+ id="stop4072-4" />
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="1"
+ id="stop4074-7" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6256-4">
+ <stop
+ style="stop-color:white;stop-opacity:1;"
+ offset="0"
+ id="stop6258-1" />
+ <stop
+ style="stop-color:#cccec9;stop-opacity:1;"
+ offset="1"
+ id="stop6260-1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4033-7"
+ inkscape:collect="always">
+ <stop
+ id="stop4035-1"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop4037-0"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4055-4">
+ <stop
+ id="stop4057-7"
+ offset="0"
+ style="stop-color:black;stop-opacity:0;" />
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0.5"
+ id="stop4063-0" />
+ <stop
+ id="stop4059-4"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4961-1">
+ <stop
+ id="stop4963-8"
+ offset="0"
+ style="stop-color:#555753;stop-opacity:1" />
+ <stop
+ id="stop4965-9"
+ offset="1"
+ style="stop-color:#babdb6;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4969"
+ inkscape:collect="always">
+ <stop
+ id="stop4971"
+ offset="0"
+ style="stop-color:#d3d7cf;stop-opacity:1;" />
+ <stop
+ id="stop4973"
+ offset="1"
+ style="stop-color:#d3d7cf;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5085">
+ <stop
+ id="stop5087"
+ offset="0"
+ style="stop-color:#73d216;stop-opacity:1;" />
+ <stop
+ id="stop5089"
+ offset="1"
+ style="stop-color:#8ae234;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5105">
+ <stop
+ style="stop-color:#edd400;stop-opacity:1"
+ offset="0"
+ id="stop5107" />
+ <stop
+ style="stop-color:#fce94f;stop-opacity:1"
+ offset="1"
+ id="stop5109" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5111">
+ <stop
+ style="stop-color:#f57900;stop-opacity:1"
+ offset="0"
+ id="stop5113" />
+ <stop
+ style="stop-color:#fcaf3e;stop-opacity:1"
+ offset="1"
+ id="stop5115" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5187"
+ inkscape:collect="always">
+ <stop
+ id="stop5189"
+ offset="0"
+ style="stop-color:white;stop-opacity:1" />
+ <stop
+ id="stop5191"
+ offset="1"
+ style="stop-color:#eeeeec;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5203">
+ <stop
+ style="stop-color:white;stop-opacity:1"
+ offset="0"
+ id="stop5205" />
+ <stop
+ style="stop-color:#eeeeec;stop-opacity:0;"
+ offset="1"
+ id="stop5207" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient5209">
+ <stop
+ style="stop-color:white;stop-opacity:1"
+ offset="0"
+ id="stop5211" />
+ <stop
+ style="stop-color:#eeeeec;stop-opacity:0;"
+ offset="1"
+ id="stop5213" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5302"
+ inkscape:collect="always">
+ <stop
+ id="stop5304"
+ offset="0"
+ style="stop-color:#888a85;stop-opacity:1" />
+ <stop
+ id="stop5306"
+ offset="1"
+ style="stop-color:#d3d7cf;stop-opacity:0" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2158">
+ <stop
+ id="stop2160"
+ offset="0"
+ style="stop-color:#555753;stop-opacity:1" />
+ <stop
+ id="stop2162"
+ offset="1"
+ style="stop-color:#888a85;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2954-1"
+ inkscape:collect="always">
+ <stop
+ id="stop2956-8"
+ offset="0"
+ style="stop-color:#3465a4;stop-opacity:1;" />
+ <stop
+ id="stop2958-0"
+ offset="1"
+ style="stop-color:#3465a4;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7959"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7961"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7963"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7965"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7967"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7969"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7971"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7973"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7975"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7977"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7979"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7981"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8522"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8524"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8526"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8528"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8530"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8532"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8534"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient8536"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8538"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8540"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8542"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8544"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8546"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8548"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8550"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient8552"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3374-9-9"
+ id="radialGradient5864-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.827349,0,1.12223)"
+ cx="10.28125"
+ cy="8.0709476"
+ fx="10.28125"
+ fy="8.0709476"
+ r="4.5250292" />
+ <linearGradient
+ id="linearGradient3374-9-9"
+ inkscape:collect="always">
+ <linearGradient
+ id="linearGradient4953">
+ <stop
+ style="stop-color: rgb(252, 245, 213); stop-opacity: 1;"
+ offset="0"
+ id="stop4955" />
+ <stop
+ style="stop-color: rgb(255, 221, 0); stop-opacity: 1;"
+ offset="1"
+ id="stop4957" />
+ </linearGradient>
+ <stop
+ id="stop3376-6-6"
+ offset="0"
+ style="stop-color: rgb(114, 159, 207); stop-opacity: 1;" />
+ <stop
+ id="stop3378-6-5"
+ offset="1"
+ style="stop-color: rgb(114, 159, 207); stop-opacity: 0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3362-7-4"
+ id="radialGradient5866-9"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(4.68085,0,0,1.27674,-37.8437,-3.30085)"
+ cx="10.28125"
+ cy="10.018439"
+ fx="10.28125"
+ fy="10.018439"
+ r="4.5250292" />
+ <linearGradient
+ id="linearGradient3362-7-4"
+ inkscape:collect="always">
+ <stop
+ id="stop3364-5-3"
+ offset="0"
+ style="stop-color: rgb(52, 101, 164); stop-opacity: 1;" />
+ <stop
+ id="stop3366-5-7"
+ offset="1"
+ style="stop-color: rgb(52, 101, 164); stop-opacity: 0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3362-7-4"
+ id="radialGradient5870-2"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(4.68085,0,0,1.27674,-37.8437,-3.30085)"
+ cx="10.28125"
+ cy="9.8424416"
+ fx="10.28125"
+ fy="9.8424416"
+ r="4.5250292" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3374-9-9"
+ id="radialGradient5872-8"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.698447,0,0,0.57786,3.10034,2.74391)"
+ cx="10.28125"
+ cy="7.8249326"
+ fx="10.28125"
+ fy="7.8249326"
+ r="4.5250292" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3362-7-4"
+ id="radialGradient5874-7"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(4.68085,0,0,1.27674,-37.8437,-3.30085)"
+ cx="10.28125"
+ cy="9.8424416"
+ fx="10.28125"
+ fy="9.8424416"
+ r="4.5250292" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7131-9-0"
+ id="radialGradient5876-6"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.737507,0,0,0.720181,2.43453,0.661737)"
+ cx="8.9057236"
+ cy="1.7286602"
+ fx="8.9057236"
+ fy="1.7286602"
+ r="1.9952321" />
+ <linearGradient
+ id="linearGradient7131-9-0"
+ inkscape:collect="always">
+ <stop
+ id="stop7133-8-4"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop7135-2-9"
+ offset="1"
+ style="stop-color: rgb(211, 215, 207); stop-opacity: 1;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7153-8-2"
+ id="radialGradient5878-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.85977,0,0,1.81726,-7.14013,-0.894237)"
+ cx="8.3046875"
+ cy="1.1256332"
+ fx="8.3046875"
+ fy="1.1256332"
+ r="2.0507698" />
+ <linearGradient
+ id="linearGradient7153-8-2"
+ inkscape:collect="always">
+ <stop
+ id="stop7155-6-2"
+ offset="0"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" />
+ <stop
+ id="stop7157-1-2"
+ offset="1"
+ style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3374-9-9"
+ id="radialGradient6930"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.827349,0,1.12223)"
+ cx="10.28125"
+ cy="8.0709476"
+ fx="10.28125"
+ fy="8.0709476"
+ r="4.5250292" />
+ <marker
+ inkscape:stockid="Arrow2Lstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Lstart-3"
+ style="overflow:visible">
+ <path
+ inkscape:connector-curvature="0"
+ id="path6083-8"
+ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="matrix(1.1,0,0,1.1,1.1,0)" />
+ </marker>
+ <marker
+ id="multiplicityStart"
+ refX="0"
+ refY="0"
+ orient="auto"
+ style="overflow:visible">
+ <path
+ id="path4836"
+ d="M 0,0 -14,7 M 0,0 -14,0 M 0,0 -14,-7"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ </marker>
+ <marker
+ id="multiplicityEnd"
+ orient="auto"
+ refX="14"
+ refY="0"
+ style="overflow:visible">
+ <path
+ id="path6575"
+ d="M 0,0 14,7 M 0,0 14,0 M 0,0 14,-7"
+ inkscape:connector-curvature="0"
+ style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+ </marker>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient6667"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient6671"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient6675"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient6679"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient6683"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient6688"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient6690"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient6739"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <linearGradient
+ id="linearGradient5048-9">
+ <stop
+ id="stop5050-8"
+ offset="0"
+ style="stop-color:black;stop-opacity:0;" />
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0.5"
+ id="stop5056-9" />
+ <stop
+ id="stop5052-1"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <radialGradient
+ r="18.5"
+ fy="61.48016"
+ fx="13.107393"
+ cy="61.48016"
+ cx="13.107393"
+ gradientTransform="matrix(2.60832,0,0,2.21881,-25.9414,-116.551)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient10291-7"
+ xlink:href="#linearGradient6945-1"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="58.838387"
+ x2="32.625"
+ y1="68.4375"
+ x1="32.625"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient10289-0"
+ xlink:href="#linearGradient6932-5"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="25.371557"
+ x2="9.9965248"
+ y1="21.246521"
+ x1="9.9965248"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient10287-3"
+ xlink:href="#linearGradient7088-39"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="24.779999"
+ x2="9.0107775"
+ y1="19.584124"
+ x1="9.0107775"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient10285-8"
+ xlink:href="#linearGradient7059-3"
+ inkscape:collect="always" />
+ <radialGradient
+ r="15.5"
+ fy="25.349953"
+ fx="26.762928"
+ cy="25.349953"
+ cx="26.762928"
+ gradientTransform="matrix(1.49194,0,0,1.32349,-11.499,-8.80317)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient10283-8"
+ xlink:href="#linearGradient7067-2"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="35.853024"
+ x2="15.75"
+ y1="24.561808"
+ x1="15.75"
+ gradientTransform="matrix(1,0,0,1.14285,-1,-4.36135)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient10281-2"
+ xlink:href="#linearGradient7002-6"
+ inkscape:collect="always" />
+ <radialGradient
+ r="18.5"
+ fy="61.48016"
+ fx="13.107393"
+ cy="61.48016"
+ cx="13.107393"
+ gradientTransform="matrix(2.60832,0,0,-2.21881,-25.9414,168.685)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient10279-8"
+ xlink:href="#linearGradient6945-1"
+ inkscape:collect="always" />
+ <radialGradient
+ r="117.14286"
+ fy="486.64789"
+ fx="605.71429"
+ cy="486.64789"
+ cx="605.71429"
+ gradientTransform="matrix(-2.77439,0,0,1.96971,112.762,-872.885)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient10277-5"
+ xlink:href="#linearGradient5060-1"
+ inkscape:collect="always" />
+ <radialGradient
+ r="117.14286"
+ fy="486.64789"
+ fx="605.71429"
+ cy="486.64789"
+ cx="605.71429"
+ gradientTransform="matrix(2.77439,0,0,1.96971,-1891.63,-872.885)"
+ gradientUnits="userSpaceOnUse"
+ id="radialGradient10275-7"
+ xlink:href="#linearGradient5060-1"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="609.50507"
+ x2="302.85715"
+ y1="366.64789"
+ x1="302.85715"
+ gradientTransform="matrix(2.77439,0,0,1.96971,-1892.18,-872.885)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient10273-9"
+ xlink:href="#linearGradient5048-2"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient7088-39">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop7090-1" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop7092-6" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient7067-2">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop7069-1" />
+ <stop
+ style="stop-color:#eeeeec;stop-opacity:1"
+ offset="1"
+ id="stop7071-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient7059-3">
+ <stop
+ style="stop-color:#babdb6;stop-opacity:1"
+ offset="0"
+ id="stop7061-0" />
+ <stop
+ style="stop-color:#babdb6;stop-opacity:0"
+ offset="1"
+ id="stop7063-3" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient7002-6">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop7004-4" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop7006-5" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient6932-5">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop6934-9" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop9565-8" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient6945-1">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0"
+ id="stop6947-8" />
+ <stop
+ style="stop-color:#d3d7cf;stop-opacity:1"
+ offset="1"
+ id="stop6949-3" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5048-2">
+ <stop
+ id="stop5050-7"
+ offset="0"
+ style="stop-color:black;stop-opacity:0;" />
+ <stop
+ style="stop-color:black;stop-opacity:1;"
+ offset="0.5"
+ id="stop5056-0" />
+ <stop
+ id="stop5052-6"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5060-1"
+ inkscape:collect="always">
+ <stop
+ id="stop5062-9"
+ offset="0"
+ style="stop-color:black;stop-opacity:1;" />
+ <stop
+ id="stop5064-9"
+ offset="1"
+ style="stop-color:black;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient7733"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient7737"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient7741"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient7745"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient7749"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient7753"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient7755"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4961-1"
+ id="linearGradient7803"
+ gradientUnits="userSpaceOnUse"
+ x1="23.994967"
+ y1="20.3125"
+ x2="23.994967"
+ y2="3.1169004" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4033-7"
+ id="radialGradient8019"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-9.458067e-7,-2.000005,2.003046,-1.684215e-6,-38.5731,51.01229)"
+ cx="13.006094"
+ cy="26"
+ fx="13.006094"
+ fy="26"
+ r="2" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4033-7"
+ id="radialGradient8021"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-9.458067e-7,-2.000005,2.003046,-1.684215e-6,-98.5731,1.012286)"
+ cx="13.006094"
+ cy="26"
+ fx="13.006094"
+ fy="26"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4055-4"
+ id="linearGradient8023"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.571428,0,0,1,-7.714286,0)"
+ x1="17.5625"
+ y1="20.996099"
+ x2="17.5625"
+ y2="29.010038" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2158"
+ id="linearGradient8025"
+ gradientUnits="userSpaceOnUse"
+ x1="5.25"
+ y1="35.75"
+ x2="5.25"
+ y2="21.997721" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4969"
+ id="linearGradient8027"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.944444,0,0,0.999999,1.333333,0)"
+ x1="19"
+ y1="33"
+ x2="20.875"
+ y2="42" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5203"
+ id="linearGradient8029"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1)"
+ x1="12.5"
+ y1="36.75"
+ x2="10.5"
+ y2="33.375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5085"
+ id="linearGradient8031"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.666662,1,12.16683)"
+ x1="10"
+ y1="34.9375"
+ x2="10"
+ y2="36.65625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5105"
+ id="linearGradient8033"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.666666,7,12.1667)"
+ x1="10"
+ y1="34.9375"
+ x2="10"
+ y2="36.65625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5111"
+ id="linearGradient8035"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.666666,13,12.1667)"
+ x1="10"
+ y1="34.9375"
+ x2="10"
+ y2="36.65625" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5209"
+ id="linearGradient8037"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(6,1)"
+ x1="12.5"
+ y1="36.75"
+ x2="10.5"
+ y2="33.375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5187"
+ id="linearGradient8039"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(12,1)"
+ x1="12.5"
+ y1="36.75"
+ x2="10.5"
+ y2="33.375" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8041"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8043"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"
+ x2="33.5625"
+ y2="39.3125" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5302"
+ id="linearGradient8045"
+ gradientUnits="userSpaceOnUse"
+ x1="33.5"
+ y1="34"