1ae9e008c32d12a517ec8628b8c37ea8b1115282
[rnaseq-cwl-training.git] / css / deckjs-js / deckjs-custom.js
1 /*
2   This is a packed deck.js with some extensions and styles.
3   It has been generated from version 16322c026d0e5b6e9953e12362ca665d5d09304e .
4   It includes:
5      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck/extensions/includedeck/load.js
6      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//jquery.min.js
7      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//modernizr.custom.js
8      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//core/deck.core.js
9      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/smarkdown/markdown.js
10      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/smarkdown/deck.smarkdown.js
11      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/fit/deck.fit.js
12      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//libs/display-latex2.user.js
13      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/simplemath/deck.simplemath.js
14      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/clone/deck.clone.js
15      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/goto/deck.goto.js
16      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/progress/deck.progress.js
17      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/navigation/deck.navigation.js
18      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/menu/deck.menu.js
19      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/step/deck.step.js
20      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/events/deck.events.js
21      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/anim/deck.anim.js
22      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//libs/jquerysvg/jquery.svg.min.js
23      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//libs/jquerysvg/jquery.svganim.min.js
24      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/svg/deck.svg.js
25      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/metadata/deck.metadata.js
26      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/attribution/deck.attribution.js
27      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/container-styling/deck.container-styling.js
28      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/timekeeper/deck.timekeeper.js
29      browsercast/popcorn.js
30      browsercast/deck.browsercast.js
31      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/style-chunks/core.css
32      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/fit/deck.fit-fs.css
33      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/clone/deck.clone.css
34      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/goto/deck.goto.css
35      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/progress/deck.progress.css
36      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/navigation/deck.navigation.css
37      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/menu/deck.menu.css
38      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/attribution/deck.attribution.css
39      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/timekeeper/deck.timekeeper.css
40      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/style-chunks/simple.css
41      /home/twilight/projects/deck.browsercast.js-demo/tmpdeck//extensions/style-chunks/comments.css
42      browsercast/deck.browsercast.css
43      browsercast/player.css
44 */
45
46
47 /*!
48  * Includedeck.
49  *
50  * Copyright (c) 2013-2014 RĂ©mi Emonet.
51  * Licensed under the MIT license.
52  * https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
53  *
54  * The goal of this extension is to simplify include of deck.js,
55  * its profiles/themes and the extensions.
56  *
57  * The first goal is not performance of loading (still it should
58  * allow the display of a message while loading) but on ease of
59  * use and extensibility (i.e., includedeck does not need to know
60  * about all existing extensions, even if by default it does know
61  * some of them).
62  *
63  */
64
65
66
67 var head_conf = {
68     
69 };
70
71 if (typeof ACTUALLY_EXPORT_A_LIST_OF_FILES == 'undefined')
72 // this is head.load.min.js (v1.0.3) from http://headjs.com/site/download.html
73 /*! head.load - v1.0.3 */
74 (function(n,t){"use strict";function w(){}function u(n,t){if(n){typeof n=="object"&&(n=[].slice.call(n));for(var i=0,r=n.length;i<r;i++)t.call(n,n[i],i)}}function it(n,i){var r=Object.prototype.toString.call(i).slice(8,-1);return i!==t&&i!==null&&r===n}function s(n){return it("Function",n)}function a(n){return it("Array",n)}function et(n){var i=n.split("/"),t=i[i.length-1],r=t.indexOf("?");return r!==-1?t.substring(0,r):t}function f(n){(n=n||w,n._done)||(n(),n._done=1)}function ot(n,t,r,u){var f=typeof n=="object"?n:{test:n,success:!t?!1:a(t)?t:[t],failure:!r?!1:a(r)?r:[r],callback:u||w},e=!!f.test;return e&&!!f.success?(f.success.push(f.callback),i.load.apply(null,f.success)):e||!f.failure?u():(f.failure.push(f.callback),i.load.apply(null,f.failure)),i}function v(n){var t={},i,r;if(typeof n=="object")for(i in n)!n[i]||(t={name:i,url:n[i]});else t={name:et(n),url:n};return(r=c[t.name],r&&r.url===t.url)?r:(c[t.name]=t,t)}function y(n){n=n||c;for(var t in n)if(n.hasOwnProperty(t)&&n[t].state!==l)return!1;return!0}function st(n){n.state=ft;u(n.onpreload,function(n){n.call()})}function ht(n){n.state===t&&(n.state=nt,n.onpreload=[],rt({url:n.url,type:"cache"},function(){st(n)}))}function ct(){var n=arguments,t=n[n.length-1],r=[].slice.call(n,1),f=r[0];return(s(t)||(t=null),a(n[0]))?(n[0].push(t),i.load.apply(null,n[0]),i):(f?(u(r,function(n){s(n)||!n||ht(v(n))}),b(v(n[0]),s(f)?f:function(){i.load.apply(null,r)})):b(v(n[0])),i)}function lt(){var n=arguments,t=n[n.length-1],r={};return(s(t)||(t=null),a(n[0]))?(n[0].push(t),i.load.apply(null,n[0]),i):(u(n,function(n){n!==t&&(n=v(n),r[n.name]=n)}),u(n,function(n){n!==t&&(n=v(n),b(n,function(){y(r)&&f(t)}))}),i)}function b(n,t){if(t=t||w,n.state===l){t();return}if(n.state===tt){i.ready(n.name,t);return}if(n.state===nt){n.onpreload.push(function(){b(n,t)});return}n.state=tt;rt(n,function(){n.state=l;t();u(h[n.name],function(n){f(n)});o&&y()&&u(h.ALL,function(n){f(n)})})}function at(n){n=n||"";var t=n.split("?")[0].split(".");return t[t.length-1].toLowerCase()}function rt(t,i){function e(t){t=t||n.event;u.onload=u.onreadystatechange=u.onerror=null;i()}function o(f){f=f||n.event;(f.type==="load"||/loaded|complete/.test(u.readyState)&&(!r.documentMode||r.documentMode<9))&&(n.clearTimeout(t.errorTimeout),n.clearTimeout(t.cssTimeout),u.onload=u.onreadystatechange=u.onerror=null,i())}function s(){if(t.state!==l&&t.cssRetries<=20){for(var i=0,f=r.styleSheets.length;i<f;i++)if(r.styleSheets[i].href===u.href){o({type:"load"});return}t.cssRetries++;t.cssTimeout=n.setTimeout(s,250)}}var u,h,f;i=i||w;h=at(t.url);h==="css"?(u=r.createElement("link"),u.type="text/"+(t.type||"css"),u.rel="stylesheet",u.href=t.url,t.cssRetries=0,t.cssTimeout=n.setTimeout(s,500)):(u=r.createElement("script"),u.type="text/"+(t.type||"javascript"),u.src=t.url);u.onload=u.onreadystatechange=o;u.onerror=e;u.async=!1;u.defer=!1;t.errorTimeout=n.setTimeout(function(){e({type:"timeout"})},7e3);f=r.head||r.getElementsByTagName("head")[0];f.insertBefore(u,f.lastChild)}function vt(){for(var t,u=r.getElementsByTagName("script"),n=0,f=u.length;n<f;n++)if(t=u[n].getAttribute("data-headjs-load"),!!t){i.load(t);return}}function yt(n,t){var v,p,e;return n===r?(o?f(t):d.push(t),i):(s(n)&&(t=n,n="ALL"),a(n))?(v={},u(n,function(n){v[n]=c[n];i.ready(n,function(){y(v)&&f(t)})}),i):typeof n!="string"||!s(t)?i:(p=c[n],p&&p.state===l||n==="ALL"&&y()&&o)?(f(t),i):(e=h[n],e?e.push(t):e=h[n]=[t],i)}function e(){if(!r.body){n.clearTimeout(i.readyTimeout);i.readyTimeout=n.setTimeout(e,50);return}o||(o=!0,vt(),u(d,function(n){f(n)}))}function k(){r.addEventListener?(r.removeEventListener("DOMContentLoaded",k,!1),e()):r.readyState==="complete"&&(r.detachEvent("onreadystatechange",k),e())}var r=n.document,d=[],h={},c={},ut="async"in r.createElement("script")||"MozAppearance"in r.documentElement.style||n.opera,o,g=n.head_conf&&n.head_conf.head||"head",i=n[g]=n[g]||function(){i.ready.apply(null,arguments)},nt=1,ft=2,tt=3,l=4,p;if(r.readyState==="complete")e();else if(r.addEventListener)r.addEventListener("DOMContentLoaded",k,!1),n.addEventListener("load",e,!1);else{r.attachEvent("onreadystatechange",k);n.attachEvent("onload",e);p=!1;try{p=!n.frameElement&&r.documentElement}catch(wt){}p&&p.doScroll&&function pt(){if(!o){try{p.doScroll("left")}catch(t){n.clearTimeout(i.readyTimeout);i.readyTimeout=n.setTimeout(pt,50);return}e()}}()}i.load=i.js=ut?lt:ct;i.test=ot;i.ready=yt;i.ready(r,function(){y()&&u(h.ALL,function(n){f(n)});i.feature&&i.feature("domloaded",!0)})})(window);
75 //# sourceMappingURL=head.load.min.js.map
76
77
78 // this is the actual includedeck
79 function includedeck(m, c) {
80     var maybe = function(f) { return f || (function(){}); }
81     var modules = m || [];
82     var conf = c || {};
83     var initDelay = conf.INITDELAY;
84     var cb = {
85         beforeLoad: maybe(conf.BEFORELOAD),
86         beforeDelay: maybe(conf.BEFOREDELAY), // useful only if INITDELAY is set, else, just like BEFOREINIT
87         beforeInit: maybe(conf.BEFOREINIT),
88         afterInit: maybe(conf.AFTERINIT),
89         atExit: maybe(conf.ATEXIT), // for backward compatibility (same as AFTERINIT)
90         hasGeneric: conf.GENERIC ? true : false,
91         generic: maybe(conf.GENERIC) // will receive calls like GENERIC("AFTER", "svg"), one of each BEFORE/AFTER for each file group (svg, simplemath, ...)
92     };
93     var prefix = conf.PREFIX || "deck.js";
94
95     if (typeof(modules) == "string") {
96         modules = modules.split(/ +/);
97     }
98     
99     // todo: make this externally extensible
100     // todo: maybe have a mechanism to load a list of dependency (e.g., mymodule-files.js)
101
102     var info = {
103         //
104         // core (differerent possible cores)
105         "deck-core-dependencies": [
106             prefix + "/jquery.min.js",
107             prefix + "/modernizr.custom.js"
108             //prefix + "/extensions/includedeck/___after___core___.js"
109         ],
110         "deck": [
111             "@_deck-core-dependencies",
112             prefix + "/core/deck.core.css",
113             prefix + "/core/deck.core.js"
114         ],
115         "newdeck": [
116             "@_deck-core-dependencies",
117             prefix + "/extensions/style-chunks/core.css",
118             prefix + "/core/deck.core.js"
119         ],
120         //
121         // extensions
122         "fit": [ prefix + "/extensions/fit/deck.fit.js" ],
123         "fit-fs": [
124             prefix + "/extensions/fit/deck.fit-fs.css",
125             "@_fit"
126         ],
127         "simplemath": [
128             prefix + "/libs/display-latex2.user.js",
129             prefix + "/extensions/simplemath/deck.simplemath.js"
130         ],
131         "smartsyntax": [ prefix + "/extensions/smartsyntax/deck.smartsyntax.js" ],
132         "smarkdown": [
133             prefix + "/extensions/smarkdown/markdown.js",
134             prefix + "/extensions/smarkdown/deck.smarkdown.js"
135         ],
136         "clone": [
137             prefix + "/extensions/clone/deck.clone.css",
138             prefix + "/extensions/clone/deck.clone.js"
139         ],
140         "timekeeper": [
141             prefix + "/extensions/timekeeper/deck.timekeeper.css",
142             prefix + "/extensions/timekeeper/deck.timekeeper.js"
143         ],
144         "goto": [
145             prefix + "/extensions/goto/deck.goto.css",
146             prefix + "/extensions/goto/deck.goto.js"
147         ],
148         "status": [
149             prefix + "/extensions/status/deck.status.css",
150             prefix + "/extensions/status/deck.status.js"
151         ],
152         "progress": [
153             prefix + "/extensions/progress/deck.progress.css",
154             prefix + "/extensions/progress/deck.progress.js"
155         ],
156         "navigation": [
157             prefix + "/extensions/navigation/deck.navigation.css",
158             prefix + "/extensions/navigation/deck.navigation.js"
159         ],
160         "menu": [
161             prefix + "/extensions/menu/deck.menu.css",
162             prefix + "/extensions/menu/deck.menu.js"
163         ],
164         "step": [ prefix + "/extensions/step/deck.step.js" ],
165         "events": [ prefix + "/extensions/events/deck.events.js" ],
166         "anim": [ prefix + "/extensions/anim/deck.anim.js" ],
167         "svg": [
168             prefix + "/libs/jquerysvg/jquery.svg.min.js" ,
169             prefix + "/libs/jquerysvg/jquery.svganim.min.js",
170             prefix + "/extensions/svg/deck.svg.js"
171         ],
172         "metadata": [ prefix + "/extensions/metadata/deck.metadata.js" ],
173         "attribution": [
174             prefix + "/extensions/attribution/deck.attribution.css",
175             prefix + "/extensions/attribution/deck.attribution.js"
176         ],
177         "container-styling": [ prefix + "/extensions/container-styling/deck.container-styling.js" ],
178         // Style extensions
179         "style-chunks": [
180             prefix + "/extensions/style-chunks/simple.css",
181             prefix + "/extensions/style-chunks/comments.css"
182         ],
183         //
184         // Themes
185         // // by convention, "theme:blabla" will load the default blabla theme
186         //
187         // Some default profiles
188         //
189         /// profile-1: default deck with most extensions and no theme
190         "profile-1": ["@_deck", "@_smartsyntax", "@_fit-fs", "@_simplemath", "@_clone", "@_goto", "@_status", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg"],
191         "profile-1-fitnofs": ["@_deck", "@_smartsyntax", "@_fit", "@_simplemath", "@_clone", "@_goto", "@_status", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg"],
192         /// profile-2: new deck (cleaner css) with most extensions and no theme
193         "profile-2": ["@_newdeck", "@_smartsyntax", "@_fit-fs", "@_simplemath", "@_clone", "@_goto", "@_status", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg"],
194         "profile-2-fitnofs": ["@_newdeck", "@_smartsyntax", "@_fit", "@_simplemath", "@_clone", "@_goto", "@_status", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg"],
195         /// profile-3: big profile = profile-2 / with new status (progress) + all good bundled extensions
196         "profile-3": ["@_newdeck", "@_smartsyntax", "@_fit-fs", "@_simplemath", "@_clone", "@_goto", "@_progress", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg",
197                       "@_metadata", "@_attribution", "@_container-styling", "@_timekeeper"],
198         /// profile-4: big profile (as profile 3) but with the smarkdown instead of the smartsyntax
199         "profile-4": ["@_newdeck", "@_smarkdown", "@_fit-fs", "@_simplemath", "@_clone", "@_goto", "@_progress", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg",
200                       "@_metadata", "@_attribution", "@_container-styling", "@_timekeeper"],
201         /// profile-5: use smarkdown and include more useful things (CSS: simple, comments)
202         "profile-5": ["@_newdeck", "@_smarkdown", "@_fit-fs", "@_simplemath", "@_clone", "@_goto", "@_progress", "@_navigation", "@_menu", "@_step", "@_events", "@_anim", "@_svg",
203                       "@_metadata", "@_attribution", "@_container-styling", "@_timekeeper", "@_style-chunks"],
204         dummy: {}
205     };
206
207     var endsInJsOrCss = /\.(css|js)$/;
208
209     // Defensive check that there are no *.js/*.css in the info (as they won't be useable anyways)
210     for (k in info) {
211         if (endsInJsOrCss.test(k)) {
212             alert("Internal problem detected in includedeck: '" + k + "' won't be useable.");
213         }
214     }
215
216     // TODO?: handle default extensions (deck.js/extensions/N/deck.N.{js,css}
217     // TODO?: some should come before others, e.g. anim before svg, (or before any (deck) or before most (loading...))
218
219     // if there are two '#' in the url, take everything after the second as a theme name
220     var forceTheme = null;
221     if ((typeof ACTUALLY_EXPORT_A_LIST_OF_FILES == 'undefined') && (window.location.hash.replace(/[^#]/gi, '').length == 2)) {
222         var theme = window.location.hash.replace(/^.*#/gi, '')
223         var base = window.location.hash.replace(/#[^#]*$/gi, '')
224         forceTheme = theme;
225         window.location.hash = base;
226     }
227
228     var toLoad = [];
229     var addInfo = function(k) {
230         if (k.substring(0, 6) == "theme:") {
231             k = k.substring(6)
232             if (forceTheme) { // replace by the url forced theme (works only with default themes...
233                 k = forceTheme
234             }
235             if (k.substring(0, 2) == "x:") {
236                 k = k.substring(2)
237                 toLoad = toLoad.concat(prefix + "/deck.js-theme-builder/" + k + ".css");
238             } else {
239                 toLoad = toLoad.concat(prefix + "/themes/style/" + k + ".css");
240             }
241             return;
242         }
243         if (k.substring(0, 10) == "extension:") {
244             toLoad = toLoad.concat(prefix + "/extensions/" + k.substring(10));
245             return;
246         }
247         if (endsInJsOrCss.test(k)) {
248             toLoad = toLoad.concat(k);
249             return;
250         }
251         var closure = function(wh, e) { return function () { cb.generic(wh, e); } };
252         for (i in info[k]) {
253             if (info[k][i].substring(0,2) == "@_") {
254                 var e = info[k][i].substring(2);
255                 if (cb.hasGeneric) toLoad = toLoad.concat(closure("BEFORE", e));
256                 addInfo(e);
257                 if (cb.hasGeneric) toLoad = toLoad.concat(closure("AFTER", e));
258             } else {
259                 toLoad = toLoad.concat(info[k][i]);
260             }
261         }
262     }
263
264     for (i in modules) {
265         addInfo(modules[i]);
266     }
267
268     if (typeof ACTUALLY_EXPORT_A_LIST_OF_FILES !== 'undefined') {
269         return toLoad;
270     }
271
272     { // First insert a CSS, just to fit modernizr
273         var c = document.createElement("style");
274         c.type = "text/css";
275         if (typeof ACTUALLY_FILL_CSS !== 'undefined') {
276             ACTUALLY_FILL_CSS(c);
277         }
278         document.getElementsByTagName("head")[0].appendChild(c);
279     }
280     
281     // custom adapter function to split the load list at each function and call by head.js by block (need to end with a function)
282     // in the end, for IE9 compat, we load everything one by one... maybe switching to lazyload.js would avoid needing this.
283     var loadsAndCalls = function(l, stack) {
284         stack = stack || [];
285         if (l.length == 0) return;
286         if ("string" !== typeof l[0]) {
287             l[0]();
288             loadsAndCalls(l.slice(1));
289         } else {
290             head.js(l[0], function() {
291                 loadsAndCalls(l.slice(1));
292             });
293         }
294     }
295     cb.beforeLoad();
296     loadsAndCalls(toLoad.concat(function() {
297         $(function() {
298             var doIt = function() {
299                 cb.beforeInit();
300                 window.defaultDeckCallIsAnError = true;
301                 $.deck('init', conf);
302                 cb.afterInit();
303                 cb.atExit();
304             };
305             // delay and callback logic
306             cb.beforeDelay();
307             if (initDelay) {
308                 setTimeout(doIt, initDelay);
309             } else {
310                 doIt();
311             }
312         });
313     }));
314 }
315
316
317 /*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
318 //@ sourceMappingURL=jquery-1.10.2.min.map
319 */
320 (function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.2",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav></:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t
321 }({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Ct=/^(?:checkbox|radio)$/i,Nt=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle);
322 u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=un(e,t),Pt.detach()),Gt[e]=n),n}function un(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,n){x.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(x.css(e,"display"))?x.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x.support.opacity||(x.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=x.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===x.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,n){return n?x.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,n){x.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?x(e).position()[n]+"px":r):t}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!x.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||x.css(e,"display"))},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(x.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Ct.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),x.param=function(e,n){var r,i=[],o=function(e,t){t=x.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var mn,yn,vn=x.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Cn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Nn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=x.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=o.href}catch(Ln){yn=a.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(T)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(l){var u;return o[l]=!0,x.each(e[l]||[],function(e,l){var c=l(n,r,i);return"string"!=typeof c||a||o[c]?a?!(u=c):t:(n.dataTypes.unshift(c),s(c),!1)}),u}return s(n.dataTypes[0])||!o["*"]&&s("*")}function _n(e,n){var r,i,o=x.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,l=e.indexOf(" ");return l>=0&&(i=e.slice(l,e.length),e=e.slice(0,l)),x.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&x.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?x("<div>").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?"80":"443"))===(mn[3]||("http:"===mn[1]?"80":"443")))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Fn.push(o)),s&&x.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(a=n.start=+a||+r||0,n.unit=o,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);(i||x._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=x.timers,a=x._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,x.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window);
323 /* Modernizr 2.0.6 (Custom Build) | MIT & BSD
324  * Contains: fontface | backgroundsize | borderimage | borderradius | boxshadow | flexbox | hsla | multiplebgs | opacity | rgba | textshadow | cssanimations | csscolumns | generatedcontent | cssgradients | cssreflections | csstransforms | csstransforms3d | csstransitions | applicationcache | canvas | canvastext | draganddrop | hashchange | history | audio | video | indexeddb | input | inputtypes | localstorage | postmessage | sessionstorage | websockets | websqldatabase | webworkers | geolocation | inlinesvg | smil | svg | svgclippaths | touch | webgl | iepp | cssclasses | addtest | teststyles | testprop | testallprops | hasevent | prefixes | domprefixes | load
325  */
326 ;window.Modernizr=function(a,b,c){function H(){e.input=function(a){for(var b=0,c=a.length;b<c;b++)t[a[b]]=a[b]in l;return t}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),e.inputtypes=function(a){for(var d=0,e,f,h,i=a.length;d<i;d++)l.setAttribute("type",f=a[d]),e=l.type!=="text",e&&(l.value=m,l.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(f)&&l.style.WebkitAppearance!==c?(g.appendChild(l),h=b.defaultView,e=h.getComputedStyle&&h.getComputedStyle(l,null).WebkitAppearance!=="textfield"&&l.offsetHeight!==0,g.removeChild(l)):/^(search|tel)$/.test(f)||(/^(url|email)$/.test(f)?e=l.checkValidity&&l.checkValidity()===!1:/^color$/.test(f)?(g.appendChild(l),g.offsetWidth,e=l.value!=m,g.removeChild(l)):e=l.value!=m)),s[a[d]]=!!e;return s}("search tel url email datetime date month week time datetime-local number range color".split(" "))}function F(a,b){var c=a.charAt(0).toUpperCase()+a.substr(1),d=(a+" "+p.join(c+" ")+c).split(" ");return E(d,b)}function E(a,b){for(var d in a)if(k[a[d]]!==c)return b=="pfx"?a[d]:!0;return!1}function D(a,b){return!!~(""+a).indexOf(b)}function C(a,b){return typeof a===b}function B(a,b){return A(o.join(a+";")+(b||""))}function A(a){k.cssText=a}var d="2.0.6",e={},f=!0,g=b.documentElement,h=b.head||b.getElementsByTagName("head")[0],i="modernizr",j=b.createElement(i),k=j.style,l=b.createElement("input"),m=":)",n=Object.prototype.toString,o=" -webkit- -moz- -o- -ms- -khtml- ".split(" "),p="Webkit Moz O ms Khtml".split(" "),q={svg:"http://www.w3.org/2000/svg"},r={},s={},t={},u=[],v=function(a,c,d,e){var f,h,j,k=b.createElement("div");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:i+(d+1),k.appendChild(j);f=["&shy;","<style>",a,"</style>"].join(""),k.id=i,k.innerHTML+=f,g.appendChild(k),h=c(k,a),k.parentNode.removeChild(k);return!!h},w=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=C(e[d],"function"),C(e[d],c)||(e[d]=c),e.removeAttribute(d))),e=null;return f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),x,y={}.hasOwnProperty,z;!C(y,c)&&!C(y.call,c)?z=function(a,b){return y.call(a,b)}:z=function(a,b){return b in a&&C(a.constructor.prototype[b],c)};var G=function(c,d){var f=c.join(""),g=d.length;v(f,function(c,d){var f=b.styleSheets[b.styleSheets.length-1],h=f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"",i=c.childNodes,j={};while(g--)j[i[g].id]=i[g];e.touch="ontouchstart"in a||j.touch.offsetTop===9,e.csstransforms3d=j.csstransforms3d.offsetLeft===9,e.generatedcontent=j.generatedcontent.offsetHeight>=1,e.fontface=/src/i.test(h)&&h.indexOf(d.split(" ")[0])===0},g,d)}(['@font-face {font-family:"font";src:url("https://")}',["@media (",o.join("touch-enabled),("),i,")","{#touch{top:9px;position:absolute}}"].join(""),["@media (",o.join("transform-3d),("),i,")","{#csstransforms3d{left:9px;position:absolute}}"].join(""),['#generatedcontent:after{content:"',m,'";visibility:hidden}'].join("")],["fontface","touch","csstransforms3d","generatedcontent"]);r.flexbox=function(){function c(a,b,c,d){a.style.cssText=o.join(b+":"+c+";")+(d||"")}function a(a,b,c,d){b+=":",a.style.cssText=(b+o.join(c+";"+b)).slice(0,-b.length)+(d||"")}var d=b.createElement("div"),e=b.createElement("div");a(d,"display","box","width:42px;padding:0;"),c(e,"box-flex","1","width:10px;"),d.appendChild(e),g.appendChild(d);var f=e.offsetWidth===42;d.removeChild(e),g.removeChild(d);return f},r.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},r.canvastext=function(){return!!e.canvas&&!!C(b.createElement("canvas").getContext("2d").fillText,"function")},r.webgl=function(){return!!a.WebGLRenderingContext},r.touch=function(){return e.touch},r.geolocation=function(){return!!navigator.geolocation},r.postmessage=function(){return!!a.postMessage},r.websqldatabase=function(){var b=!!a.openDatabase;return b},r.indexedDB=function(){for(var b=-1,c=p.length;++b<c;)if(a[p[b].toLowerCase()+"IndexedDB"])return!0;return!!a.indexedDB},r.hashchange=function(){return w("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},r.history=function(){return!!a.history&&!!history.pushState},r.draganddrop=function(){return w("dragstart")&&w("drop")},r.websockets=function(){for(var b=-1,c=p.length;++b<c;)if(a[p[b]+"WebSocket"])return!0;return"WebSocket"in a},r.rgba=function(){A("background-color:rgba(150,255,150,.5)");return D(k.backgroundColor,"rgba")},r.hsla=function(){A("background-color:hsla(120,40%,100%,.5)");return D(k.backgroundColor,"rgba")||D(k.backgroundColor,"hsla")},r.multiplebgs=function(){A("background:url(https://),url(https://),red url(https://)");return/(url\s*\(.*?){3}/.test(k.background)},r.backgroundsize=function(){return F("backgroundSize")},r.borderimage=function(){return F("borderImage")},r.borderradius=function(){return F("borderRadius")},r.boxshadow=function(){return F("boxShadow")},r.textshadow=function(){return b.createElement("div").style.textShadow===""},r.opacity=function(){B("opacity:.55");return/^0.55$/.test(k.opacity)},r.cssanimations=function(){return F("animationName")},r.csscolumns=function(){return F("columnCount")},r.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";A((a+o.join(b+a)+o.join(c+a)).slice(0,-a.length));return D(k.backgroundImage,"gradient")},r.cssreflections=function(){return F("boxReflect")},r.csstransforms=function(){return!!E(["transformProperty","WebkitTransform","MozTransform","OTransform","msTransform"])},r.csstransforms3d=function(){var a=!!E(["perspectiveProperty","WebkitPerspective","MozPerspective","OPerspective","msPerspective"]);a&&"webkitPerspective"in g.style&&(a=e.csstransforms3d);return a},r.csstransitions=function(){return F("transitionProperty")},r.fontface=function(){return e.fontface},r.generatedcontent=function(){return e.generatedcontent},r.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType){c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"');var d='video/mp4; codecs="avc1.42E01E';c.h264=a.canPlayType(d+'"')||a.canPlayType(d+', mp4a.40.2"'),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"')}}catch(e){}return c},r.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"'),c.mp3=a.canPlayType("audio/mpeg;"),c.wav=a.canPlayType('audio/wav; codecs="1"'),c.m4a=a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")}catch(d){}return c},r.localstorage=function(){try{return!!localStorage.getItem}catch(a){return!1}},r.sessionstorage=function(){try{return!!sessionStorage.getItem}catch(a){return!1}},r.webworkers=function(){return!!a.Worker},r.applicationcache=function(){return!!a.applicationCache},r.svg=function(){return!!b.createElementNS&&!!b.createElementNS(q.svg,"svg").createSVGRect},r.inlinesvg=function(){var a=b.createElement("div");a.innerHTML="<svg/>";return(a.firstChild&&a.firstChild.namespaceURI)==q.svg},r.smil=function(){return!!b.createElementNS&&/SVG/.test(n.call(b.createElementNS(q.svg,"animate")))},r.svgclippaths=function(){return!!b.createElementNS&&/SVG/.test(n.call(b.createElementNS(q.svg,"clipPath")))};for(var I in r)z(r,I)&&(x=I.toLowerCase(),e[x]=r[I](),u.push((e[x]?"":"no-")+x));e.input||H(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)z(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return;b=typeof b=="boolean"?b:!!b(),g.className+=" "+(b?"":"no-")+a,e[a]=b}return e},A(""),j=l=null,a.attachEvent&&function(){var a=b.createElement("div");a.innerHTML="<elem></elem>";return a.childNodes.length!==1}()&&function(a,b){function s(a){var b=-1;while(++b<g)a.createElement(f[b])}a.iepp=a.iepp||{};var d=a.iepp,e=d.html5elements||"abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",f=e.split("|"),g=f.length,h=new RegExp("(^|\\s)("+e+")","gi"),i=new RegExp("<(/*)("+e+")","gi"),j=/^\s*[\{\}]\s*$/,k=new RegExp("(^|[^\\n]*?\\s)("+e+")([^\\n]*)({[\\n\\w\\W]*?})","gi"),l=b.createDocumentFragment(),m=b.documentElement,n=m.firstChild,o=b.createElement("body"),p=b.createElement("style"),q=/print|all/,r;d.getCSS=function(a,b){if(a+""===c)return"";var e=-1,f=a.length,g,h=[];while(++e<f){g=a[e];if(g.disabled)continue;b=g.media||b,q.test(b)&&h.push(d.getCSS(g.imports,b),g.cssText),b="all"}return h.join("")},d.parseCSS=function(a){var b=[],c;while((c=k.exec(a))!=null)b.push(((j.exec(c[1])?"\n":c[1])+c[2]+c[3]).replace(h,"$1.iepp_$2")+c[4]);return b.join("\n")},d.writeHTML=function(){var a=-1;r=r||b.body;while(++a<g){var c=b.getElementsByTagName(f[a]),d=c.length,e=-1;while(++e<d)c[e].className.indexOf("iepp_")<0&&(c[e].className+=" iepp_"+f[a])}l.appendChild(r),m.appendChild(o),o.className=r.className,o.id=r.id,o.innerHTML=r.innerHTML.replace(i,"<$1font")},d._beforePrint=function(){p.styleSheet.cssText=d.parseCSS(d.getCSS(b.styleSheets,"all")),d.writeHTML()},d.restoreHTML=function(){o.innerHTML="",m.removeChild(o),m.appendChild(r)},d._afterPrint=function(){d.restoreHTML(),p.styleSheet.cssText=""},s(b),s(l);d.disablePP||(n.insertBefore(p,n.firstChild),p.media="print",p.className="iepp-printshim",a.attachEvent("onbeforeprint",d._beforePrint),a.attachEvent("onafterprint",d._afterPrint))}(a,b),e._version=d,e._prefixes=o,e._domPrefixes=p,e.hasEvent=w,e.testProp=function(a){return E([a])},e.testAllProps=F,e.testStyles=v,g.className=g.className.replace(/\bno-js\b/,"")+(f?" js "+u.join(" "):"");return e}(this,this.document),function(a,b,c){function k(a){return!a||a=="loaded"||a=="complete"}function j(){var a=1,b=-1;while(p.length- ++b)if(p[b].s&&!(a=p[b].r))break;a&&g()}function i(a){var c=b.createElement("script"),d;c.src=a.s,c.onreadystatechange=c.onload=function(){!d&&k(c.readyState)&&(d=1,j(),c.onload=c.onreadystatechange=null)},m(function(){d||(d=1,j())},H.errorTimeout),a.e?c.onload():n.parentNode.insertBefore(c,n)}function h(a){var c=b.createElement("link"),d;c.href=a.s,c.rel="stylesheet",c.type="text/css";if(!a.e&&(w||r)){var e=function(a){m(function(){if(!d)try{a.sheet.cssRules.length?(d=1,j()):e(a)}catch(b){b.code==1e3||b.message=="security"||b.message=="denied"?(d=1,m(function(){j()},0)):e(a)}},0)};e(c)}else c.onload=function(){d||(d=1,m(function(){j()},0))},a.e&&c.onload();m(function(){d||(d=1,j())},H.errorTimeout),!a.e&&n.parentNode.insertBefore(c,n)}function g(){var a=p.shift();q=1,a?a.t?m(function(){a.t=="c"?h(a):i(a)},0):(a(),j()):q=0}function f(a,c,d,e,f,h){function i(){!o&&k(l.readyState)&&(r.r=o=1,!q&&j(),l.onload=l.onreadystatechange=null,m(function(){u.removeChild(l)},0))}var l=b.createElement(a),o=0,r={t:d,s:c,e:h};l.src=l.data=c,!s&&(l.style.display="none"),l.width=l.height="0",a!="object"&&(l.type=d),l.onload=l.onreadystatechange=i,a=="img"?l.onerror=i:a=="script"&&(l.onerror=function(){r.e=r.r=1,g()}),p.splice(e,0,r),u.insertBefore(l,s?null:n),m(function(){o||(u.removeChild(l),r.r=r.e=o=1,j())},H.errorTimeout)}function e(a,b,c){var d=b=="c"?z:y;q=0,b=b||"j",C(a)?f(d,a,b,this.i++,l,c):(p.splice(this.i++,0,a),p.length==1&&g());return this}function d(){var a=H;a.loader={load:e,i:0};return a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=r&&!s,u=s?l:n.parentNode,v=a.opera&&o.call(a.opera)=="[object Opera]",w="webkitAppearance"in l.style,x=w&&"async"in b.createElement("script"),y=r?"object":v||x?"img":"script",z=w?"img":y,A=Array.isArray||function(a){return o.call(a)=="[object Array]"},B=function(a){return Object(a)===a},C=function(a){return typeof a=="string"},D=function(a){return o.call(a)=="[object Function]"},E=[],F={},G,H;H=function(a){function f(a){var b=a.split("!"),c=E.length,d=b.pop(),e=b.length,f={url:d,origUrl:d,prefixes:b},g,h;for(h=0;h<e;h++)g=F[b[h]],g&&(f=g(f));for(h=0;h<c;h++)f=E[h](f);return f}function e(a,b,e,g,h){var i=f(a),j=i.autoCallback;if(!i.bypass){b&&(b=D(b)?b:b[a]||b[g]||b[a.split("/").pop().split("?")[0]]);if(i.instead)return i.instead(a,b,e,g,h);e.load(i.url,i.forceCSS||!i.forceJS&&/css$/.test(i.url)?"c":c,i.noexec),(D(b)||D(j))&&e.load(function(){d(),b&&b(i.origUrl,h,g),j&&j(i.origUrl,h,g)})}}function b(a,b){function c(a){if(C(a))e(a,h,b,0,d);else if(B(a))for(i in a)a.hasOwnProperty(i)&&e(a[i],h,b,i,d)}var d=!!a.test,f=d?a.yep:a.nope,g=a.load||a.both,h=a.callback,i;c(f),c(g),a.complete&&b.load(a.complete)}var g,h,i=this.yepnope.loader;if(C(a))e(a,0,i,0);else if(A(a))for(g=0;g<a.length;g++)h=a[g],C(h)?e(h,0,i,0):A(h)?H(h):B(h)&&b(h,i);else B(a)&&b(a,i)},H.addPrefix=function(a,b){F[a]=b},H.addFilter=function(a){E.push(a)},H.errorTimeout=1e4,b.readyState==null&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",G=function(){b.removeEventListener("DOMContentLoaded",G,0),b.readyState="complete"},0)),a.yepnope=d()}(this,this.document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))};
327 /*!
328 Deck JS - deck.core
329 Copyright (c) 2011-2014 Caleb Troughton
330 Dual licensed under the MIT license.
331 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
332 */
333
334 /*
335 The deck.core module provides all the basic functionality for creating and
336 moving through a deck.  It does so by applying classes to indicate the state of
337 the deck and its slides, allowing CSS to take care of the visual representation
338 of each state.  It also provides methods for navigating the deck and inspecting
339 its state, as well as basic key bindings for going to the next and previous
340 slides.  More functionality is provided by wholly separate extension modules
341 that use the API provided by core.
342 */
343 (function($, undefined) {
344   var slides, currentIndex, $container, $fragmentLinks;
345
346   var events = {
347     /*
348     This event fires at the beginning of a slide change, before the actual
349     change occurs. Its purpose is to give extension authors a way to prevent
350     the slide change from occuring. This is done by calling preventDefault
351     on the event object within this event. If that is done, the deck.change
352     event will never be fired and the slide will not change.
353     */
354     beforeChange: 'deck.beforeChange',
355
356     /*
357     This event fires whenever the current slide changes, whether by way of
358     next, prev, or go. The callback function is passed two parameters, from
359     and to, equal to the indices of the old slide and the new slide
360     respectively. If preventDefault is called on the event within this handler
361     the slide change does not occur.
362
363     $(document).bind('deck.change', function(event, from, to) {
364        alert('Moving from slide ' + from + ' to ' + to);
365     });
366     */
367     change: 'deck.change',
368
369     /*
370     This event fires at the beginning of deck initialization. This event makes
371     a good hook for preprocessing extensions looking to modify the DOM before
372     the deck is fully initialized. It is also possible to halt the deck.init
373     event from firing while you do things in beforeInit. This can be done by
374     calling lockInit on the event object passed to this event. The init can be
375     released by calling releaseInit.
376
377     $(document).bind('deck.beforeInit', function(event) {
378       event.lockInit(); // halts deck.init event
379       window.setTimeout(function() {
380         event.releaseInit(); // deck.init will now fire 2 seconds later
381       }, 2000);
382     });
383
384     The init event will be fired regardless of locks after
385     options.initLockTimeout milliseconds.
386     */
387     beforeInitialize: 'deck.beforeInit',
388
389     /*
390     This event fires at the end of deck initialization. Extensions should
391     implement any code that relies on user extensible options (key bindings,
392     element selectors, classes) within a handler for this event. Native
393     events associated with Deck JS should be scoped under a .deck event
394     namespace, as with the example below:
395
396     var $d = $(document);
397     $.deck.defaults.keys.myExtensionKeycode = 70; // 'h'
398     $d.bind('deck.init', function() {
399        $d.bind('keydown.deck', function(event) {
400           if (event.which === $.deck.getOptions().keys.myExtensionKeycode) {
401              // Rock out
402           }
403        });
404     });
405     */
406     initialize: 'deck.init'
407   };
408
409   var options = {};
410   var $document = $(document);
411   var $window = $(window);
412   var stopPropagation = function(event) {
413     event.stopPropagation();
414   };
415
416   var updateContainerState = function() {
417     var oldIndex = $container.data('onSlide');
418     $container.removeClass(options.classes.onPrefix + oldIndex);
419     $container.addClass(options.classes.onPrefix + currentIndex);
420     $container.data('onSlide', currentIndex);
421   };
422
423   var updateChildCurrent = function() {
424     var $oldCurrent = $('.' + options.classes.current);
425     var $oldParents = $oldCurrent.parentsUntil(options.selectors.container);
426     var $newCurrent = slides[currentIndex];
427     var $newParents = $newCurrent.parentsUntil(options.selectors.container);
428     $oldParents.removeClass(options.classes.childCurrent);
429     $newParents.addClass(options.classes.childCurrent);
430   };
431
432   var removeOldSlideStates = function() {
433     var $all = $();
434     $.each(slides, function(i, el) {
435       $all = $all.add(el);
436     });
437     $all.removeClass([
438       options.classes.before,
439       options.classes.previous,
440       options.classes.current,
441       options.classes.next,
442       options.classes.after
443     ].join(' '));
444   };
445
446   var addNewSlideStates = function() {
447     slides[currentIndex].addClass(options.classes.current);
448     if (currentIndex > 0) {
449       slides[currentIndex-1].addClass(options.classes.previous);
450     }
451     if (currentIndex + 1 < slides.length) {
452       slides[currentIndex+1].addClass(options.classes.next);
453     }
454     if (currentIndex > 1) {
455       $.each(slides.slice(0, currentIndex - 1), function(i, $slide) {
456         $slide.addClass(options.classes.before);
457       });
458     }
459     if (currentIndex + 2 < slides.length) {
460       $.each(slides.slice(currentIndex+2), function(i, $slide) {
461         $slide.addClass(options.classes.after);
462       });
463     }
464   };
465
466   var setAriaHiddens = function() {
467     $(options.selectors.slides).each(function() {
468       var $slide = $(this);
469       var isSub = $slide.closest('.' + options.classes.childCurrent).length;
470       var isBefore = $slide.hasClass(options.classes.before) && !isSub;
471       var isPrevious = $slide.hasClass(options.classes.previous) && !isSub;
472       var isNext = $slide.hasClass(options.classes.next);
473       var isAfter = $slide.hasClass(options.classes.after);
474       var ariaHiddenValue = isBefore || isPrevious || isNext || isAfter;
475       $slide.attr('aria-hidden', ariaHiddenValue);
476     });
477   };
478
479   var updateStates = function() {
480     updateContainerState();
481     updateChildCurrent();
482     removeOldSlideStates();
483     addNewSlideStates();
484     if (options.setAriaHiddens) {
485       setAriaHiddens();
486     }
487   };
488
489   var initSlidesArray = function(elements) {
490     if ($.isArray(elements)) {
491       $.each(elements, function(i, element) {
492         slides.push($(element));
493       });
494     }
495     else {
496       $(elements).each(function(i, element) {
497         slides.push($(element));
498       });
499     }
500   };
501
502   var bindKeyEvents = function() {
503     var editables = [
504       'input',
505       'textarea',
506       'select',
507       'button',
508       'meter',
509       'progress',
510       '[contentEditable]'
511     ].join(', ');
512
513     $document.unbind('keydown.deck').bind('keydown.deck', function(event) {
514       var isNext = event.which === options.keys.next;
515       var isPrev = event.which === options.keys.previous;
516       isNext = isNext || $.inArray(event.which, options.keys.next) > -1;
517       isPrev = isPrev || $.inArray(event.which, options.keys.previous) > -1;
518
519       if (isNext) {
520         methods.next();
521         event.preventDefault();
522       }
523       else if (isPrev) {
524         methods.prev();
525         event.preventDefault();
526       }
527     });
528
529     $document.undelegate(editables, 'keydown.deck', stopPropagation);
530     $document.delegate(editables, 'keydown.deck', stopPropagation);
531   };
532
533   var bindTouchEvents = function() {
534     var startTouch;
535     var direction = options.touch.swipeDirection;
536     var tolerance = options.touch.swipeTolerance;
537     var listenToHorizontal = ({ both: true, horizontal: true })[direction];
538     var listenToVertical = ({ both: true, vertical: true })[direction];
539
540     $container.unbind('touchstart.deck');
541     $container.bind('touchstart.deck', function(event) {
542       if (!startTouch) {
543         startTouch = $.extend({}, event.originalEvent.targetTouches[0]);
544       }
545     });
546
547     $container.unbind('touchmove.deck');
548     $container.bind('touchmove.deck', function(event) {
549       $.each(event.originalEvent.changedTouches, function(i, touch) {
550         if (!startTouch || touch.identifier !== startTouch.identifier) {
551           return true;
552         }
553         var xDistance = touch.screenX - startTouch.screenX;
554         var yDistance = touch.screenY - startTouch.screenY;
555         var leftToRight = xDistance > tolerance && listenToHorizontal;
556         var rightToLeft = xDistance < -tolerance && listenToHorizontal;
557         var topToBottom = yDistance > tolerance && listenToVertical;
558         var bottomToTop = yDistance < -tolerance && listenToVertical;
559
560         if (leftToRight || topToBottom) {
561           $.deck('prev');
562           startTouch = undefined;
563         }
564         else if (rightToLeft || bottomToTop) {
565           $.deck('next');
566           startTouch = undefined;
567         }
568         return false;
569       });
570
571       if (listenToVertical) {
572         event.preventDefault();
573       }
574     });
575
576     $container.unbind('touchend.deck');
577     $container.bind('touchend.deck', function(event) {
578       $.each(event.originalEvent.changedTouches, function(i, touch) {
579         if (startTouch && touch.identifier === startTouch.identifier) {
580           startTouch = undefined;
581         }
582       });
583     });
584   };
585
586   var indexInBounds = function(index) {
587     return typeof index === 'number' && index >=0 && index < slides.length;
588   };
589
590   var createBeforeInitEvent = function() {
591     var event = $.Event(events.beforeInitialize);
592     event.locks = 0;
593     event.done = $.noop;
594     event.lockInit = function() {
595       ++event.locks;
596     };
597     event.releaseInit = function() {
598       --event.locks;
599       if (!event.locks) {
600         event.done();
601       }
602     };
603     return event;
604   };
605
606   var goByHash = function(str) {
607     var id = str.substr(str.indexOf("#") + 1);
608
609     $.each(slides, function(i, $slide) {
610       if ($slide.attr('id') === id) {
611         $.deck('go', i);
612         return false;
613       }
614     });
615
616     // If we don't set these to 0 the container scrolls due to hashchange
617     if (options.preventFragmentScroll) {
618       $.deck('getContainer').scrollLeft(0).scrollTop(0);
619     }
620   };
621
622   var assignSlideId = function(i, $slide) {
623     var currentId = $slide.attr('id');
624     var previouslyAssigned = $slide.data('deckAssignedId') === currentId;
625     if (!currentId || previouslyAssigned) {
626       $slide.attr('id', options.hashPrefix + i);
627       $slide.data('deckAssignedId', options.hashPrefix + i);
628     }
629   };
630
631   var removeContainerHashClass = function(id) {
632     $container.removeClass(options.classes.onPrefix + id);
633   };
634
635   var addContainerHashClass = function(id) {
636     $container.addClass(options.classes.onPrefix + id);
637   };
638
639   var setupHashBehaviors = function() {
640     $fragmentLinks = $();
641     $.each(slides, function(i, $slide) {
642       var hash, altHash;
643
644       assignSlideId(i, $slide);
645       hash = '#' + $slide.attr('id');
646       altHash = '#/' + $slide.attr('id');
647       if (hash === window.location.hash || altHash === window.location.hash) {
648         setTimeout(function() {
649           $.deck('go', i);
650         }, 1);
651       }
652       $fragmentLinks = $fragmentLinks.add('a[href="' + hash + '"]');
653     });
654
655     if (slides.length) {
656       addContainerHashClass($.deck('getSlide').attr('id'));
657     };
658   };
659
660   var changeHash = function(from, to) {
661     var hash = '#' + $.deck('getSlide', to).attr('id');
662     var hashPath = window.location.href.replace(/#.*/, '') + hash;
663
664     removeContainerHashClass($.deck('getSlide', from).attr('id'));
665     addContainerHashClass($.deck('getSlide', to).attr('id'));
666     if (Modernizr.history) {
667       window.history.replaceState({}, "", hashPath);
668     }
669   };
670
671   /* Methods exposed in the jQuery.deck namespace */
672   var methods = {
673
674     /*
675     jQuery.deck(selector, options)
676
677     selector: string | jQuery | array
678     options: object, optional
679
680     Initializes the deck, using each element matched by selector as a slide.
681     May also be passed an array of string selectors or jQuery objects, in
682     which case each selector in the array is considered a slide. The second
683     parameter is an optional options object which will extend the default
684     values.
685
686     Users may also pass only an options object to init. In this case the slide
687     selector will be options.selectors.slides which defaults to .slide.
688
689     $.deck('.slide');
690
691     or
692
693     $.deck([
694        '#first-slide',
695        '#second-slide',
696        '#etc'
697     ]);
698     */
699     init: function(opts) {
700       var beforeInitEvent = createBeforeInitEvent();
701       var overrides = opts;
702
703       if (!$.isPlainObject(opts)) {
704         overrides = arguments[1] || {};
705         $.extend(true, overrides, {
706           selectors: {
707             slides: arguments[0]
708           }
709         });
710       }
711
712       options = $.extend(true, {}, $.deck.defaults, overrides);
713       slides = [];
714       currentIndex = 0;
715       $container = $(options.selectors.container);
716
717       // Hide the deck while states are being applied to kill transitions
718       $container.addClass(options.classes.loading);
719
720       // populate the array of slides for pre-init
721       initSlidesArray(options.selectors.slides);
722       // Pre init event for preprocessing hooks
723       beforeInitEvent.done = function() {
724         // reInitSlidesArray is meant only for beforeInit
725         methods['reInitSlidesArray'] = function() {
726             alert('Deck.js method "reInitSlidesArray" is meant to be called in the beforeInit phase only.');
727         }
728         // re-populate the array of slides
729         slides = [];
730         initSlidesArray(options.selectors.slides);
731         setupHashBehaviors();
732         bindKeyEvents();
733         bindTouchEvents();
734         $container.scrollLeft(0).scrollTop(0);
735
736         if (slides.length) {
737           updateStates();
738         }
739
740         // Show deck again now that slides are in place
741         $container.removeClass(options.classes.loading);
742         $document.trigger(events.initialize);
743       };
744
745       beforeInitEvent.lockInit();
746       $document.trigger(beforeInitEvent);
747       beforeInitEvent.releaseInit();
748       window.setTimeout(function() {
749         if (beforeInitEvent.locks) {
750           if (window.console) {
751             window.console.warn('Something locked deck initialization\
752               without releasing it before the timeout. Proceeding with\
753               initialization anyway.');
754           }
755           beforeInitEvent.done();
756         }
757       }, options.initLockTimeout);
758     },
759
760     /*
761     jQuery.deck('reInitSlidesArray')
762     
763     Force a recomputation of the "slides" array. This method is meant
764     to be used by extensions that generate new slides in the
765     beforeInit phase.
766     */
767
768     reInitSlidesArray: function() {
769         slides = [];
770         initSlidesArray(options.selectors.slides);
771     },
772
773     /*
774     jQuery.deck('go', index)
775
776     index: integer | string
777
778     Moves to the slide at the specified index if index is a number. Index is
779     0-based, so $.deck('go', 0); will move to the first slide. If index is a
780     string this will move to the slide with the specified id. If index is out
781     of bounds or doesn't match a slide id the call is ignored.
782     */
783     go: function(indexOrId) {
784       var beforeChangeEvent = $.Event(events.beforeChange);
785       var index;
786
787       /* Number index, easy. */
788       if (indexInBounds(indexOrId)) {
789         index = indexOrId;
790       }
791       /* Id string index, search for it and set integer index */
792       else if (typeof indexOrId === 'string') {
793         $.each(slides, function(i, $slide) {
794           if ($slide.attr('id') === indexOrId) {
795             index = i;
796             return false;
797           }
798         });
799       }
800       if (typeof index === 'undefined') {
801         return;
802       }
803
804       /* Trigger beforeChange. If nothing prevents the change, trigger
805       the slide change. */
806       $document.trigger(beforeChangeEvent, [currentIndex, index]);
807       if (!beforeChangeEvent.isDefaultPrevented()) {
808         $document.trigger(events.change, [currentIndex, index]);
809         changeHash(currentIndex, index);
810         currentIndex = index;
811         updateStates();
812       }
813     },
814
815     /*
816     jQuery.deck('next')
817
818     Moves to the next slide. If the last slide is already active, the call
819     is ignored.
820     */
821     next: function() {
822       methods.go(currentIndex+1);
823     },
824
825     /*
826     jQuery.deck('prev')
827
828     Moves to the previous slide. If the first slide is already active, the
829     call is ignored.
830     */
831     prev: function() {
832       methods.go(currentIndex-1);
833     },
834
835     /*
836     jQuery.deck('getSlide', index)
837
838     index: integer, optional
839
840     Returns a jQuery object containing the slide at index. If index is not
841     specified, the current slide is returned.
842     */
843     getSlide: function(index) {
844       index = typeof index !== 'undefined' ? index : currentIndex;
845       if (!indexInBounds(index)) {
846         return null;
847       }
848       return slides[index];
849     },
850
851     /*
852     jQuery.deck('getSlides')
853
854     Returns all slides as an array of jQuery objects.
855     */
856     getSlides: function() {
857       return slides;
858     },
859
860     /*
861     jQuery.deck('getTopLevelSlides')
862
863     Returns all slides that are not subslides.
864     */
865     getTopLevelSlides: function() {
866       var topLevelSlides = [];
867       var slideSelector = options.selectors.slides;
868       var subSelector = [slideSelector, slideSelector].join(' ');
869       $.each(slides, function(i, $slide) {
870         if (!$slide.is(subSelector)) {
871           topLevelSlides.push($slide);
872         }
873       });
874       return topLevelSlides;
875     },
876
877     /*
878     jQuery.deck('getNestedSlides', index)
879
880     index: integer, optional
881
882     Returns all the nested slides of the current slide. If index is
883     specified it returns the nested slides of the slide at that index.
884     If there are no nested slides this will return an empty array.
885     */
886     getNestedSlides: function(index) {
887       var targetIndex = index == null ? currentIndex : index;
888       var $targetSlide = $.deck('getSlide', targetIndex);
889       var $nesteds = $targetSlide.find(options.selectors.slides);
890       var nesteds = $nesteds.get();
891       return $.map(nesteds, function(slide, i) {
892         return $(slide);
893       });
894     },
895
896
897     /*
898     jQuery.deck('getContainer')
899
900     Returns a jQuery object containing the deck container as defined by the
901     container option.
902     */
903     getContainer: function() {
904       return $container;
905     },
906
907     /*
908     jQuery.deck('getOptions')
909
910     Returns the options object for the deck, including any overrides that
911     were defined at initialization.
912     */
913     getOptions: function() {
914       return options;
915     },
916
917     /*
918     jQuery.deck('extend', name, method)
919
920     name: string
921     method: function
922
923     Adds method to the deck namespace with the key of name. This doesn’t
924     give access to any private member data â€” public methods must still be
925     used within method â€” but lets extension authors piggyback on the deck
926     namespace rather than pollute jQuery.
927
928     $.deck('extend', 'alert', function(msg) {
929        alert(msg);
930     });
931
932     // Alerts 'boom'
933     $.deck('alert', 'boom');
934     */
935     extend: function(name, method) {
936       methods[name] = method;
937     }
938   };
939
940   /* jQuery extension */
941   $.deck = function(method, arg) {
942     var args = Array.prototype.slice.call(arguments, 1);
943     if (methods[method]) {
944       return methods[method].apply(this, args);
945     }
946     else {
947       if (window.defaultDeckCallIsAnError) {
948         alert("'" + method + "' not found (or meant to be a parameter-less init)");
949       }
950       else {
951         return methods.init(method, arg);
952       }
953     }
954   };
955
956   /*
957   The default settings object for a deck. All deck extensions should extend
958   this object to add defaults for any of their options.
959
960   options.classes.after
961     This class is added to all slides that appear after the 'next' slide.
962
963   options.classes.before
964     This class is added to all slides that appear before the 'previous'
965     slide.
966
967   options.classes.childCurrent
968     This class is added to all elements in the DOM tree between the
969     'current' slide and the deck container. For standard slides, this is
970     mostly seen and used for nested slides.
971
972   options.classes.current
973     This class is added to the current slide.
974
975   options.classes.loading
976     This class is applied to the deck container during loading phases and is
977     primarily used as a way to short circuit transitions between states
978     where such transitions are distracting or unwanted.  For example, this
979     class is applied during deck initialization and then removed to prevent
980     all the slides from appearing stacked and transitioning into place
981     on load.
982
983   options.classes.next
984     This class is added to the slide immediately following the 'current'
985     slide.
986
987   options.classes.onPrefix
988     This prefix, concatenated with the current slide index, is added to the
989     deck container as you change slides.
990
991   options.classes.previous
992     This class is added to the slide immediately preceding the 'current'
993     slide.
994
995   options.selectors.container
996     Elements matched by this CSS selector will be considered the deck
997     container. The deck container is used to scope certain states of the
998     deck, as with the onPrefix option, or with extensions such as deck.goto
999     and deck.menu.
1000
1001   options.selectors.slides
1002     Elements matched by this selector make up the individual deck slides.
1003     If a user chooses to pass the slide selector as the first argument to
1004     $.deck() on initialization it does the same thing as passing in this
1005     option and this option value will be set to the value of that parameter.
1006
1007   options.keys.next
1008     The numeric keycode used to go to the next slide.
1009
1010   options.keys.previous
1011     The numeric keycode used to go to the previous slide.
1012
1013   options.touch.swipeDirection
1014     The direction swipes occur to cause slide changes. Can be 'horizontal',
1015     'vertical', or 'both'. Any other value or a falsy value will disable
1016     swipe gestures for navigation.
1017
1018   options.touch.swipeTolerance
1019     The number of pixels the users finger must travel to produce a swipe
1020     gesture.
1021
1022   options.initLockTimeout
1023     The number of milliseconds the init event will wait for BeforeInit event
1024     locks to be released before firing the init event regardless.
1025
1026   options.hashPrefix
1027     Every slide that does not have an id is assigned one at initialization.
1028     Assigned ids take the form of hashPrefix + slideIndex, e.g., slide-0,
1029     slide-12, etc.
1030
1031   options.preventFragmentScroll
1032     When deep linking to a hash of a nested slide, this scrolls the deck
1033     container to the top, undoing the natural browser behavior of scrolling
1034     to the document fragment on load.
1035
1036   options.setAriaHiddens
1037     When set to true, deck.js will set aria hidden attributes for slides
1038     that do not appear onscreen according to a typical heirarchical
1039     deck structure. You may want to turn this off if you are using a theme
1040     where slides besides the current slide are visible on screen and should
1041     be accessible to screenreaders.
1042   */
1043   $.deck.defaults = {
1044     classes: {
1045       after: 'deck-after',
1046       before: 'deck-before',
1047       childCurrent: 'deck-child-current',
1048       current: 'deck-current',
1049       loading: 'deck-loading',
1050       next: 'deck-next',
1051       onPrefix: 'on-slide-',
1052       previous: 'deck-previous'
1053     },
1054
1055     selectors: {
1056       container: '.deck-container',
1057       slides: '.slide'
1058     },
1059
1060     keys: {
1061       // enter, space, page down, right arrow, down arrow,
1062       next: [13, 32, 34, 39, 40],
1063       // backspace, page up, left arrow, up arrow
1064       previous: [8, 33, 37, 38]
1065     },
1066
1067     touch: {
1068       swipeDirection: 'horizontal',
1069       swipeTolerance: 60
1070     },
1071
1072     initLockTimeout: 10000,
1073     hashPrefix: 'slide-',
1074     preventFragmentScroll: true,
1075     setAriaHiddens: true
1076   };
1077
1078   $document.ready(function() {
1079     $('html').addClass('ready');
1080   });
1081
1082   $window.bind('hashchange.deck', function(event) {
1083     if (event.originalEvent && event.originalEvent.newURL) {
1084       goByHash(event.originalEvent.newURL);
1085     }
1086     else {
1087       goByHash(window.location.hash);
1088     }
1089   });
1090
1091   $window.bind('load.deck', function() {
1092     if (options.preventFragmentScroll) {
1093       $container.scrollLeft(0).scrollTop(0);
1094     }
1095   });
1096 })(jQuery);
1097
1098 // Released under MIT license
1099 // Copyright (c) 2009-2010 Dominic Baggott
1100 // Copyright (c) 2009-2010 Ash Berlin
1101 // Copyright (c) 2011 Christoph Dorn <christoph@christophdorn.com> (http://www.christophdorn.com)
1102
1103 /*jshint browser:true, devel:true */
1104
1105 (function( expose ) {
1106
1107 /**
1108  *  class Markdown
1109  *
1110  *  Markdown processing in Javascript done right. We have very particular views
1111  *  on what constitutes 'right' which include:
1112  *
1113  *  - produces well-formed HTML (this means that em and strong nesting is
1114  *    important)
1115  *
1116  *  - has an intermediate representation to allow processing of parsed data (We
1117  *    in fact have two, both as [JsonML]: a markdown tree and an HTML tree).
1118  *
1119  *  - is easily extensible to add new dialects without having to rewrite the
1120  *    entire parsing mechanics
1121  *
1122  *  - has a good test suite
1123  *
1124  *  This implementation fulfills all of these (except that the test suite could
1125  *  do with expanding to automatically run all the fixtures from other Markdown
1126  *  implementations.)
1127  *
1128  *  ##### Intermediate Representation
1129  *
1130  *  *TODO* Talk about this :) Its JsonML, but document the node names we use.
1131  *
1132  *  [JsonML]: http://jsonml.org/ "JSON Markup Language"
1133  **/
1134 var Markdown = expose.Markdown = function(dialect) {
1135   switch (typeof dialect) {
1136     case "undefined":
1137       this.dialect = Markdown.dialects.Gruber;
1138       break;
1139     case "object":
1140       this.dialect = dialect;
1141       break;
1142     default:
1143       if ( dialect in Markdown.dialects ) {
1144         this.dialect = Markdown.dialects[dialect];
1145       }
1146       else {
1147         throw new Error("Unknown Markdown dialect '" + String(dialect) + "'");
1148       }
1149       break;
1150   }
1151   this.em_state = [];
1152   this.strong_state = [];
1153   this.debug_indent = "";
1154 };
1155
1156 /**
1157  *  parse( markdown, [dialect] ) -> JsonML
1158  *  - markdown (String): markdown string to parse
1159  *  - dialect (String | Dialect): the dialect to use, defaults to gruber
1160  *
1161  *  Parse `markdown` and return a markdown document as a Markdown.JsonML tree.
1162  **/
1163 expose.parse = function( source, dialect ) {
1164   // dialect will default if undefined
1165   var md = new Markdown( dialect );
1166   return md.toTree( source );
1167 };
1168
1169 /**
1170  *  toHTML( markdown, [dialect]  ) -> String
1171  *  toHTML( md_tree ) -> String
1172  *  - markdown (String): markdown string to parse
1173  *  - md_tree (Markdown.JsonML): parsed markdown tree
1174  *
1175  *  Take markdown (either as a string or as a JsonML tree) and run it through
1176  *  [[toHTMLTree]] then turn it into a well-formated HTML fragment.
1177  **/
1178 expose.toHTML = function toHTML( source , dialect , options ) {
1179   var input = expose.toHTMLTree( source , dialect , options );
1180
1181   return expose.renderJsonML( input );
1182 };
1183
1184 /**
1185  *  toHTMLTree( markdown, [dialect] ) -> JsonML
1186  *  toHTMLTree( md_tree ) -> JsonML
1187  *  - markdown (String): markdown string to parse
1188  *  - dialect (String | Dialect): the dialect to use, defaults to gruber
1189  *  - md_tree (Markdown.JsonML): parsed markdown tree
1190  *
1191  *  Turn markdown into HTML, represented as a JsonML tree. If a string is given
1192  *  to this function, it is first parsed into a markdown tree by calling
1193  *  [[parse]].
1194  **/
1195 expose.toHTMLTree = function toHTMLTree( input, dialect , options ) {
1196   // convert string input to an MD tree
1197   if ( typeof input ==="string" ) input = this.parse( input, dialect );
1198
1199   // Now convert the MD tree to an HTML tree
1200
1201   // remove references from the tree
1202   var attrs = extract_attr( input ),
1203       refs = {};
1204
1205   if ( attrs && attrs.references ) {
1206     refs = attrs.references;
1207   }
1208
1209   var html = convert_tree_to_html( input, refs , options );
1210   merge_text_nodes( html );
1211   return html;
1212 };
1213
1214 // For Spidermonkey based engines
1215 function mk_block_toSource() {
1216   return "Markdown.mk_block( " +
1217           uneval(this.toString()) +
1218           ", " +
1219           uneval(this.trailing) +
1220           ", " +
1221           uneval(this.lineNumber) +
1222           " )";
1223 }
1224
1225 // node
1226 function mk_block_inspect() {
1227   var util = require("util");
1228   return "Markdown.mk_block( " +
1229           util.inspect(this.toString()) +
1230           ", " +
1231           util.inspect(this.trailing) +
1232           ", " +
1233           util.inspect(this.lineNumber) +
1234           " )";
1235
1236 }
1237
1238 var mk_block = Markdown.mk_block = function(block, trail, line) {
1239   // Be helpful for default case in tests.
1240   if ( arguments.length == 1 ) trail = "\n\n";
1241
1242   var s = new String(block);
1243   s.trailing = trail;
1244   // To make it clear its not just a string
1245   s.inspect = mk_block_inspect;
1246   s.toSource = mk_block_toSource;
1247
1248   if ( line != undefined )
1249     s.lineNumber = line;
1250
1251   return s;
1252 };
1253
1254 function count_lines( str ) {
1255   var n = 0, i = -1;
1256   while ( ( i = str.indexOf("\n", i + 1) ) !== -1 ) n++;
1257   return n;
1258 }
1259
1260 // Internal - split source into rough blocks
1261 Markdown.prototype.split_blocks = function splitBlocks( input, startLine ) {
1262   input = input.replace(/(\r\n|\n|\r)/g, "\n");
1263   // [\s\S] matches _anything_ (newline or space)
1264   // [^] is equivalent but doesn't work in IEs.
1265   var re = /([\s\S]+?)($|\n#|\n(?:\s*\n|$)+)/g,
1266       blocks = [],
1267       m;
1268
1269   var line_no = 1;
1270
1271   if ( ( m = /^(\s*\n)/.exec(input) ) != null ) {
1272     // skip (but count) leading blank lines
1273     line_no += count_lines( m[0] );
1274     re.lastIndex = m[0].length;
1275   }
1276
1277   while ( ( m = re.exec(input) ) !== null ) {
1278     if (m[2] == "\n#") {
1279       m[2] = "\n";
1280       re.lastIndex--;
1281     }
1282     blocks.push( mk_block( m[1], m[2], line_no ) );
1283     line_no += count_lines( m[0] );
1284   }
1285
1286   return blocks;
1287 };
1288
1289 /**
1290  *  Markdown#processBlock( block, next ) -> undefined | [ JsonML, ... ]
1291  *  - block (String): the block to process
1292  *  - next (Array): the following blocks
1293  *
1294  * Process `block` and return an array of JsonML nodes representing `block`.
1295  *
1296  * It does this by asking each block level function in the dialect to process
1297  * the block until one can. Succesful handling is indicated by returning an
1298  * array (with zero or more JsonML nodes), failure by a false value.
1299  *
1300  * Blocks handlers are responsible for calling [[Markdown#processInline]]
1301  * themselves as appropriate.
1302  *
1303  * If the blocks were split incorrectly or adjacent blocks need collapsing you
1304  * can adjust `next` in place using shift/splice etc.
1305  *
1306  * If any of this default behaviour is not right for the dialect, you can
1307  * define a `__call__` method on the dialect that will get invoked to handle
1308  * the block processing.
1309  */
1310 Markdown.prototype.processBlock = function processBlock( block, next ) {
1311   var cbs = this.dialect.block,
1312       ord = cbs.__order__;
1313
1314   if ( "__call__" in cbs ) {
1315     return cbs.__call__.call(this, block, next);
1316   }
1317
1318   for ( var i = 0; i < ord.length; i++ ) {
1319     //D:this.debug( "Testing", ord[i] );
1320     var res = cbs[ ord[i] ].call( this, block, next );
1321     if ( res ) {
1322       //D:this.debug("  matched");
1323       if ( !isArray(res) || ( res.length > 0 && !( isArray(res[0]) ) ) )
1324         this.debug(ord[i], "didn't return a proper array");
1325       //D:this.debug( "" );
1326       return res;
1327     }
1328   }
1329
1330   // Uhoh! no match! Should we throw an error?
1331   return [];
1332 };
1333
1334 Markdown.prototype.processInline = function processInline( block ) {
1335   return this.dialect.inline.__call__.call( this, String( block ) );
1336 };
1337
1338 /**
1339  *  Markdown#toTree( source ) -> JsonML
1340  *  - source (String): markdown source to parse
1341  *
1342  *  Parse `source` into a JsonML tree representing the markdown document.
1343  **/
1344 // custom_tree means set this.tree to `custom_tree` and restore old value on return
1345 Markdown.prototype.toTree = function toTree( source, custom_root ) {
1346   var blocks = source instanceof Array ? source : this.split_blocks( source );
1347
1348   // Make tree a member variable so its easier to mess with in extensions
1349   var old_tree = this.tree;
1350   try {
1351     this.tree = custom_root || this.tree || [ "markdown" ];
1352
1353     blocks:
1354     while ( blocks.length ) {
1355       var b = this.processBlock( blocks.shift(), blocks );
1356
1357       // Reference blocks and the like won't return any content
1358       if ( !b.length ) continue blocks;
1359
1360       this.tree.push.apply( this.tree, b );
1361     }
1362     return this.tree;
1363   }
1364   finally {
1365     if ( custom_root ) {
1366       this.tree = old_tree;
1367     }
1368   }
1369 };
1370
1371 // Noop by default
1372 Markdown.prototype.debug = function () {
1373   var args = Array.prototype.slice.call( arguments);
1374   args.unshift(this.debug_indent);
1375   if ( typeof print !== "undefined" )
1376       print.apply( print, args );
1377   if ( typeof console !== "undefined" && typeof console.log !== "undefined" )
1378       console.log.apply( null, args );
1379 }
1380
1381 Markdown.prototype.loop_re_over_block = function( re, block, cb ) {
1382   // Dont use /g regexps with this
1383   var m,
1384       b = block.valueOf();
1385
1386   while ( b.length && (m = re.exec(b) ) != null ) {
1387     b = b.substr( m[0].length );
1388     cb.call(this, m);
1389   }
1390   return b;
1391 };
1392
1393 /**
1394  * Markdown.dialects
1395  *
1396  * Namespace of built-in dialects.
1397  **/
1398 Markdown.dialects = {};
1399
1400 /**
1401  * Markdown.dialects.Gruber
1402  *
1403  * The default dialect that follows the rules set out by John Gruber's
1404  * markdown.pl as closely as possible. Well actually we follow the behaviour of
1405  * that script which in some places is not exactly what the syntax web page
1406  * says.
1407  **/
1408 Markdown.dialects.Gruber = {
1409   block: {
1410     atxHeader: function atxHeader( block, next ) {
1411       var m = block.match( /^(#{1,6})\s*(.*?)\s*#*\s*(?:\n|$)/ );
1412
1413       if ( !m ) return undefined;
1414
1415       var header = [ "header", { level: m[ 1 ].length } ];
1416       Array.prototype.push.apply(header, this.processInline(m[ 2 ]));
1417
1418       if ( m[0].length < block.length )
1419         next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) );
1420
1421       return [ header ];
1422     },
1423
1424     setextHeader: function setextHeader( block, next ) {
1425       var m = block.match( /^(.*)\n([-=])\2\2+(?:\n|$)/ );
1426
1427       if ( !m ) return undefined;
1428
1429       var level = ( m[ 2 ] === "=" ) ? 1 : 2;
1430       var header = [ "header", { level : level }, m[ 1 ] ];
1431
1432       if ( m[0].length < block.length )
1433         next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) );
1434
1435       return [ header ];
1436     },
1437
1438     code: function code( block, next ) {
1439       // |    Foo
1440       // |bar
1441       // should be a code block followed by a paragraph. Fun
1442       //
1443       // There might also be adjacent code block to merge.
1444
1445       var ret = [],
1446           re = /^(?: {0,3}\t| {4})(.*)\n?/,
1447           lines;
1448
1449       // 4 spaces + content
1450       if ( !block.match( re ) ) return undefined;
1451
1452       block_search:
1453       do {
1454         // Now pull out the rest of the lines
1455         var b = this.loop_re_over_block(
1456                   re, block.valueOf(), function( m ) { ret.push( m[1] ); } );
1457
1458         if ( b.length ) {
1459           // Case alluded to in first comment. push it back on as a new block
1460           next.unshift( mk_block(b, block.trailing) );
1461           break block_search;
1462         }
1463         else if ( next.length ) {
1464           // Check the next block - it might be code too
1465           if ( !next[0].match( re ) ) break block_search;
1466
1467           // Pull how how many blanks lines follow - minus two to account for .join
1468           ret.push ( block.trailing.replace(/[^\n]/g, "").substring(2) );
1469
1470           block = next.shift();
1471         }
1472         else {
1473           break block_search;
1474         }
1475       } while ( true );
1476
1477       return [ [ "code_block", ret.join("\n") ] ];
1478     },
1479
1480     horizRule: function horizRule( block, next ) {
1481       // this needs to find any hr in the block to handle abutting blocks
1482       var m = block.match( /^(?:([\s\S]*?)\n)?[ \t]*([-_*])(?:[ \t]*\2){2,}[ \t]*(?:\n([\s\S]*))?$/ );
1483
1484       if ( !m ) {
1485         return undefined;
1486       }
1487
1488       var jsonml = [ [ "hr" ] ];
1489
1490       // if there's a leading abutting block, process it
1491       if ( m[ 1 ] ) {
1492         jsonml.unshift.apply( jsonml, this.processBlock( m[ 1 ], [] ) );
1493       }
1494
1495       // if there's a trailing abutting block, stick it into next
1496       if ( m[ 3 ] ) {
1497         next.unshift( mk_block( m[ 3 ] ) );
1498       }
1499
1500       return jsonml;
1501     },
1502
1503     // There are two types of lists. Tight and loose. Tight lists have no whitespace
1504     // between the items (and result in text just in the <li>) and loose lists,
1505     // which have an empty line between list items, resulting in (one or more)
1506     // paragraphs inside the <li>.
1507     //
1508     // There are all sorts weird edge cases about the original markdown.pl's
1509     // handling of lists:
1510     //
1511     // * Nested lists are supposed to be indented by four chars per level. But
1512     //   if they aren't, you can get a nested list by indenting by less than
1513     //   four so long as the indent doesn't match an indent of an existing list
1514     //   item in the 'nest stack'.
1515     //
1516     // * The type of the list (bullet or number) is controlled just by the
1517     //    first item at the indent. Subsequent changes are ignored unless they
1518     //    are for nested lists
1519     //
1520     lists: (function( ) {
1521       // Use a closure to hide a few variables.
1522       var any_list = "[*+-]|\\d+\\.",
1523           bullet_list = /[*+-]/,
1524           number_list = /\d+\./,
1525           // Capture leading indent as it matters for determining nested lists.
1526           is_list_re = new RegExp( "^( {0,3})(" + any_list + ")[ \t]+" ),
1527           indent_re = "(?: {0,3}\\t| {4})";
1528
1529       // TODO: Cache this regexp for certain depths.
1530       // Create a regexp suitable for matching an li for a given stack depth
1531       function regex_for_depth( depth ) {
1532
1533         return new RegExp(
1534           // m[1] = indent, m[2] = list_type
1535           "(?:^(" + indent_re + "{0," + depth + "} {0,3})(" + any_list + ")\\s+)|" +
1536           // m[3] = cont
1537           "(^" + indent_re + "{0," + (depth-1) + "}[ ]{0,4})"
1538         );
1539       }
1540       function expand_tab( input ) {
1541         return input.replace( / {0,3}\t/g, "    " );
1542       }
1543
1544       // Add inline content `inline` to `li`. inline comes from processInline
1545       // so is an array of content
1546       function add(li, loose, inline, nl) {
1547         if ( loose ) {
1548           li.push( [ "para" ].concat(inline) );
1549           return;
1550         }
1551         // Hmmm, should this be any block level element or just paras?
1552         var add_to = li[li.length -1] instanceof Array && li[li.length - 1][0] == "para"
1553                    ? li[li.length -1]
1554                    : li;
1555
1556         // If there is already some content in this list, add the new line in
1557         if ( nl && li.length > 1 ) inline.unshift(nl);
1558
1559         for ( var i = 0; i < inline.length; i++ ) {
1560           var what = inline[i],
1561               is_str = typeof what == "string";
1562           if ( is_str && add_to.length > 1 && typeof add_to[add_to.length-1] == "string" ) {
1563             add_to[ add_to.length-1 ] += what;
1564           }
1565           else {
1566             add_to.push( what );
1567           }
1568         }
1569       }
1570
1571       // contained means have an indent greater than the current one. On
1572       // *every* line in the block
1573       function get_contained_blocks( depth, blocks ) {
1574
1575         var re = new RegExp( "^(" + indent_re + "{" + depth + "}.*?\\n?)*$" ),
1576             replace = new RegExp("^" + indent_re + "{" + depth + "}", "gm"),
1577             ret = [];
1578
1579         while ( blocks.length > 0 ) {
1580           if ( re.exec( blocks[0] ) ) {
1581             var b = blocks.shift(),
1582                 // Now remove that indent
1583                 x = b.replace( replace, "");
1584
1585             ret.push( mk_block( x, b.trailing, b.lineNumber ) );
1586           }
1587           else {
1588             break;
1589           }
1590         }
1591         return ret;
1592       }
1593
1594       // passed to stack.forEach to turn list items up the stack into paras
1595       function paragraphify(s, i, stack) {
1596         var list = s.list;
1597         var last_li = list[list.length-1];
1598
1599         if ( last_li[1] instanceof Array && last_li[1][0] == "para" ) {
1600           return;
1601         }
1602         if ( i + 1 == stack.length ) {
1603           // Last stack frame
1604           // Keep the same array, but replace the contents
1605           last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ) );
1606         }
1607         else {
1608           var sublist = last_li.pop();
1609           last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ), sublist );
1610         }
1611       }
1612
1613       // The matcher function
1614       return function( block, next ) {
1615         var m = block.match( is_list_re );
1616         if ( !m ) return undefined;
1617
1618         function make_list( m ) {
1619           var list = bullet_list.exec( m[2] )
1620                    ? ["bulletlist"]
1621                    : ["numberlist"];
1622
1623           stack.push( { list: list, indent: m[1] } );
1624           return list;
1625         }
1626
1627
1628         var stack = [], // Stack of lists for nesting.
1629             list = make_list( m ),
1630             last_li,
1631             loose = false,
1632             ret = [ stack[0].list ],
1633             i;
1634
1635         // Loop to search over block looking for inner block elements and loose lists
1636         loose_search:
1637         while ( true ) {
1638           // Split into lines preserving new lines at end of line
1639           var lines = block.split( /(?=\n)/ );
1640
1641           // We have to grab all lines for a li and call processInline on them
1642           // once as there are some inline things that can span lines.
1643           var li_accumulate = "";
1644
1645           // Loop over the lines in this block looking for tight lists.
1646           tight_search:
1647           for ( var line_no = 0; line_no < lines.length; line_no++ ) {
1648             var nl = "",
1649                 l = lines[line_no].replace(/^\n/, function(n) { nl = n; return ""; });
1650
1651             // TODO: really should cache this
1652             var line_re = regex_for_depth( stack.length );
1653
1654             m = l.match( line_re );
1655             //print( "line:", uneval(l), "\nline match:", uneval(m) );
1656
1657             // We have a list item
1658             if ( m[1] !== undefined ) {
1659               // Process the previous list item, if any
1660               if ( li_accumulate.length ) {
1661                 add( last_li, loose, this.processInline( li_accumulate ), nl );
1662                 // Loose mode will have been dealt with. Reset it
1663                 loose = false;
1664                 li_accumulate = "";
1665               }
1666
1667               m[1] = expand_tab( m[1] );
1668               var wanted_depth = Math.floor(m[1].length/4)+1;
1669               //print( "want:", wanted_depth, "stack:", stack.length);
1670               if ( wanted_depth > stack.length ) {
1671                 // Deep enough for a nested list outright
1672                 //print ( "new nested list" );
1673                 list = make_list( m );
1674                 last_li.push( list );
1675                 last_li = list[1] = [ "listitem" ];
1676               }
1677               else {
1678                 // We aren't deep enough to be strictly a new level. This is
1679                 // where Md.pl goes nuts. If the indent matches a level in the
1680                 // stack, put it there, else put it one deeper then the
1681                 // wanted_depth deserves.
1682                 var found = false;
1683                 for ( i = 0; i < stack.length; i++ ) {
1684                   if ( stack[ i ].indent != m[1] ) continue;
1685                   list = stack[ i ].list;
1686                   stack.splice( i+1, stack.length - (i+1) );
1687                   found = true;
1688                   break;
1689                 }
1690
1691                 if (!found) {
1692                   //print("not found. l:", uneval(l));
1693                   wanted_depth++;
1694                   if ( wanted_depth <= stack.length ) {
1695                     stack.splice(wanted_depth, stack.length - wanted_depth);
1696                     //print("Desired depth now", wanted_depth, "stack:", stack.length);
1697                     list = stack[wanted_depth-1].list;
1698                     //print("list:", uneval(list) );
1699                   }
1700                   else {
1701                     //print ("made new stack for messy indent");
1702                     list = make_list(m);
1703                     last_li.push(list);
1704                   }
1705                 }
1706
1707                 //print( uneval(list), "last", list === stack[stack.length-1].list );
1708                 last_li = [ "listitem" ];
1709                 list.push(last_li);
1710               } // end depth of shenegains
1711               nl = "";
1712             }
1713
1714             // Add content
1715             if ( l.length > m[0].length ) {
1716               li_accumulate += nl + l.substr( m[0].length );
1717             }
1718           } // tight_search
1719
1720           if ( li_accumulate.length ) {
1721             add( last_li, loose, this.processInline( li_accumulate ), nl );
1722             // Loose mode will have been dealt with. Reset it
1723             loose = false;
1724             li_accumulate = "";
1725           }
1726
1727           // Look at the next block - we might have a loose list. Or an extra
1728           // paragraph for the current li
1729           var contained = get_contained_blocks( stack.length, next );
1730
1731           // Deal with code blocks or properly nested lists
1732           if ( contained.length > 0 ) {
1733             // Make sure all listitems up the stack are paragraphs
1734             forEach( stack, paragraphify, this);
1735
1736             last_li.push.apply( last_li, this.toTree( contained, [] ) );
1737           }
1738
1739           var next_block = next[0] && next[0].valueOf() || "";
1740
1741           if ( next_block.match(is_list_re) || next_block.match( /^ / ) ) {
1742             block = next.shift();
1743
1744             // Check for an HR following a list: features/lists/hr_abutting
1745             var hr = this.dialect.block.horizRule( block, next );
1746
1747             if ( hr ) {
1748               ret.push.apply(ret, hr);
1749               break;
1750             }
1751
1752             // Make sure all listitems up the stack are paragraphs
1753             forEach( stack, paragraphify, this);
1754
1755             loose = true;
1756             continue loose_search;
1757           }
1758           break;
1759         } // loose_search
1760
1761         return ret;
1762       };
1763     })(),
1764
1765     blockquote: function blockquote( block, next ) {
1766       if ( !block.match( /^>/m ) )
1767         return undefined;
1768
1769       var jsonml = [];
1770
1771       // separate out the leading abutting block, if any. I.e. in this case:
1772       //
1773       //  a
1774       //  > b
1775       //
1776       if ( block[ 0 ] != ">" ) {
1777         var lines = block.split( /\n/ ),
1778             prev = [],
1779             line_no = block.lineNumber;
1780
1781         // keep shifting lines until you find a crotchet
1782         while ( lines.length && lines[ 0 ][ 0 ] != ">" ) {
1783             prev.push( lines.shift() );
1784             line_no++;
1785         }
1786
1787         var abutting = mk_block( prev.join( "\n" ), "\n", block.lineNumber );
1788         jsonml.push.apply( jsonml, this.processBlock( abutting, [] ) );
1789         // reassemble new block of just block quotes!
1790         block = mk_block( lines.join( "\n" ), block.trailing, line_no );
1791       }
1792
1793
1794       // if the next block is also a blockquote merge it in
1795       while ( next.length && next[ 0 ][ 0 ] == ">" ) {
1796         var b = next.shift();
1797         block = mk_block( block + block.trailing + b, b.trailing, block.lineNumber );
1798       }
1799
1800       // Strip off the leading "> " and re-process as a block.
1801       var input = block.replace( /^> ?/gm, "" ),
1802           old_tree = this.tree,
1803           processedBlock = this.toTree( input, [ "blockquote" ] ),
1804           attr = extract_attr( processedBlock );
1805
1806       // If any link references were found get rid of them
1807       if ( attr && attr.references ) {
1808         delete attr.references;
1809         // And then remove the attribute object if it's empty
1810         if ( isEmpty( attr ) ) {
1811           processedBlock.splice( 1, 1 );
1812         }
1813       }
1814
1815       jsonml.push( processedBlock );
1816       return jsonml;
1817     },
1818
1819     referenceDefn: function referenceDefn( block, next) {
1820       var re = /^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/;
1821       // interesting matches are [ , ref_id, url, , title, title ]
1822
1823       if ( !block.match(re) )
1824         return undefined;
1825
1826       // make an attribute node if it doesn't exist
1827       if ( !extract_attr( this.tree ) ) {
1828         this.tree.splice( 1, 0, {} );
1829       }
1830
1831       var attrs = extract_attr( this.tree );
1832
1833       // make a references hash if it doesn't exist
1834       if ( attrs.references === undefined ) {
1835         attrs.references = {};
1836       }
1837
1838       var b = this.loop_re_over_block(re, block, function( m ) {
1839
1840         if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" )
1841           m[2] = m[2].substring( 1, m[2].length - 1 );
1842
1843         var ref = attrs.references[ m[1].toLowerCase() ] = {
1844           href: m[2]
1845         };
1846
1847         if ( m[4] !== undefined )
1848           ref.title = m[4];
1849         else if ( m[5] !== undefined )
1850           ref.title = m[5];
1851
1852       } );
1853
1854       if ( b.length )
1855         next.unshift( mk_block( b, block.trailing ) );
1856
1857       return [];
1858     },
1859
1860     para: function para( block, next ) {
1861       // everything's a para!
1862       return [ ["para"].concat( this.processInline( block ) ) ];
1863     }
1864   }
1865 };
1866
1867 Markdown.dialects.Gruber.inline = {
1868
1869     __oneElement__: function oneElement( text, patterns_or_re, previous_nodes ) {
1870       var m,
1871           res,
1872           lastIndex = 0;
1873
1874       patterns_or_re = patterns_or_re || this.dialect.inline.__patterns__;
1875       var re = new RegExp( "([\\s\\S]*?)(" + (patterns_or_re.source || patterns_or_re) + ")" );
1876
1877       m = re.exec( text );
1878       if (!m) {
1879         // Just boring text
1880         return [ text.length, text ];
1881       }
1882       else if ( m[1] ) {
1883         // Some un-interesting text matched. Return that first
1884         return [ m[1].length, m[1] ];
1885       }
1886
1887       var res;
1888       if ( m[2] in this.dialect.inline ) {
1889         res = this.dialect.inline[ m[2] ].call(
1890                   this,
1891                   text.substr( m.index ), m, previous_nodes || [] );
1892       }
1893       // Default for now to make dev easier. just slurp special and output it.
1894       res = res || [ m[2].length, m[2] ];
1895       return res;
1896     },
1897
1898     __call__: function inline( text, patterns ) {
1899
1900       var out = [],
1901           res;
1902
1903       function add(x) {
1904         //D:self.debug("  adding output", uneval(x));
1905         if ( typeof x == "string" && typeof out[out.length-1] == "string" )
1906           out[ out.length-1 ] += x;
1907         else
1908           out.push(x);
1909       }
1910
1911       while ( text.length > 0 ) {
1912         res = this.dialect.inline.__oneElement__.call(this, text, patterns, out );
1913         text = text.substr( res.shift() );
1914         forEach(res, add )
1915       }
1916
1917       return out;
1918     },
1919
1920     // These characters are intersting elsewhere, so have rules for them so that
1921     // chunks of plain text blocks don't include them
1922     "]": function () {},
1923     "}": function () {},
1924
1925     __escape__ : /^\\[\\`\*_{}\[\]()#\+.!\-]/,
1926
1927     "\\": function escaped( text ) {
1928       // [ length of input processed, node/children to add... ]
1929       // Only esacape: \ ` * _ { } [ ] ( ) # * + - . !
1930       if ( this.dialect.inline.__escape__.exec( text ) )
1931         return [ 2, text.charAt( 1 ) ];
1932       else
1933         // Not an esacpe
1934         return [ 1, "\\" ];
1935     },
1936
1937     "![": function image( text ) {
1938
1939       // Unlike images, alt text is plain text only. no other elements are
1940       // allowed in there
1941
1942       // ![Alt text](/path/to/img.jpg "Optional title")
1943       //      1          2            3       4         <--- captures
1944       var m = text.match( /^!\[(.*?)\][ \t]*\([ \t]*([^")]*?)(?:[ \t]+(["'])(.*?)\3)?[ \t]*\)/ );
1945
1946       if ( m ) {
1947         if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" )
1948           m[2] = m[2].substring( 1, m[2].length - 1 );
1949
1950         m[2] = this.dialect.inline.__call__.call( this, m[2], /\\/ )[0];
1951
1952         var attrs = { alt: m[1], href: m[2] || "" };
1953         if ( m[4] !== undefined)
1954           attrs.title = m[4];
1955
1956         return [ m[0].length, [ "img", attrs ] ];
1957       }
1958
1959       // ![Alt text][id]
1960       m = text.match( /^!\[(.*?)\][ \t]*\[(.*?)\]/ );
1961
1962       if ( m ) {
1963         // We can't check if the reference is known here as it likely wont be
1964         // found till after. Check it in md tree->hmtl tree conversion
1965         return [ m[0].length, [ "img_ref", { alt: m[1], ref: m[2].toLowerCase(), original: m[0] } ] ];
1966       }
1967
1968       // Just consume the '!['
1969       return [ 2, "![" ];
1970     },
1971
1972     "[": function link( text ) {
1973
1974       var orig = String(text);
1975       // Inline content is possible inside `link text`
1976       var res = Markdown.DialectHelpers.inline_until_char.call( this, text.substr(1), "]" );
1977
1978       // No closing ']' found. Just consume the [
1979       if ( !res ) return [ 1, "[" ];
1980
1981       var consumed = 1 + res[ 0 ],
1982           children = res[ 1 ],
1983           link,
1984           attrs;
1985
1986       // At this point the first [...] has been parsed. See what follows to find
1987       // out which kind of link we are (reference or direct url)
1988       text = text.substr( consumed );
1989
1990       // [link text](/path/to/img.jpg "Optional title")
1991       //                 1            2       3         <--- captures
1992       // This will capture up to the last paren in the block. We then pull
1993       // back based on if there a matching ones in the url
1994       //    ([here](/url/(test))
1995       // The parens have to be balanced
1996       var m = text.match( /^\s*\([ \t]*([^"']*)(?:[ \t]+(["'])(.*?)\2)?[ \t]*\)/ );
1997       if ( m ) {
1998         var url = m[1];
1999         consumed += m[0].length;
2000
2001         if ( url && url[0] == "<" && url[url.length-1] == ">" )
2002           url = url.substring( 1, url.length - 1 );
2003
2004         // If there is a title we don't have to worry about parens in the url
2005         if ( !m[3] ) {
2006           var open_parens = 1; // One open that isn't in the capture
2007           for ( var len = 0; len < url.length; len++ ) {
2008             switch ( url[len] ) {
2009             case "(":
2010               open_parens++;
2011               break;
2012             case ")":
2013               if ( --open_parens == 0) {
2014                 consumed -= url.length - len;
2015                 url = url.substring(0, len);
2016               }
2017               break;
2018             }
2019           }
2020         }
2021
2022         // Process escapes only
2023         url = this.dialect.inline.__call__.call( this, url, /\\/ )[0];
2024
2025         attrs = { href: url || "" };
2026         if ( m[3] !== undefined)
2027           attrs.title = m[3];
2028
2029         link = [ "link", attrs ].concat( children );
2030         return [ consumed, link ];
2031       }
2032
2033       // [Alt text][id]
2034       // [Alt text] [id]
2035       m = text.match( /^\s*\[(.*?)\]/ );
2036
2037       if ( m ) {
2038
2039         consumed += m[ 0 ].length;
2040
2041         // [links][] uses links as its reference
2042         attrs = { ref: ( m[ 1 ] || String(children) ).toLowerCase(),  original: orig.substr( 0, consumed ) };
2043
2044         link = [ "link_ref", attrs ].concat( children );
2045
2046         // We can't check if the reference is known here as it likely wont be
2047         // found till after. Check it in md tree->hmtl tree conversion.
2048         // Store the original so that conversion can revert if the ref isn't found.
2049         return [ consumed, link ];
2050       }
2051
2052       // [id]
2053       // Only if id is plain (no formatting.)
2054       if ( children.length == 1 && typeof children[0] == "string" ) {
2055
2056         attrs = { ref: children[0].toLowerCase(),  original: orig.substr( 0, consumed ) };
2057         link = [ "link_ref", attrs, children[0] ];
2058         return [ consumed, link ];
2059       }
2060
2061       // Just consume the "["
2062       return [ 1, "[" ];
2063     },
2064
2065
2066     "<": function autoLink( text ) {
2067       var m;
2068
2069       if ( ( m = text.match( /^<(?:((https?|ftp|mailto):[^>]+)|(.*?@.*?\.[a-zA-Z]+))>/ ) ) != null ) {
2070         if ( m[3] ) {
2071           return [ m[0].length, [ "link", { href: "mailto:" + m[3] }, m[3] ] ];
2072
2073         }
2074         else if ( m[2] == "mailto" ) {
2075           return [ m[0].length, [ "link", { href: m[1] }, m[1].substr("mailto:".length ) ] ];
2076         }
2077         else
2078           return [ m[0].length, [ "link", { href: m[1] }, m[1] ] ];
2079       }
2080
2081       return [ 1, "<" ];
2082     },
2083
2084     "`": function inlineCode( text ) {
2085       // Inline code block. as many backticks as you like to start it
2086       // Always skip over the opening ticks.
2087       var m = text.match( /(`+)(([\s\S]*?)\1)/ );
2088
2089       if ( m && m[2] )
2090         return [ m[1].length + m[2].length, [ "inlinecode", m[3] ] ];
2091       else {
2092         // TODO: No matching end code found - warn!
2093         return [ 1, "`" ];
2094       }
2095     },
2096
2097     "  \n": function lineBreak( text ) {
2098       return [ 3, [ "linebreak" ] ];
2099     }
2100
2101 };
2102
2103 // Meta Helper/generator method for em and strong handling
2104 function strong_em( tag, md ) {
2105
2106   var state_slot = tag + "_state",
2107       other_slot = tag == "strong" ? "em_state" : "strong_state";
2108
2109   function CloseTag(len) {
2110     this.len_after = len;
2111     this.name = "close_" + md;
2112   }
2113
2114   return function ( text, orig_match ) {
2115
2116     if ( this[state_slot][0] == md ) {
2117       // Most recent em is of this type
2118       //D:this.debug("closing", md);
2119       this[state_slot].shift();
2120
2121       // "Consume" everything to go back to the recrusion in the else-block below
2122       return[ text.length, new CloseTag(text.length-md.length) ];
2123     }
2124     else {
2125       // Store a clone of the em/strong states
2126       var other = this[other_slot].slice(),
2127           state = this[state_slot].slice();
2128
2129       this[state_slot].unshift(md);
2130
2131       //D:this.debug_indent += "  ";
2132
2133       // Recurse
2134       var res = this.processInline( text.substr( md.length ) );
2135       //D:this.debug_indent = this.debug_indent.substr(2);
2136
2137       var last = res[res.length - 1];
2138
2139       //D:this.debug("processInline from", tag + ": ", uneval( res ) );
2140
2141       var check = this[state_slot].shift();
2142       if ( last instanceof CloseTag ) {
2143         res.pop();
2144         // We matched! Huzzah.
2145         var consumed = text.length - last.len_after;
2146         return [ consumed, [ tag ].concat(res) ];
2147       }
2148       else {
2149         // Restore the state of the other kind. We might have mistakenly closed it.
2150         this[other_slot] = other;
2151         this[state_slot] = state;
2152
2153         // We can't reuse the processed result as it could have wrong parsing contexts in it.
2154         return [ md.length, md ];
2155       }
2156     }
2157   }; // End returned function
2158 }
2159
2160 Markdown.dialects.Gruber.inline["**"] = strong_em("strong", "**");
2161 Markdown.dialects.Gruber.inline["__"] = strong_em("strong", "__");
2162 Markdown.dialects.Gruber.inline["*"]  = strong_em("em", "*");
2163 Markdown.dialects.Gruber.inline["_"]  = strong_em("em", "_");
2164
2165
2166 // Build default order from insertion order.
2167 Markdown.buildBlockOrder = function(d) {
2168   var ord = [];
2169   for ( var i in d ) {
2170     if ( i == "__order__" || i == "__call__" ) continue;
2171     ord.push( i );
2172   }
2173   d.__order__ = ord;
2174 };
2175
2176 // Build patterns for inline matcher
2177 Markdown.buildInlinePatterns = function(d) {
2178   var patterns = [];
2179
2180   for ( var i in d ) {
2181     // __foo__ is reserved and not a pattern
2182     if ( i.match( /^__.*__$/) ) continue;
2183     var l = i.replace( /([\\.*+?|()\[\]{}])/g, "\\$1" )
2184              .replace( /\n/, "\\n" );
2185     patterns.push( i.length == 1 ? l : "(?:" + l + ")" );
2186   }
2187
2188   patterns = patterns.join("|");
2189   d.__patterns__ = patterns;
2190   //print("patterns:", uneval( patterns ) );
2191
2192   var fn = d.__call__;
2193   d.__call__ = function(text, pattern) {
2194     if ( pattern != undefined ) {
2195       return fn.call(this, text, pattern);
2196     }
2197     else
2198     {
2199       return fn.call(this, text, patterns);
2200     }
2201   };
2202 };
2203
2204 Markdown.DialectHelpers = {};
2205 Markdown.DialectHelpers.inline_until_char = function( text, want ) {
2206   var consumed = 0,
2207       nodes = [];
2208
2209   while ( true ) {
2210     if ( text.charAt( consumed ) == want ) {
2211       // Found the character we were looking for
2212       consumed++;
2213       return [ consumed, nodes ];
2214     }
2215
2216     if ( consumed >= text.length ) {
2217       // No closing char found. Abort.
2218       return null;
2219     }
2220
2221     var res = this.dialect.inline.__oneElement__.call(this, text.substr( consumed ) );
2222     consumed += res[ 0 ];
2223     // Add any returned nodes.
2224     nodes.push.apply( nodes, res.slice( 1 ) );
2225   }
2226 }
2227
2228 // Helper function to make sub-classing a dialect easier
2229 Markdown.subclassDialect = function( d ) {
2230   function Block() {}
2231   Block.prototype = d.block;
2232   function Inline() {}
2233   Inline.prototype = d.inline;
2234
2235   return { block: new Block(), inline: new Inline() };
2236 };
2237
2238 Markdown.buildBlockOrder ( Markdown.dialects.Gruber.block );
2239 Markdown.buildInlinePatterns( Markdown.dialects.Gruber.inline );
2240
2241 Markdown.dialects.Maruku = Markdown.subclassDialect( Markdown.dialects.Gruber );
2242
2243 Markdown.dialects.Maruku.processMetaHash = function processMetaHash( meta_string ) {
2244   var meta = split_meta_hash( meta_string ),
2245       attr = {};
2246
2247   for ( var i = 0; i < meta.length; ++i ) {
2248     // id: #foo
2249     if ( /^#/.test( meta[ i ] ) ) {
2250       attr.id = meta[ i ].substring( 1 );
2251     }
2252     // class: .foo
2253     else if ( /^\./.test( meta[ i ] ) ) {
2254       // if class already exists, append the new one
2255       if ( attr["class"] ) {
2256         attr["class"] = attr["class"] + meta[ i ].replace( /./, " " );
2257       }
2258       else {
2259         attr["class"] = meta[ i ].substring( 1 );
2260       }
2261     }
2262     // attribute: foo=bar
2263     else if ( /\=/.test( meta[ i ] ) ) {
2264       var s = meta[ i ].split( /\=/ );
2265       attr[ s[ 0 ] ] = s[ 1 ];
2266     }
2267   }
2268
2269   return attr;
2270 }
2271
2272 function split_meta_hash( meta_string ) {
2273   var meta = meta_string.split( "" ),
2274       parts = [ "" ],
2275       in_quotes = false;
2276
2277   while ( meta.length ) {
2278     var letter = meta.shift();
2279     switch ( letter ) {
2280       case " " :
2281         // if we're in a quoted section, keep it
2282         if ( in_quotes ) {
2283           parts[ parts.length - 1 ] += letter;
2284         }
2285         // otherwise make a new part
2286         else {
2287           parts.push( "" );
2288         }
2289         break;
2290       case "'" :
2291       case '"' :
2292         // reverse the quotes and move straight on
2293         in_quotes = !in_quotes;
2294         break;
2295       case "\\" :
2296         // shift off the next letter to be used straight away.
2297         // it was escaped so we'll keep it whatever it is
2298         letter = meta.shift();
2299       default :
2300         parts[ parts.length - 1 ] += letter;
2301         break;
2302     }
2303   }
2304
2305   return parts;
2306 }
2307
2308 Markdown.dialects.Maruku.block.document_meta = function document_meta( block, next ) {
2309   // we're only interested in the first block
2310   if ( block.lineNumber > 1 ) return undefined;
2311
2312   // document_meta blocks consist of one or more lines of `Key: Value\n`
2313   if ( ! block.match( /^(?:\w+:.*\n)*\w+:.*$/ ) ) return undefined;
2314
2315   // make an attribute node if it doesn't exist
2316   if ( !extract_attr( this.tree ) ) {
2317     this.tree.splice( 1, 0, {} );
2318   }
2319
2320   var pairs = block.split( /\n/ );
2321   for ( p in pairs ) {
2322     var m = pairs[ p ].match( /(\w+):\s*(.*)$/ ),
2323         key = m[ 1 ].toLowerCase(),
2324         value = m[ 2 ];
2325
2326     this.tree[ 1 ][ key ] = value;
2327   }
2328
2329   // document_meta produces no content!
2330   return [];
2331 };
2332
2333 Markdown.dialects.Maruku.block.block_meta = function block_meta( block, next ) {
2334   // check if the last line of the block is an meta hash
2335   var m = block.match( /(^|\n) {0,3}\{:\s*((?:\\\}|[^\}])*)\s*\}$/ );
2336   if ( !m ) return undefined;
2337
2338   // process the meta hash
2339   var attr = this.dialect.processMetaHash( m[ 2 ] );
2340
2341   var hash;
2342
2343   // if we matched ^ then we need to apply meta to the previous block
2344   if ( m[ 1 ] === "" ) {
2345     var node = this.tree[ this.tree.length - 1 ];
2346     hash = extract_attr( node );
2347
2348     // if the node is a string (rather than JsonML), bail
2349     if ( typeof node === "string" ) return undefined;
2350
2351     // create the attribute hash if it doesn't exist
2352     if ( !hash ) {
2353       hash = {};
2354       node.splice( 1, 0, hash );
2355     }
2356
2357     // add the attributes in
2358     for ( a in attr ) {
2359       hash[ a ] = attr[ a ];
2360     }
2361
2362     // return nothing so the meta hash is removed
2363     return [];
2364   }
2365
2366   // pull the meta hash off the block and process what's left
2367   var b = block.replace( /\n.*$/, "" ),
2368       result = this.processBlock( b, [] );
2369
2370   // get or make the attributes hash
2371   hash = extract_attr( result[ 0 ] );
2372   if ( !hash ) {
2373     hash = {};
2374     result[ 0 ].splice( 1, 0, hash );
2375   }
2376
2377   // attach the attributes to the block
2378   for ( a in attr ) {
2379     hash[ a ] = attr[ a ];
2380   }
2381
2382   return result;
2383 };
2384
2385 Markdown.dialects.Maruku.block.definition_list = function definition_list( block, next ) {
2386   // one or more terms followed by one or more definitions, in a single block
2387   var tight = /^((?:[^\s:].*\n)+):\s+([\s\S]+)$/,
2388       list = [ "dl" ],
2389       i, m;
2390
2391   // see if we're dealing with a tight or loose block
2392   if ( ( m = block.match( tight ) ) ) {
2393     // pull subsequent tight DL blocks out of `next`
2394     var blocks = [ block ];
2395     while ( next.length && tight.exec( next[ 0 ] ) ) {
2396       blocks.push( next.shift() );
2397     }
2398
2399     for ( var b = 0; b < blocks.length; ++b ) {
2400       var m = blocks[ b ].match( tight ),
2401           terms = m[ 1 ].replace( /\n$/, "" ).split( /\n/ ),
2402           defns = m[ 2 ].split( /\n:\s+/ );
2403
2404       // print( uneval( m ) );
2405
2406       for ( i = 0; i < terms.length; ++i ) {
2407         list.push( [ "dt", terms[ i ] ] );
2408       }
2409
2410       for ( i = 0; i < defns.length; ++i ) {
2411         // run inline processing over the definition
2412         list.push( [ "dd" ].concat( this.processInline( defns[ i ].replace( /(\n)\s+/, "$1" ) ) ) );
2413       }
2414     }
2415   }
2416   else {
2417     return undefined;
2418   }
2419
2420   return [ list ];
2421 };
2422
2423 // splits on unescaped instances of @ch. If @ch is not a character the result
2424 // can be unpredictable
2425
2426 Markdown.dialects.Maruku.block.table = function table (block, next) {
2427
2428     var _split_on_unescaped = function(s, ch) {
2429         ch = ch || '\\s';
2430         if (ch.match(/^[\\|\[\]{}?*.+^$]$/)) { ch = '\\' + ch; }
2431         var res = [ ],
2432             r = new RegExp('^((?:\\\\.|[^\\\\' + ch + '])*)' + ch + '(.*)'),
2433             m;
2434         while(m = s.match(r)) {
2435             res.push(m[1]);
2436             s = m[2];
2437         }
2438         res.push(s);
2439         return res;
2440     }
2441
2442     var leading_pipe = /^ {0,3}\|(.+)\n {0,3}\|\s*([\-:]+[\-| :]*)\n((?:\s*\|.*(?:\n|$))*)(?=\n|$)/,
2443         // find at least an unescaped pipe in each line
2444         no_leading_pipe = /^ {0,3}(\S(?:\\.|[^\\|])*\|.*)\n {0,3}([\-:]+\s*\|[\-| :]*)\n((?:(?:\\.|[^\\|])*\|.*(?:\n|$))*)(?=\n|$)/,
2445         i, m;
2446     if (m = block.match(leading_pipe)) {
2447         // remove leading pipes in contents
2448         // (header and horizontal rule already have the leading pipe left out)
2449         m[3] = m[3].replace(/^\s*\|/gm, '');
2450     } else if (! ( m = block.match(no_leading_pipe))) {
2451         return undefined;
2452     }
2453
2454     var table = [ "table", [ "thead", [ "tr" ] ], [ "tbody" ] ];
2455
2456     // remove trailing pipes, then split on pipes
2457     // (no escaped pipes are allowed in horizontal rule)
2458     m[2] = m[2].replace(/\|\s*$/, '').split('|');
2459
2460     // process alignment
2461     var html_attrs = [ ];
2462     forEach (m[2], function (s) {
2463         if (s.match(/^\s*-+:\s*$/))       html_attrs.push({align: "right"});
2464         else if (s.match(/^\s*:-+\s*$/))  html_attrs.push({align: "left"});
2465         else if (s.match(/^\s*:-+:\s*$/)) html_attrs.push({align: "center"});
2466         else                              html_attrs.push({});
2467     });
2468
2469     // now for the header, avoid escaped pipes
2470     m[1] = _split_on_unescaped(m[1].replace(/\|\s*$/, ''), '|');
2471     for (i = 0; i < m[1].length; i++) {
2472         table[1][1].push(['th', html_attrs[i] || {}].concat(
2473             this.processInline(m[1][i].trim())));
2474     }
2475
2476     // now for body contents
2477     forEach (m[3].replace(/\|\s*$/mg, '').split('\n'), function (row) {
2478         var html_row = ['tr'];
2479         row = _split_on_unescaped(row, '|');
2480         for (i = 0; i < row.length; i++) {
2481             html_row.push(['td', html_attrs[i] || {}].concat(this.processInline(row[i].trim())));
2482         }
2483         table[2].push(html_row);
2484     }, this);
2485
2486     return [table];
2487 }
2488
2489 Markdown.dialects.Maruku.inline[ "{:" ] = function inline_meta( text, matches, out ) {
2490   if ( !out.length ) {
2491     return [ 2, "{:" ];
2492   }
2493
2494   // get the preceeding element
2495   var before = out[ out.length - 1 ];
2496
2497   if ( typeof before === "string" ) {
2498     return [ 2, "{:" ];
2499   }
2500
2501   // match a meta hash
2502   var m = text.match( /^\{:\s*((?:\\\}|[^\}])*)\s*\}/ );
2503
2504   // no match, false alarm
2505   if ( !m ) {
2506     return [ 2, "{:" ];
2507   }
2508
2509   // attach the attributes to the preceeding element
2510   var meta = this.dialect.processMetaHash( m[ 1 ] ),
2511       attr = extract_attr( before );
2512
2513   if ( !attr ) {
2514     attr = {};
2515     before.splice( 1, 0, attr );
2516   }
2517
2518   for ( var k in meta ) {
2519     attr[ k ] = meta[ k ];
2520   }
2521
2522   // cut out the string and replace it with nothing
2523   return [ m[ 0 ].length, "" ];
2524 };
2525
2526 Markdown.dialects.Maruku.inline.__escape__ = /^\\[\\`\*_{}\[\]()#\+.!\-|:]/;
2527
2528 Markdown.buildBlockOrder ( Markdown.dialects.Maruku.block );
2529 Markdown.buildInlinePatterns( Markdown.dialects.Maruku.inline );
2530
2531 var isArray = Array.isArray || function(obj) {
2532   return Object.prototype.toString.call(obj) == "[object Array]";
2533 };
2534
2535 var forEach;
2536 // Don't mess with Array.prototype. Its not friendly
2537 if ( Array.prototype.forEach ) {
2538   forEach = function( arr, cb, thisp ) {
2539     return arr.forEach( cb, thisp );
2540   };
2541 }
2542 else {
2543   forEach = function(arr, cb, thisp) {
2544     for (var i = 0; i < arr.length; i++) {
2545       cb.call(thisp || arr, arr[i], i, arr);
2546     }
2547   }
2548 }
2549
2550 var isEmpty = function( obj ) {
2551   for ( var key in obj ) {
2552     if ( hasOwnProperty.call( obj, key ) ) {
2553       return false;
2554     }
2555   }
2556
2557   return true;
2558 }
2559
2560 function extract_attr( jsonml ) {
2561   return isArray(jsonml)
2562       && jsonml.length > 1
2563       && typeof jsonml[ 1 ] === "object"
2564       && !( isArray(jsonml[ 1 ]) )
2565       ? jsonml[ 1 ]
2566       : undefined;
2567 }
2568
2569
2570
2571 /**
2572  *  renderJsonML( jsonml[, options] ) -> String
2573  *  - jsonml (Array): JsonML array to render to XML
2574  *  - options (Object): options
2575  *
2576  *  Converts the given JsonML into well-formed XML.
2577  *
2578  *  The options currently understood are:
2579  *
2580  *  - root (Boolean): wether or not the root node should be included in the
2581  *    output, or just its children. The default `false` is to not include the
2582  *    root itself.
2583  */
2584 expose.renderJsonML = function( jsonml, options ) {
2585   options = options || {};
2586   // include the root element in the rendered output?
2587   options.root = options.root || false;
2588
2589   var content = [];
2590
2591   if ( options.root ) {
2592     content.push( render_tree( jsonml ) );
2593   }
2594   else {
2595     jsonml.shift(); // get rid of the tag
2596     if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) {
2597       jsonml.shift(); // get rid of the attributes
2598     }
2599
2600     while ( jsonml.length ) {
2601       content.push( render_tree( jsonml.shift() ) );
2602     }
2603   }
2604
2605   return content.join( "\n\n" );
2606 };
2607
2608 function escapeHTML( text ) {
2609   return text.replace( /&/g, "&amp;" )
2610              .replace( /</g, "&lt;" )
2611              .replace( />/g, "&gt;" )
2612              .replace( /"/g, "&quot;" )
2613              .replace( /'/g, "&#39;" );
2614 }
2615
2616 function render_tree( jsonml ) {
2617   // basic case
2618   if ( typeof jsonml === "string" ) {
2619     return jsonml; // modified for deck.smarkdown.js
2620   }
2621
2622   var tag = jsonml.shift(),
2623       attributes = {},
2624       content = [];
2625
2626   if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) {
2627     attributes = jsonml.shift();
2628   }
2629
2630   while ( jsonml.length ) {
2631     content.push( render_tree( jsonml.shift() ) );
2632   }
2633
2634   var tag_attrs = "";
2635   for ( var a in attributes ) {
2636     tag_attrs += " " + a + '="' + escapeHTML( attributes[ a ] ) + '"';
2637   }
2638
2639   // be careful about adding whitespace here for inline elements
2640   if ( tag == "img" || tag == "br" || tag == "hr" ) {
2641     return "<"+ tag + tag_attrs + "/>";
2642   }
2643   else {
2644     return "<"+ tag + tag_attrs + ">" + content.join( "" ) + "</" + tag + ">";
2645   }
2646 }
2647
2648 function convert_tree_to_html( tree, references, options ) {
2649   var i;
2650   options = options || {};
2651
2652   // shallow clone
2653   var jsonml = tree.slice( 0 );
2654
2655   if ( typeof options.preprocessTreeNode === "function" ) {
2656       jsonml = options.preprocessTreeNode(jsonml, references);
2657   }
2658
2659   // Clone attributes if they exist
2660   var attrs = extract_attr( jsonml );
2661   if ( attrs ) {
2662     jsonml[ 1 ] = {};
2663     for ( i in attrs ) {
2664       jsonml[ 1 ][ i ] = attrs[ i ];
2665     }
2666     attrs = jsonml[ 1 ];
2667   }
2668
2669   // basic case
2670   if ( typeof jsonml === "string" ) {
2671     return jsonml;
2672   }
2673
2674   // convert this node
2675   switch ( jsonml[ 0 ] ) {
2676     case "header":
2677       jsonml[ 0 ] = "h" + jsonml[ 1 ].level;
2678       delete jsonml[ 1 ].level;
2679       break;
2680     case "bulletlist":
2681       jsonml[ 0 ] = "ul";
2682       break;
2683     case "numberlist":
2684       jsonml[ 0 ] = "ol";
2685       break;
2686     case "listitem":
2687       jsonml[ 0 ] = "li";
2688       break;
2689     case "para":
2690       jsonml[ 0 ] = "p";
2691       break;
2692     case "markdown":
2693       jsonml[ 0 ] = "html";
2694       if ( attrs ) delete attrs.references;
2695       break;
2696     case "code_block":
2697       jsonml[ 0 ] = "pre";
2698       i = attrs ? 2 : 1;
2699       var code = [ "code" ];
2700       code.push.apply( code, jsonml.splice( i, jsonml.length - i ) );
2701       jsonml[ i ] = code;
2702       break;
2703     case "inlinecode":
2704       jsonml[ 0 ] = "code";
2705       break;
2706     case "img":
2707       jsonml[ 1 ].src = jsonml[ 1 ].href;
2708       delete jsonml[ 1 ].href;
2709       break;
2710     case "linebreak":
2711       jsonml[ 0 ] = "br";
2712     break;
2713     case "link":
2714       jsonml[ 0 ] = "a";
2715       break;
2716     case "link_ref":
2717       jsonml[ 0 ] = "a";
2718
2719       // grab this ref and clean up the attribute node
2720       var ref = references[ attrs.ref ];
2721
2722       // if the reference exists, make the link
2723       if ( ref ) {
2724         delete attrs.ref;
2725
2726         // add in the href and title, if present
2727         attrs.href = ref.href;
2728         if ( ref.title ) {
2729           attrs.title = ref.title;
2730         }
2731
2732         // get rid of the unneeded original text
2733         delete attrs.original;
2734       }
2735       // the reference doesn't exist, so revert to plain text
2736       else {
2737         return attrs.original;
2738       }
2739       break;
2740     case "img_ref":
2741       jsonml[ 0 ] = "img";
2742
2743       // grab this ref and clean up the attribute node
2744       var ref = references[ attrs.ref ];
2745
2746       // if the reference exists, make the link
2747       if ( ref ) {
2748         delete attrs.ref;
2749
2750         // add in the href and title, if present
2751         attrs.src = ref.href;
2752         if ( ref.title ) {
2753           attrs.title = ref.title;
2754         }
2755
2756         // get rid of the unneeded original text
2757         delete attrs.original;
2758       }
2759       // the reference doesn't exist, so revert to plain text
2760       else {
2761         return attrs.original;
2762       }
2763       break;
2764   }
2765
2766   // convert all the children
2767   i = 1;
2768
2769   // deal with the attribute node, if it exists
2770   if ( attrs ) {
2771     // if there are keys, skip over it
2772     for ( var key in jsonml[ 1 ] ) {
2773         i = 2;
2774         break;
2775     }
2776     // if there aren't, remove it
2777     if ( i === 1 ) {
2778       jsonml.splice( i, 1 );
2779     }
2780   }
2781
2782   for ( ; i < jsonml.length; ++i ) {
2783     jsonml[ i ] = convert_tree_to_html( jsonml[ i ], references, options );
2784   }
2785
2786   return jsonml;
2787 }
2788
2789
2790 // merges adjacent text nodes into a single node
2791 function merge_text_nodes( jsonml ) {
2792   // skip the tag name and attribute hash
2793   var i = extract_attr( jsonml ) ? 2 : 1;
2794
2795   while ( i < jsonml.length ) {
2796     // if it's a string check the next item too
2797     if ( typeof jsonml[ i ] === "string" ) {
2798       if ( i + 1 < jsonml.length && typeof jsonml[ i + 1 ] === "string" ) {
2799         // merge the second string into the first and remove it
2800         jsonml[ i ] += jsonml.splice( i + 1, 1 )[ 0 ];
2801       }
2802       else {
2803         ++i;
2804       }
2805     }
2806     // if it's not a string recurse
2807     else {
2808       merge_text_nodes( jsonml[ i ] );
2809       ++i;
2810     }
2811   }
2812 }
2813
2814 } )( (function() {
2815   if ( typeof exports === "undefined" ) {
2816     window.markdown = {};
2817     return window.markdown;
2818   }
2819   else {
2820     return exports;
2821   }
2822 } )() );
2823
2824 /*!
2825 Deck JS - deck.smarkdown
2826 Copyright (c) 2014-2014 RĂ©mi Emonet
2827 Licensed under the MIT license.
2828 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
2829 */
2830
2831 /*
2832 This module provides a support for a shorter syntax for slides, with a syntax that is closer to plain markdown.
2833 TODO:
2834 - configurize the .smark and the default duration also
2835 - have a shortcut for {slide}?
2836
2837 */
2838
2839 (function($, deck, undefined) {
2840     var $d = $(document);
2841     var may = function(f) {return f ? f : function() {}};
2842     var endsWith = function(longStr, part) {return longStr.indexOf(part, longStr.length - part.length) !== -1;}
2843     var REST = null;
2844     var startsWith = function(longStr, part) {
2845         if (part == "%+class:") alert(":::"+longStr+":::");
2846         var res = longStr.substr(0, part.length) == part;
2847         REST = res ? longStr.slice(part.length) : null;
2848         RESTRIM = res ? REST.replace(/^ */, "") : null;
2849         return res;
2850     }
2851     var startsWithIgnoreCase = function(longStr, part) {
2852         var res = longStr.substr(0, part.length).toUpperCase() == part.toUpperCase();
2853         REST = res ? longStr.slice(part.length) : null;
2854         RESTRIM = res ? REST.replace(/^ */, "") : null;
2855         return res;
2856     }
2857     var isArray = Array.isArray || $.isArray; // there is also an alternative in markdownjs
2858
2859     // the animation duration is stateful across the smarkdown sections
2860     var animationDurationDefault = 400;
2861     var animationDuration = animationDurationDefault;
2862
2863     function clone(a) { return JSON.parse(JSON.stringify(a)) }
2864     function findTag(tree, regexp, startAt) {
2865         var i = startAt || 0;
2866         while (i < tree.length) {
2867             if (isArray(tree[i]) && tree[i][0].match(regexp)) {
2868                 return i;
2869             }
2870             i++;
2871         }
2872         return -1;
2873     }
2874     function addSpaceSeparatedAttr(o, a, c) {
2875         ensureHasAttributes(o);
2876         if (o[1][a])
2877             o[1][a] += " " + c;
2878         else
2879             o[1][a] = c;
2880     }
2881     function addClass(o, c) {
2882         addSpaceSeparatedAttr(o, 'class', c);
2883     }
2884     function hasClass(o, c) {
2885         if (!isObject(o[1]) || !o[1]['class']) {
2886             return false;
2887         } else {
2888             return o[1]['class'].match(new RegExp("\\b"+c+"\\b"));
2889         }
2890     }
2891     function isObject(o) {
2892         return !isArray(o) && typeof(o) === 'object';
2893     }
2894     function ensureHasAttributes(tree) {
2895         if (!isObject(tree[1])) {
2896             tree.splice(1, 0, {});
2897             return true;
2898         }
2899         return false;
2900     }
2901     function lazyGetAttributes(tree) {
2902         if (isObject(tree[1])) {
2903             return tree[1];
2904         } else {
2905             return {};
2906         }
2907     }
2908     function lazyUnsetAttributes(tree) {
2909         if (isObject(tree[1])) {
2910             tree.splice(1, 1);
2911         }
2912     }
2913     function hasIDOrClassDecoration(s) {
2914         return s.match(/^(.*)\{([^{}<>]*)\}$/);
2915     }
2916     function maybeProcessCopySlide(tree, index) {
2917         var slide = tree[index];
2918         ensureHasAttributes(slide);
2919         if (slide.length != 3) return false;
2920         if (slide[2][0] != "h1") return false;
2921         ensureHasAttributes(slide[2]);
2922         if (startsWithIgnoreCase(slide[2][2], "@COPY:#")) {
2923             var main = RESTRIM.split(/:/);
2924             var idOfBase = main[0];
2925             var animPart = main.slice(1).join(":");
2926             var hasAnim = ! animPart.match(/^\s*$/);
2927             var base = null;
2928             for (i in tree) {
2929                 if (i == 0 || (i==1 && isObject(tree[1]))) continue;
2930                 ensureHasAttributes(tree[i]);
2931                 if (tree[i][1].id == idOfBase) {
2932                     base = tree[i];
2933                     break;
2934                 }
2935             }
2936             if (base == null) { alert("pb"); return false; } // TODO should alert based on options
2937             var content = [["div", {}, "@anim:" + animPart]];
2938             content = content.concat(clone(base.slice(2)));
2939             slide[1] = clone(base[1]);
2940             delete slide[1].id;
2941             if (hasAnim) addClass(slide, "anim-continue");
2942             slide.splice.apply(slide, [2, 1].concat(content)); // replace the h1 with content
2943             return true;
2944         }
2945         return false;
2946     }
2947     function processIDOrClassDecoration(tree, index) {
2948         var matched = hasIDOrClassDecoration(tree[index]); // make sure the group is set
2949         if (!matched) { alert("should call processIDOrClassDecoration() only if hasIDOrClassDecoration is true"); return; }
2950         var returnValue = false; // whether we added the attributes
2951         var base = RegExp.$1;
2952         var decorations = RegExp.$2.split(/ +/);
2953         if (ensureHasAttributes(tree)) {
2954             if (index>0) index++;
2955             returnValue = true;
2956         }
2957         tree[index] = base;
2958         for (d in decorations) {
2959             // allow .class and class notations
2960             if (startsWith(decorations[d], ".")) decorations[d] = decorations[d].slice(1);
2961
2962             if (startsWith(decorations[d], "#")) {
2963                 tree[1].id = decorations[d].slice(1);
2964             } else {
2965                 if (startsWith(decorations[d], "*") | startsWith(decorations[d], "/")) {
2966                     addSpaceSeparatedAttr(tree, "data-container-class", decorations[d].slice(1));
2967                 } else {
2968                     addClass(tree, decorations[d]);
2969                 }
2970             }                
2971         }
2972         return returnValue;
2973     }
2974     function possiblyHideIfEmpty(tree) { // if it contains only anim stuf etc
2975         var hide = false;
2976         var i = isObject(tree[1]) ? 2 : 1;
2977         function onlyDivAnims(tt) {
2978             var only = true;
2979             var start = isObject(tt[1]) ? 2 : 1;
2980             tt.slice(start).forEach(function(e) {
2981                 if (!isArray(e) || !isObject(e[1]) || (" "+e[1]["class"]).indexOf(" anim-") == -1) {
2982                     only = false;
2983                 }
2984             });
2985             return only;
2986         }
2987
2988         if (onlyDivAnims(tree)) hide = true;
2989         else if (tree.length == i+1 && isArray(tree[i]) && tree[i][0] == "p"
2990                  && onlyDivAnims(tree[i])) hide = true;
2991         if (hide) {
2992             ensureHasAttributes(tree);
2993             tree[1].style = "display: none";
2994         }
2995     }
2996     function maybeProcessComment(tree, index) {
2997         var line = tree[index];
2998         var clean = function(s) { return s;}; //return s.replace(/\/\\\//g, '//'); };
2999         if (line.match(/^(.*?)[\n\s]*\/\/ +(.*)/)) {
3000             var obj = ["div", {
3001                 'class': "comment"
3002             }, clean(RegExp.$2)];
3003             tree.splice(index, 1, RegExp.$1, obj);
3004             return true;
3005         }
3006         tree[index] = clean(tree[index]);
3007         return false;
3008     }
3009     function maybeProcessAtSomething(tree, index) {
3010         var line = tree[index];
3011         if (startsWithIgnoreCase(line, "@SVG:")) {
3012             var content = RESTRIM
3013             var parts = content.split(/ +/);
3014             if (hasIDOrClassDecoration(content) || parts.length == 3) {
3015                 // new version
3016                 var obj = ["div", {
3017                     'data-src': parts[0],
3018                     'data-width': parts[1],
3019                     'data-height': parts[2],
3020                     'class': "svg-object"
3021                 }, parts.slice(3).join(" ")];
3022                 // TODO: alert when wrong number of args
3023                 if (hasIDOrClassDecoration(content)) processIDOrClassDecoration(obj, 2);
3024                 tree[index] = obj;
3025             } else {
3026                 // TODO allow this only when an option is set option
3027                 // old, smartsyntax version
3028                 var obj = ["div", {
3029                     'data-src': parts[1],
3030                     'data-width': parts[2],
3031                     'data-height': parts[3],
3032                     'class': "svg-object"
3033                 }, ""];
3034                 parts[0].split(/,/).forEach(function (p) { addClass(obj, p); });
3035                 tree[index] = obj;
3036             }
3037         } else if (startsWithIgnoreCase(line, "@ANIM:")) {
3038             line = RESTRIM.replace(/%[+]/i, "%%"); // protect the "%+class" from being split
3039             var allToAdd = [];
3040             var parts = line.split(/ *\| */); // TODO: configurize + reconsider all separators?
3041             for (i in parts) {
3042                 // process each group of simultaneous animations
3043                 var subparts = parts[i].split(/ *\+ */);
3044                 for (ii in subparts) {
3045                     var what = subparts[ii];
3046                     if (what == "") continue; // as a good side effect, this allows to set a "anim-continue" on all elements (e.g., put a + at the end of the line) 
3047                     var continuating  = ii != subparts.length-1;
3048                     var toAdd = ["div", {}, ""];
3049                     addClass(toAdd, "slide");
3050                     // process the individual element (reminder: animationDuration is global)
3051                     function dw() { addSpaceSeparatedAttr(toAdd, "data-what", REST); }
3052                     function dd() { addSpaceSeparatedAttr(toAdd, "data-dur", ""+animationDuration); }
3053                     if (startsWithIgnoreCase(what, "%duration:")) {
3054                         animationDuration = RESTRIM == "" ? animationDurationDefault : RESTRIM;
3055                         continue;
3056                     } else if (startsWithIgnoreCase(what, "%dur:")) {
3057                         animationDuration = RESTRIM == "" ? animationDurationDefault : RESTRIM;
3058                         continue;
3059                     } else if (startsWithIgnoreCase(what, "%play:")) {
3060                         addClass(toAdd, "anim-play");
3061                         dw();
3062                     } else if (startsWithIgnoreCase(what, "%pause:")) {
3063                         addClass(toAdd, "anim-pause");
3064                         dw();
3065                     } else if (startsWith(what, "%viewbox:")) {
3066                         addClass(toAdd, "anim-viewboxas");
3067                         // TODO: if REST contains ':', two params (then the target is specified, else it is just all SVGs root elements)
3068                         addSpaceSeparatedAttr(toAdd, "data-as", REST);
3069                         addSpaceSeparatedAttr(toAdd, "data-what", "svg");
3070                         dd();
3071                     } else if (startsWith(what, "%attr:")) {
3072                         var main = RESTRIM.split(/ *: */);
3073                         addClass(toAdd, "anim-attribute");
3074                         addSpaceSeparatedAttr(toAdd, "data-what", main[0]);
3075                         addSpaceSeparatedAttr(toAdd, "data-attr", main.slice(1).join(":"));
3076                         dd();
3077                     } else if (startsWith(what, "%along:")) {
3078                         var main = RESTRIM.split(/ *: */);
3079                         addClass(toAdd, "anim-along");
3080                         if (startsWith(main[0], "-")) {
3081                             main[0] = RESTRIM;
3082                             addSpaceSeparatedAttr(toAdd, "data-reverse", "true");
3083                         }
3084                         addSpaceSeparatedAttr(toAdd, "data-path", main[0]);
3085                         addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
3086                         dd();
3087                     } else if (startsWith(what, "%%class:")) {
3088                         var main = RESTRIM.split(/ *: */);
3089                         addClass(toAdd, "anim-addclass");
3090                         addSpaceSeparatedAttr(toAdd, "data-class", main[0]);
3091                         addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
3092                     } else if (startsWith(what, "%-class:")) {
3093                         var main = RESTRIM.split(/ *: */);
3094                         addClass(toAdd, "anim-removeclass");
3095                         addSpaceSeparatedAttr(toAdd, "data-class", main[0]);
3096                         addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
3097                     } else if (startsWith(what, "+")) {
3098                         addClass(toAdd, "anim-show");
3099                         dw();
3100                     } else if (startsWith(what, "-")) {
3101                         addClass(toAdd, "anim-hide");
3102                         dw(); dd();
3103                     } else {
3104                         addClass(toAdd, "anim-show");
3105                         addSpaceSeparatedAttr(toAdd, "data-what", what);
3106                         dd();
3107                     }
3108                     if (continuating) addClass(toAdd, "anim-continue");
3109                     allToAdd.push(toAdd);
3110                 }
3111             }
3112             tree.splice.apply(tree, [index, 1].concat(allToAdd)); // just replacing the text with allToAdd elements
3113         } else {
3114             return false;
3115         }
3116         // TODO? handle the decorations for comments
3117         return true;
3118     }
3119     function processMath(content) {
3120         return content.replace(/\$([^$][^$]*)\$/g, '<span class="latex">\\displaystyle $1</span>').replace(/\$\$/, '$');
3121     }
3122
3123     var interpretationOfSmartLanguage = function(smark, doc) {
3124         var jstree = markdown.toHTMLTree(smark);
3125         
3126         // split at each h2 or h1
3127         (function makeTopLevelDivs(jsTree) {
3128             var firstIndex = findTag(jsTree, /^(h1|h2)$/);
3129             if (firstIndex == -1) return;
3130             var secondIndex = findTag(jsTree, /^(h1|h2)$/, firstIndex+1);
3131             if (secondIndex == -1) secondIndex = jsTree.length;
3132             var slide = ["section"].concat( // we will add the 'slide' class later below
3133                 jsTree.splice(firstIndex, secondIndex - firstIndex));
3134             jsTree.splice(firstIndex, 0, slide);
3135             makeTopLevelDivs(jsTree);
3136         })(jstree);
3137
3138         // process:
3139         // - the class and id decorations like    {#first hightlight slide}
3140         // - the @... custom notations
3141         // - the // for comments
3142         for (s in jstree) {
3143             if (s == 0 || (s==1 && isObject(jstree[1]))) continue;
3144             var slide = jstree[s];
3145             ensureHasAttributes(slide);
3146             if (maybeProcessCopySlide(jstree, s)) {
3147                 //continue;
3148                 // actually we want to apply anims to it
3149             }
3150             // cleanup: first, remove first "p" in a "li" (happens when one put an empty line in a bullet list, but it would break the decorations)
3151             (function patch(tree){ // tree is slide or a subelement
3152                 var i = 1;
3153                 while (i < tree.length) {
3154                     if (isArray(tree[i])) {
3155                         if (tree[i][0] === "li") {
3156                             var li = tree[i];
3157                             if (isArray(li[1]) && li[1][0] === "p") {
3158                                 li.splice.apply(li, [1, 1].concat(li[1].slice(1)));
3159                                 continue;
3160                             }
3161                         }
3162                         patch(tree[i]);
3163                     }
3164                     i++;
3165                 }
3166             })(slide);
3167             // process @anim... and {} decoration
3168             (function patch(tree){ // tree is slide or a subelement
3169                 var i = 1;
3170                 while (i < tree.length) {
3171                     if (isArray(tree[i])) patch(tree[i]);
3172                     else if (typeof(tree[i]) == 'string') {
3173                         if (maybeProcessComment(tree, i)) continue;
3174                         else if (maybeProcessAtSomething(tree, i)) continue;
3175                         else if (hasIDOrClassDecoration(tree[i])) {
3176                             if (processIDOrClassDecoration(tree, i)) {
3177                                 i++; // avoid processing the same element twice
3178                             }
3179                         }
3180                     }
3181                     i++;
3182                 }
3183             })(slide);
3184             // cleanup: hide empty "li" after @anim processing
3185             (function patch(tree){ // tree is slide or a subelement
3186                 var i = 1;
3187                 while (i < tree.length) {
3188                     if (isArray(tree[i])) {
3189                         if (tree[i][0] === "li" && possiblyHideIfEmpty(tree[i])) continue;
3190                         else patch(tree[i]);
3191                     }
3192                     i++;
3193                 }
3194             })(slide);
3195             // process the $math$
3196             (function patch(tree){ // tree is slide or a subelement
3197                 if (hasClass(tree, "smark-nomath")) return;
3198                 var i = 1;
3199                 while (i < tree.length) {
3200                     if (isArray(tree[i])) patch(tree[i]);
3201                     else if (typeof(tree[i]) == 'string') {
3202                         tree[i] = processMath(tree[i]);
3203                     }
3204                     i++;
3205                 }
3206             })(slide);
3207             // change things to textarea (to help with codemirror) https://github.com/iros/deck.js-codemirror/issues/19
3208             (function patch(tree){ // tree is slide or a subelement
3209                 if (hasClass(tree, "smark-textarea")) {
3210                     tree[3][0] = "textarea";
3211                 }
3212                 var i = 1;
3213                 while (i < tree.length) {
3214                     if (isArray(tree[i])) patch(tree[i]);
3215                     i++;
3216                 }
3217             })(slide);
3218             // now propagate to the slide
3219             var hAttributes = lazyGetAttributes(slide[2]);
3220             if (slide[1]['class']) {
3221                 var cl = slide[1]['class'];
3222                 slide[1] = clone(hAttributes);
3223                 addClass(slide, cl);
3224             } else {
3225                 slide[1] = clone(hAttributes);
3226             }
3227             lazyUnsetAttributes(slide[2]);
3228             addClass(slide, 'slide');
3229         }
3230
3231         return markdown.renderJsonML(jstree);
3232     }
3233
3234     // this have to be executed before the deck init
3235     $d.bind('deck.beforeInit', function() {
3236         $('.smark').each(function() { // TODO make it configurable
3237             var it = this;
3238             var slides = interpretationOfSmartLanguage(it.innerHTML, document);
3239             $(it).after(slides);
3240             // remove the smart node (to avoid having an empty non-slide sibling (e.g., in the presenter view))
3241             $(it).remove();
3242         });
3243         var opts = $[deck]('getOptions');
3244         var maybe = function(f) { return f || (function(){}); }
3245         maybe(opts.AFTERSMARKDOWN)();
3246         $[deck]('reInitSlidesArray')
3247     });
3248
3249 })(jQuery, 'deck');
3250
3251 /*!
3252   Deck JS - deck.fit
3253   Copyright (c) 2012 RĂ©mi Emonet
3254   Licensed under the MIT license.
3255   https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
3256 */
3257
3258 /*
3259   This extension provides a way of scaling the slides to fit the slide container.
3260   A "design size" is used to do global scaling of all slides in the same way.
3261   The default design size is 800x600.
3262 */
3263 (function($, deck, window, undefined) {
3264     var $d = $(document),
3265     $w = $(window),
3266     timer, // Timeout id for debouncing
3267     rootSlides,
3268     
3269     /*
3270       Internal function to do all the dirty work of scaling the slides.
3271     */
3272     scaleDeck = function() {
3273         var opts = $[deck]('getOptions');
3274         var addMarginX = opts.fitMarginX * 2;
3275         var addMarginY = opts.fitMarginY * 2;
3276         var fitMode = opts.fitMode;
3277         var sdw = opts.designWidth;
3278         var sdh = opts.designHeight;
3279         var $container = $[deck]('getContainer');
3280         var scaleX = $container.hasClass(opts.classes.globalscale) ? $container.innerWidth() / (sdw+addMarginX) : 1;
3281         var scaleY = $container.hasClass(opts.classes.globalscale) ? $container.innerHeight() / (sdh+addMarginY) : 1;
3282         //var truescaleX = $container.hasClass(opts.classes.globalscale) ? $container.innerWidth() / (sdw) : 1;
3283         //var truescaleY = $container.hasClass(opts.classes.globalscale) ? $container.innerHeight() / (sdh) : 1;
3284         var scale = scaleX < scaleY ? scaleX : scaleY;
3285         var rootSlides = [];
3286         var slideTest = $.map([opts.classes.before, opts.classes.previous, opts.classes.current, opts.classes.next, opts.classes.after],
3287                               function(el, i) {return '.' + el;}).join(', ');
3288
3289         $.each($[deck]('getSlides'), function(i, $el) {
3290             if (!$el.parentsUntil(opts.selectors.container).length) {
3291                 rootSlides.push($el);
3292             }
3293         });
3294         $.each(rootSlides, function(i, $slide) {
3295             $slide.css('width', sdw);
3296             $slide.css('height', sdh);
3297             $.each('Webkit Moz O ms Khtml'.split(' '), function(i, prefix) {
3298                 if (scale == 1) {
3299                     $slide.css(prefix + 'Transform', '');
3300                 } else {
3301                     if (fitMode == "left top" || fitMode == "top left") {
3302                         // ok align left/top (ok with the percents)
3303                         $slide.css(prefix + 'Transform', 'translate(-50%,-50%) scale(' + scale + ' , ' + scale + ') translate(50%,50%) translate('+(addMarginX/2)+'px,'+(addMarginY/2)+'px)');
3304                     } else if (fitMode == "center middle") {
3305                         // ok align center/middle
3306                         $slide.css(prefix + 'Transform', 'translate(-50%,-50%) scale(' + scale + ' , ' + scale + ') translate(50%, 50%) translate('+($container.innerWidth()/2/scale - sdw/2)+'px,'+($container.innerHeight()/2/scale - sdh/2)+'px)');
3307                     } else if (fitMode == "right bottom" || fitMode == "bottom right") {
3308                         // ok align right/bottom
3309                         $slide.css(prefix + 'Transform', 'translate(-50%,-50%) scale(' + scale + ' , ' + scale + ') translate(50%, 50%) translate('+($container.innerWidth()/scale - sdw - addMarginX/2)+'px,'+($container.innerHeight()/scale - sdh - addMarginY/2)+'px)');
3310                     } else if (fitMode == "stretched") {
3311                         // ok stretched (with respect of the margin, i.e., it is center/middle)
3312                         $slide.css(prefix + 'Transform', 'scale(' + scaleX + ' , ' + scaleY + ') translate('+(($container.innerWidth()-sdw)/2/scaleX)+'px,'+(($container.innerHeight()-sdh)/2/scaleY)+'px)');
3313                     }
3314                 }
3315             });
3316         });
3317         
3318     }
3319     
3320     /*
3321       Extends defaults/options.
3322       
3323       options.designWidth
3324       Defaults to 800. You may instead specify a width as a number
3325       of px and all slides will be scaled in the same way, considering their
3326       size is the provided one.
3327       
3328       options.designHeight
3329       Defaults to 600. You may instead specify a height as a number
3330       of px and all slides will be scaled in the same way, considering their
3331       size is the provided one.
3332       
3333       options.fitMode
3334       How to adapt the slide to the container.
3335       Only the following combinations are available for now:
3336       "center middle", "top left", "bottom right", "stretched"
3337     
3338       options.fitMarginX
3339       options.fitMarginY
3340       Defaults to 5. Adds some margin in design space units.
3341       E.g., if the designe width is 800 and the margin is 5, the slide will be
3342       810 pixel wide before rescaling.
3343     
3344       options.scaleDebounce
3345       Scaling on the browser resize event is debounced. This number is the
3346       threshold in milliseconds. You can learn more about debouncing here:
3347       http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
3348       
3349     */
3350     $.extend(true, $[deck].defaults, {
3351         classes: {
3352             globalscale: 'deck-globalscale'
3353         },
3354         keys: {
3355             scale: 83 // s
3356         },
3357         
3358         designWidth: 800,
3359         designHeight: 600,
3360         fitMode: "center middle",
3361         fitMarginX: 0,
3362         fitMarginY: 0,
3363         scaleDebounce: 200
3364     });
3365     
3366     /*
3367       jQuery.deck('disableScale')
3368       
3369       Disables scaling and removes the scale class from the deck container.
3370     */
3371     $[deck]('extend', 'disableScale', function() {
3372         $[deck]('getContainer').removeClass($[deck]('getOptions').classes.globalscale);
3373         scaleDeck();
3374     });
3375     
3376     /*
3377       jQuery.deck('enableScale')
3378       
3379       Enables scaling and adds the scale class to the deck container.
3380     */
3381     $[deck]('extend', 'enableScale', function() {
3382         $[deck]('getContainer').addClass($[deck]('getOptions').classes.globalscale);
3383         scaleDeck();
3384     });
3385     
3386     /*
3387       jQuery.deck('toggleScale')
3388       
3389       Toggles between enabling and disabling scaling.
3390     */
3391     $[deck]('extend', 'toggleScale', function() {
3392         var $c = $[deck]('getContainer');
3393         $[deck]($c.hasClass($[deck]('getOptions').classes.globalscale) ?
3394                 'disableScale' : 'enableScale');
3395     });
3396     
3397     $d.bind('deck.init', function() {
3398         var opts = $[deck]('getOptions');
3399         
3400         // Debounce the resize scaling
3401         $w.unbind('resize.deckscale').bind('resize.deckscale', function() {
3402             window.clearTimeout(timer);
3403             timer = window.setTimeout(scaleDeck, opts.scaleDebounce);
3404         })
3405         // Scale once on load, in case images or something change layout
3406             .unbind('load.deckscale').bind('load.deckscale', scaleDeck);
3407         
3408         // Bind key events
3409         $d.unbind('keydown.deckscale').bind('keydown.deckscale', function(e) {
3410             if (e.which === opts.keys.scale || $.inArray(e.which, opts.keys.scale) > -1) {
3411                 $[deck]('toggleScale');
3412                 e.preventDefault();
3413             }
3414         });
3415         
3416         // Enable scale on init
3417         $[deck]('enableScale');
3418     });
3419 })(jQuery, 'deck', this);
3420
3421
3422 // This script was automatically generated from a literate source.  
3423 // Do not edit this file; look at the literate source instead!
3424 //
3425 // Greasemonkey user script to 
3426 // Display LaTeX in Web pages by transforming to MathML
3427 // --------------------------------------------------------------------
3428
3429 // Original script by
3430 // Copyright (C) 2006 Steve Cheng <stevecheng@users.sourceforge.net>
3431 // Home page: http://gold-saucer.afraid.org/mathml/greasemonkey/
3432 //
3433 // Modified by
3434 // Copyright (C) 2010 Valery Alexeev <va.email.tex@gmail.com>
3435 // Version 1.15, May 7, 2010
3436 // as follows:
3437 //
3438 // Added arxiv.org, front.math.ucdavis.edu, *mathscinet*, mail.google.com
3439 // Changed char_map to fix the display for \mathcal, \mathbb, \mathfrak
3440 // Fixed the displayed formulas with $$...$$ and \[...\]
3441 // Added \scr, \germ, \roman, etc used by Mathscinet.
3442 // Added miscellaneous symbols and arrows 
3443
3444 // Permission is hereby granted, free of charge, to any person obtaining
3445 // a copy of this software and associated documentation files (the
3446 // "Software"), to deal in the Software without restriction, including
3447 // without limitation the rights to use, copy, modify, merge, publish,
3448 // distribute, sublicense, and/or sell copies of the Software, and to
3449 // permit persons to whom the Software is furnished to do so, subject to
3450 // the following conditions:
3451
3452 // The above copyright notice and this permission notice shall be included
3453 // in all copies or substantial portions of the Software.
3454
3455 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3456 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3457 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
3458 // IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
3459 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
3460 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
3461 // OTHER DEALNGS IN THE SOFTWARE.
3462
3463
3464 function latex2mml() {
3465
3466
3467     function GM_log() {}
3468
3469
3470 // First, find out where we are
3471 var va_loc = window.location.href;
3472 var va_view = 'web';
3473
3474 //alert( 'va_view=' + va_view );
3475
3476 // The script itself begins
3477
3478 var/*const*/ mmlns = 'http://www.w3.org/1998/Math/MathML';
3479
3480 /*
3481 // VA: Fix displayed equations first.
3482 if( va_view == 'web' ){
3483     document.body.innerHTML=
3484         document.body.innerHTML.replace(/\n/g," "); // remove end-of-lines
3485     document.body.innerHTML=
3486         document.body.innerHTML.replace(/(\$\$|\\\[)([^$]+)(\$\$|\\\])/g,
3487                                         "<p style=\"text-indent: 20px;\"> \$ $2 \$ </p>");
3488 // VA: Experimental: may lead to slow down. \spcheck is used on MathSciNet
3489 // document.body.innerHTML=
3490 // document.body.innerHTML.replace(/\\spcheck/g,"^{\\vee}");
3491 }
3492 */
3493
3494
3495 function result_element(tag, num_attrs)
3496 {
3497   var node = document.createElementNS(mmlns, tag);
3498
3499   var k = 2;
3500   while(--num_attrs >= 0) {
3501     if(arguments[k+1] != null) {
3502       node.setAttribute(arguments[k], arguments[k+1]);
3503     }
3504     k += 2;
3505   }
3506     
3507   for(; k < arguments.length; k++) {
3508     if(arguments[k] != null) {
3509       if(typeof(arguments[k]) == 'string')
3510         node.appendChild(document.createTextNode(arguments[k]));
3511       else
3512         node.appendChild(arguments[k]);
3513     }
3514   }
3515
3516   return node;
3517 }
3518
3519
3520 function result_element_append(parent, child)
3521 {
3522   if(parent != null && child != null) {
3523     if(typeof(child) == 'string')
3524       parent.appendChild(document.createTextNode(child));
3525     else
3526       parent.appendChild(child);
3527   }
3528 }
3529
3530
3531 function result_element_prepend(parent, child, next)
3532 {
3533   if(next == null)
3534     result_element_append(parent, child);
3535   else if (parent != null && child != null)
3536     parent.insertBefore(child, next);
3537 }
3538
3539
3540 function result_set_attr(elem, attr, value)
3541 {
3542   if(elem != null && attr != null) {
3543     if(value != null)
3544       elem.setAttribute(attr, value);
3545     else
3546       elem.removeAttribute(attr);
3547   }
3548 }
3549
3550
3551 function result_append_attr(elem, attr, value)
3552 {
3553   if(elem != null && attr != null) {
3554     var old_value = elem.getAttribute(elem, attr);
3555     if(old_value == null)
3556       elem.setAttribute(attr, value);
3557     else
3558       elem.setAttribute(attr, old_value + value);
3559   }
3560 }
3561
3562 /*
3563 if( va_view == 'web' ){
3564     if(!this.GM_getValue) {
3565         this.GM_getValue = function(key, value) { return value; }
3566         this.GM_log = function() {}
3567     }
3568     
3569     
3570     if(this.GM_registerMenuCommand) {
3571         GM_registerMenuCommand("Enable native display of math images", 
3572                                function() {
3573                                    GM_setValue("patch-images", true);
3574                                    do_patch_images = true;
3575                                    patch_element(document.documentElement);
3576                                });
3577         GM_registerMenuCommand("Disable native display of math images",
3578                                function() {
3579                                    GM_setValue("patch-images", false);
3580                                });
3581     }
3582 }
3583 */
3584
3585 // VA: changed char_map
3586 var/*const*/ char_map = {
3587   'script': [
3588              '\uD835\uDC9C', '\u212C', '\uD835\uDC9E', //abc
3589              '\uD835\uDC9F', '\u2130', '\u2131', //def
3590              '\uD835\uDCA2', '\u210B', '\u2110', //ghi
3591              '\uD835\uDCA5', '\uD835\uDCA6', '\u2112', //jkl
3592              '\u2133', '\uD835\uDCA9', '\uD835\uDCAA', //mno
3593              '\uD835\uDCAB', '\uD835\uDCAC', '\u211B', //pqr
3594              '\uD835\uDCAE', '\uD835\uDCAF', '\uD835\uDCB0', //stu
3595              '\uD835\uDCB1', '\uD835\uDCB2', '\uD835\uDCB3', //vwx
3596              '\uD835\uDCB4', '\uD835\uDCB5' ], //yz
3597
3598   'fraktur': [
3599               '\uD835\uDD04', '\uD835\uDD05', '\u212D', //abc
3600               '\uD835\uDD07', '\uD835\uDD08', '\uD835\uDD09', //def
3601               '\uD835\uDD0A', '\u210C', '\u2111', //ghi
3602               '\uD835\uDD0D', '\uD835\uDD0E', '\uD835\uDD0F', //jkl
3603               '\uD835\uDD10', '\uD835\uDD11', '\uD835\uDD12', //mno
3604               '\uD835\uDD13', '\uD835\uDD14', '\u211C', //pqr
3605               '\uD835\uDD16', '\uD835\uDD17', '\uD835\uDD18', //stu
3606               '\uD835\uDD19', '\uD835\uDD1A', '\uD835\uDD1B', //vwx
3607               '\uD835\uDD1C', '\u2128' ], //yz
3608
3609   'double-struck': [
3610                     '\uD835\uDD38', '\uD835\uDD39', '\u2102', //abc
3611                     '\uD835\uDD3B', '\uD835\uDD3C', '\uD835\uDD3D', //def
3612                     '\uD835\uDD3E', '\u210D', '\uD835\uDD40', //ghi
3613                     '\uD835\uDD41', '\uD835\uDD42', '\uD835\uDD43', //jkl
3614                     '\uD835\uDD44', '\u2115', '\uD835\uDD46', //mno
3615                     '\u2119', '\u211A', '\u211D', //pqr
3616                     '\uD835\uDD4A', '\uD835\uDD4B', '\uD835\uDD4C', //stu
3617                     '\uD835\uDD4D', '\uD835\uDD4E', '\uD835\uDD4F', //vwx
3618                     '\uD835\uDD50', '\u2124', ], //yz
3619 };
3620
3621 var/*const*/ uppercase_re = /[A-Z]/;
3622
3623 function fix_mathvariant(node, style)
3624 {
3625   if(node.nodeType == node.TEXT_NODE) {
3626     if(style != null && style != '' && style in char_map) {
3627       node.data = node.data.replace(uppercase_re,
3628         function(s) {return char_map[style][s.charCodeAt(0)-65]});
3629     }
3630   } else if(node.nodeType == node.ELEMENT_NODE) {
3631     var new_style = node.getAttribute('mathvariant');
3632     if(new_style != null && new_style != '')
3633       style = new_style;
3634
3635     for(var i=0; i < node.childNodes.length; i++)
3636       fix_mathvariant(node.childNodes.item(i), style);
3637   }
3638 }
3639
3640 var g_punct_and_space
3641 = {"\\quad" : "\u2003" ,
3642 "\\qquad" : "\u2003\u2003" ,
3643 "\\thickspace" : "\u2002" ,
3644 "\\;" : "\u2002" ,
3645 "\\medspace" : "\u2005" ,
3646 "\\:" : "\u2005" ,
3647 "\\thinspace" : "\u2004" ,
3648 "\\," : "\u2004" ,
3649 "\\!" : "\u200b" ,
3650 "." : "." ,
3651 ";" : ";" ,
3652 "?" : "?" ,
3653 "\\qedsymbol" : "\u25a0" ,
3654 }
3655 ;
3656 var g_left_delimiters
3657 = {"(" : "(" ,
3658 "[" : "[" ,
3659 "\\{" : "{" ,
3660 "\\lgroup" : "(" ,
3661 "\\lbrace" : "{" ,
3662 "\\lvert" : "|" ,
3663 "\\lVert" : "\u2016" ,
3664 "\\lceil" : "\u2308" ,
3665 "\\lfloor" : "\u230a" ,
3666 "\\lmoustache" : "\u23b0" ,
3667 "\\langle" : "\u2329" ,
3668 }
3669 ;
3670 var g_right_delimiters
3671 = {")" : ")" ,
3672 "]" : "]" ,
3673 "\\}" : "}" ,
3674 "\\rbrace" : "}" ,
3675 "\\rgroup" : ")" ,
3676 "\\rvert" : "|" ,
3677 "\\rVert" : "\u2016" ,
3678 "\\rceil" : "\u2309" ,
3679 "\\rfloor" : "\u230b" ,
3680 "\\rmoustache" : "\u23b1" ,
3681 "\\rangle" : "\u232a" ,
3682 }
3683 ;
3684 var g_operator_symbols
3685 = {"\\amalg" : "\u2a3f" ,
3686 "\\ast" : "*" ,
3687 "\\ast" : "\u2217" ,
3688 "\\barwedge" : "\u22bc" ,
3689 "\\barwedge" : "\u2305" ,
3690 "\\bigcirc" : "\u25cb" ,
3691 "\\bigtriangledown" : "\u25bd" ,
3692 "\\bigtriangleup" : "\u25b3" ,
3693 "\\boxdot" : "\u22a1" ,
3694 "\\boxminus" : "\u229f" ,
3695 "\\boxplus" : "\u229e" ,
3696 "\\boxtimes" : "\u22a0" ,
3697 "\\bullet" : "\u2022" ,
3698 "\\bullet" : "\u2219" ,
3699 "\\cap" : "\u2229" ,
3700 "\\Cap" : "\u22d2" ,
3701 "\\cdot" : "\u22c5" ,
3702 "\\centerdot" : "\u00b7" ,
3703 "\\circ" : "\u2218" ,
3704 "\\circledast" : "\u229b" ,
3705 "\\circledcirc" : "\u229a" ,
3706 "\\circleddash" : "\u229d" ,
3707 "\\cup" : "\u222a" ,
3708 "\\Cup" : "\u22d3" ,
3709 "\\curlyvee" : "\u22ce" ,
3710 "\\curlywedge" : "\u22cf" ,
3711 "\\dagger" : "\u2020" ,
3712 "\\ddagger" : "\u2021" ,
3713 "\\diamond" : "\u22c4" ,
3714 "\\div" : "\u00f7" ,
3715 "\\divideontimes" : "\u22c7" ,
3716 "\\dotplus" : "\u2214" ,
3717 "\\doublebarwedge" : "\u2306" ,
3718 "\\doublecap" : "\u22d2" ,
3719 "\\doublecup" : "\u22d3" ,
3720 "\\gtrdot" : "\u22d7" ,
3721 "\\intercal" : "\u22ba" ,
3722 "\\land" : "\u2227" ,
3723 "\\leftthreetimes" : "\u22cb" ,
3724 "\\lessdot" : "\u22d6" ,
3725 "\\lor" : "\u2228" ,
3726 "\\ltimes" : "\u22c9" ,
3727 "\\mp" : "\u2213" ,
3728 "\\odot" : "\u2299" ,
3729 "\\ominus" : "\u2296" ,
3730 "\\oplus" : "\u2295" ,
3731 "\\oslash" : "\u2298" ,
3732 "\\otimes" : "\u2297" ,
3733 "\\pm" : "\u00b1" ,
3734 "\\rightthreetimes" : "\u22cc" ,
3735 "\\rtimes" : "\u22ca" ,
3736 "\\setminus" : "\u2216" ,
3737 "\\smallsetminus" : "\u2216" ,
3738 "\\sqcap" : "\u2293" ,
3739 "\\sqcup" : "\u2294" ,
3740 "\\star" : "\u22c6" ,
3741 "\\times" : "\u00d7" ,
3742 "\\triangleleft" : "\u25c1" ,
3743 "\\triangleright" : "\u25b7" ,
3744 "\\uplus" : "\u228e" ,
3745 "\\vee" : "\u2228" ,
3746 "\\spcheck" : "\u207a" , // has to be ^{\vee} instead but that's hard
3747                          // to code
3748     //"\\spcheck" : "\u002a" , 
3749 "\\veebar" : "\u22bb" ,
3750 "\\veebar" : "\u2a61" ,
3751 "\\wedge" : "\u2227" ,
3752 "\\wr" : "\u2240" ,
3753 "+" : "+" ,
3754 "-" : "\u2212" ,
3755 "*" : "*" ,
3756 "," : "," ,
3757 "/" : "\u2215" ,
3758 ":" : ":" ,
3759 "\\colon" : ":" ,
3760 "|" : "|" ,
3761 "\\vert" : "|" ,
3762 "\\Vert" : "\u2016" ,
3763 "\\|" : "\u2016" ,
3764 "\\backslash" : "\\" ,
3765 "'" : "\u2032" ,
3766 "\\#" : "#" ,
3767 "\\bmod" : "mod" ,
3768 "\\mod" : "mod" ,
3769 "\\downarrow" : "\u2193" ,
3770 "\\Downarrow" : "\u21d3" ,
3771 "\\uparrow" : "\u2191" ,
3772 "\\Uparrow" : "\u21d1" ,
3773 "\\updownarrow" : "\u2195" ,
3774 "\\Updownarrow" : "\u21d5" ,
3775 "\\bigcap" : "\u22c2" ,
3776 "\\bigcup" : "\u22c3" ,
3777 "\\bigodot" : "\u2a00" ,
3778 "\\bigoplus" : "\u2a01" ,
3779 "\\bigotimes" : "\u2a02" ,
3780 "\\bigsqcup" : "\u2a06" ,
3781 "\\biguplus" : "\u2a04" ,
3782 "\\bigvee" : "\u22c1" ,
3783 "\\bigwedge" : "\u22c0" ,
3784 "\\coprod" : "\u2210" ,
3785 "\\prod" : "\u220f" ,
3786 "\\sum" : "\u2211" ,
3787 "\\int" : "\u222b" ,
3788 "\\smallint" : "\u222b" ,
3789 "\\oint" : "\u222e" ,
3790 "\\angle" : "\u2220" ,
3791 "\\backprime" : "\u2035" ,
3792 "\\bigstar" : "\u2605" ,
3793 "\\blacklozenge" : "\u29eb" ,
3794 "\\blacksquare" : "\u25a0" ,
3795 "\\blacktriangle" : "\u25b4" ,
3796 "\\blacktriangledown" : "\u25be" ,
3797 "\\bot" : "\u22a5" ,
3798 "\\clubsuit" : "\u2663" ,
3799 "\\diagdown" : "\u2572" ,
3800 "\\diagup" : "\u2571" ,
3801 "\\diamondsuit" : "\u2662" ,
3802 "\\emptyset" : "\u2205" ,
3803 "\\exists" : "\u2203" ,
3804 "\\flat" : "\u266d" ,
3805 "\\forall" : "\u2200" ,
3806 "\\heartsuit" : "\u2661" ,
3807 "\\infty" : "\u221e" ,
3808 "\\lnot" : "\u00ac" ,
3809 "\\lozenge" : "\u25ca" ,
3810 "\\measuredangle" : "\u2221" ,
3811 "\\nabla" : "\u2207" ,
3812 "\\natural" : "\u266e" ,
3813 "\\neg" : "\u00ac" ,
3814 "\\nexists" : "\u2204" ,
3815 "\\prime" : "\u2032" ,
3816 "\\sharp" : "\u266f" ,
3817 "\\spadesuit" : "\u2660" ,
3818 "\\sphericalangle" : "\u2222" ,
3819 "\\square" : "\u25a1" ,
3820 "\\surd" : "\u221a" ,
3821 "\\top" : "\u22a4" ,
3822 "\\triangle" : "\u25b5" ,
3823 "\\triangledown" : "\u25bf" ,
3824 "\\varnothing" : "\u2205" ,
3825 "\\aleph" : "\u2135" ,
3826 "\\Bbbk" : "\u1d55C" ,
3827 "\\beth" : "\u2136" ,
3828 "\\circledS" : "\u24c8" ,
3829 "\\complement" : "\u2201" ,
3830 "\\daleth" : "\u2138" ,
3831 "\\ell" : "\u2113" ,
3832 "\\eth" : "\u00f0" ,
3833 "\\Finv" : "\u2132" ,
3834 "\\Game" : "\u2141" ,
3835 "\\gimel" : "\u2137" ,
3836 "\\hbar" : "\u210f" ,
3837 "\\hslash" : "\u210f" ,
3838 "\\Im" : "\u2111" ,
3839 "\\mho" : "\u2127" ,
3840 "\\partial" : "\u2202" ,
3841 "\\Re" : "\u211c" ,
3842 "\\wp" : "\u2118" ,
3843 }
3844 ;
3845 var g_relation_symbols
3846 = {"=" : "=" ,
3847 "<" : "<" ,
3848 ">" : ">" ,
3849 "\\approx" : "\u2248" ,
3850 "\\approxeq" : "\u224a" ,
3851 "\\asymp" : "\u2248" ,
3852 "\\backsim" : "\u223d" ,
3853 "\\backsimeq" : "\u22cd" ,
3854 "\\bumpeq" : "\u224f" ,
3855 "\\Bumpeq" : "\u224e" ,
3856 "\\circeq" : "\u2257" ,
3857 "\\cong" : "\u2245" ,
3858 "\\curlyeqprec" : "\u22de" ,
3859 "\\curlyeqsucc" : "\u22df" ,
3860 "\\doteq" : "\u2250" ,
3861 "\\doteqdot" : "\u2251" ,
3862 "\\eqcirc" : "\u2256" ,
3863 "\\eqsim" : "\u2242" ,
3864 "\\eqslantgtr" : "\u2a96" ,
3865 "\\eqslantless" : "\u2a95" ,
3866 "\\equiv" : "\u2261" ,
3867 "\\fallingdotseq" : "\u2252" ,
3868 "\\ge" : "\u2265" ,
3869 "\\geq" : "\u2265" ,
3870 "\\geqq" : "\u2267" ,
3871 "\\geqslant" : "\u2a7e" ,
3872 "\\gg" : "\u226b" ,
3873 "\\gg" : "\u2aa2" ,
3874 "\\ggg" : "\u22d9" ,
3875 "\\gggtr" : "\u22d9" ,
3876 "\\gnapprox" : "\u2a8a" ,
3877 "\\gneq" : "\u2a88" ,
3878 "\\gneqq" : "\u2269" ,
3879 "\\gnsim" : "\u22e7" ,
3880 "\\gtrapprox" : "\u2a86" ,
3881 "\\gtreqless" : "\u22db" ,
3882 "\\gtreqqless" : "\u2a8c" ,
3883 "\\gtrless" : "\u2277" ,
3884 "\\gtrsim" : "\u2273" ,
3885 "\\gvertneqq" : "\u2269" ,
3886 "\\le" : "\u2264" ,
3887 "\\leq" : "\u2264" ,
3888 "\\leqq" : "\u2266" ,
3889 "\\leqslant" : "\u2a7d" ,
3890 "\\lessapprox" : "\u2a85" ,
3891 "\\lesseqgtr" : "\u22da" ,
3892 "\\lesseqqgtr" : "\u2a8b" ,
3893 "\\lessgtr" : "\u2276" ,
3894 "\\lesssim" : "\u2272" ,
3895 "\\ll" : "\u226a" ,
3896 "\\llless" : "\u22d8" ,
3897 "\\lnapprox" : "\u2a89" ,
3898 "\\lneq" : "\u2a87" ,
3899 "\\lneqq" : "\u2268" ,
3900 "\\lnsim" : "\u22e6" ,
3901 "\\lvertneqq" : "\u2268" ,
3902 "\\ncong" : "\u2247" ,
3903 "\\ne" : "\u2260" ,
3904 "\\neq" : "\u2260" ,
3905 "\\ngeq" : "\u2271" ,
3906 "\\ngeqq" : "\u2267" ,
3907 "\\ngeqslant" : "\u2a7e" ,
3908 "\\ngtr" : "\u226f" ,
3909 "\\nleq" : "\u2270" ,
3910 "\\nleqq" : "\u2266" ,
3911 "\\nleqslant" : "\u2a7d" ,
3912 "\\nless" : "\u226e" ,
3913 "\\nprec" : "\u2280" ,
3914 "\\npreceq" : "\u2aaf" ,
3915 "\\nsim" : "\u2241" ,
3916 "\\nsucc" : "\u2281" ,
3917 "\\nsucceq" : "\u2ab0" ,
3918 "\\prec" : "\u227a" ,
3919 "\\precapprox" : "\u2ab7" ,
3920 "\\preccurlyeq" : "\u227c" ,
3921 "\\preceq" : "\u2aaf" ,
3922 "\\precnapprox" : "\u2ab9" ,
3923 "\\precneqq" : "\u2ab5" ,
3924 "\\precnsim" : "\u22e8" ,
3925 "\\precsim" : "\u227e" ,
3926 "\\risingdotseq" : "\u2253" ,
3927 "\\sim" : "\u223c" ,
3928 "\\simeq" : "\u2243" ,
3929 "\\succ" : "\u227b" ,
3930 "\\succapprox" : "\u2ab8" ,
3931 "\\succcurlyeq" : "\u227d" ,
3932 "\\succeq" : "\u2ab0" ,
3933 "\\succnapprox" : "\u2aba" ,
3934 "\\succneqq" : "\u2ab6" ,
3935 "\\succnsim" : "\u22e9" ,
3936 "\\succsim" : "\u227f" ,
3937 "\\thickapprox" : "\u2248" ,
3938 "\\thicksim" : "\u223c" ,
3939 "\\triangleq" : "\u225c" ,
3940 "\\longrightarrow" : "\u27F6" ,
3941 "\\curvearrowleft" : "\u21b6" ,
3942 "\\curvearrowright" : "\u21b7" ,
3943 "\\downdownarrows" : "\u21ca" ,
3944 "\\downharpoonleft" : "\u21c3" ,
3945 "\\downharpoonright" : "\u21c2" ,
3946 "\\gets" : "\u2190" ,
3947 "\\hookleftarrow" : "\u21a9" ,
3948 "\\hookrightarrow" : "\u21aa" ,
3949 "\\leftarrow" : "\u2190" ,
3950 "\\Leftarrow" : "\u21d0" ,
3951 "\\leftarrowtail" : "\u21a2" ,
3952 "\\leftharpoondown" : "\u21bd" ,
3953 "\\leftharpoonup" : "\u21bc" ,
3954 "\\leftleftarrows" : "\u21c7" ,
3955 "\\leftrightarrow" : "\u2194" ,
3956 "\\leftrightarrows" : "\u21c6" ,
3957 "\\leftrightharpoons" : "\u21cb" ,
3958 "\\leftrightsquigarrow" : "\u21ad" ,
3959 "\\Lleftarrow" : "\u21da" ,
3960 "\\longleftarrow" : "\u27f5" ,
3961 "\\Longleftarrow" : "\u27f8" ,
3962 "\\longleftrightarrow" : "\u27f7" ,
3963 "\\Longleftrightarrow" : "\u27fa" ,
3964 "\\looparrowleft" : "\u21ab" ,
3965 "\\looparrowright" : "\u21ac" ,
3966 "\\Lsh" : "\u21b0" ,
3967 "\\mapsto" : "\u21a6" ,
3968 "\\multimap" : "\u22b8" ,
3969 "\\nearrow" : "\u2197" ,
3970 "\\nleftarrow" : "\u219a" ,
3971 "\\nLeftarrow" : "\u21cd" ,
3972 "\\nleftrightarrow" : "\u21ae" ,
3973 "\\nLeftrightarrow" : "\u21ce" ,
3974 "\\nrightarrow" : "\u219b" ,
3975 "\\nRightarrow" : "\u21cf" ,
3976 "\\nwarrow" : "\u2196" ,
3977 "\\restriction" : "\u21be" ,
3978 "\\rightarrow" : "\u2192" ,
3979 "\\Rightarrow" : "\u21d2" ,
3980 "\\rightarrowtail" : "\u21a3" ,
3981 "\\rightharpoondown" : "\u21c1" ,
3982 "\\rightharpoonup" : "\u21c0" ,
3983 "\\rightleftarrows" : "\u21c4" ,
3984 "\\rightleftharpoons" : "\u21cc" ,
3985 "\\rightrightarrows" : "\u21c9" ,
3986 "\\rightsquigarrow" : "\u219d" ,
3987 "\\Rrightarrow" : "\u21db" ,
3988 "\\Rsh" : "\u21b1" ,
3989 "\\searrow" : "\u2198" ,
3990 "\\swarrow" : "\u2199" ,
3991 "\\to" : "\u2192" ,
3992 "\\twoheadleftarrow" : "\u219e" ,
3993 "\\twoheadrightarrow" : "\u21a0" ,
3994 "\\upharpoonleft" : "\u21bf" ,
3995 "\\upharpoonright" : "\u21be" ,
3996 "\\upuparrows" : "\u21c8" ,
3997 "\\backepsilon" : "\u03f6" ,
3998 "\\because" : "\u2235" ,
3999 "\\between" : "\u226c" ,
4000 "\\blacktriangleleft" : "\u25c0" ,
4001 "\\blacktriangleright" : "\u25b6" ,
4002 "\\bowtie" : "\u22c8" ,
4003 "\\dashv" : "\u22a3" ,
4004 "\\frown" : "\u2323" ,
4005 "\\in" : "\u220a" ,
4006 "\\mid" : "\u2223" ,
4007 "\\models" : "\u22a7" ,
4008 "\\ni" : "\u220b" ,
4009 "\\ni" : "\u220d" ,
4010 "\\nmid" : "\u2224" ,
4011 "\\notin" : "\u2209" ,
4012 "\\nparallel" : "\u2226" ,
4013 "\\nshortmid" : "\u2224" ,
4014 "\\nshortparallel" : "\u2226" ,
4015 "\\nsubseteq" : "\u2286" ,
4016 "\\nsubseteq" : "\u2288" ,
4017 "\\nsubseteqq" : "\u2ac5" ,
4018 "\\nsupseteq" : "\u2287" ,
4019 "\\nsupseteq" : "\u2289" ,
4020 "\\nsupseteqq" : "\u2ac6" ,
4021 "\\ntriangleleft" : "\u22ea" ,
4022 "\\ntrianglelefteq" : "\u22ec" ,
4023 "\\ntriangleright" : "\u22eb" ,
4024 "\\ntrianglerighteq" : "\u22ed" ,
4025 "\\nvdash" : "\u22ac" ,
4026 "\\nvDash" : "\u22ad" ,
4027 "\\nVdash" : "\u22ae" ,
4028 "\\nVDash" : "\u22af" ,
4029 "\\owns" : "\u220d" ,
4030 "\\parallel" : "\u2225" ,
4031 "\\perp" : "\u22a5" ,
4032 "\\pitchfork" : "\u22d4" ,
4033 "\\propto" : "\u221d" ,
4034 "\\shortmid" : "\u2223" ,
4035 "\\shortparallel" : "\u2225" ,
4036 "\\smallfrown" : "\u2322" ,
4037 "\\smallsmile" : "\u2323" ,
4038 "\\smile" : "\u2323" ,
4039 "\\sqsubset" : "\u228f" ,
4040 "\\sqsubseteq" : "\u2291" ,
4041 "\\sqsupset" : "\u2290" ,
4042 "\\sqsupseteq" : "\u2292" ,
4043 "\\subset" : "\u2282" ,
4044 "\\Subset" : "\u22d0" ,
4045 "\\subseteq" : "\u2286" ,
4046 "\\subseteqq" : "\u2ac5" ,
4047 "\\subsetneq" : "\u228a" ,
4048 "\\subsetneqq" : "\u2acb" ,
4049 "\\supset" : "\u2283" ,
4050 "\\Supset" : "\u22d1" ,
4051 "\\supseteq" : "\u2287" ,
4052 "\\supseteqq" : "\u2ac6" ,
4053 "\\supsetneq" : "\u228b" ,
4054 "\\supsetneqq" : "\u2acc" ,
4055 "\\therefore" : "\u2234" ,
4056 "\\trianglelefteq" : "\u22b4" ,
4057 "\\trianglerighteq" : "\u22b5" ,
4058 "\\varpropto" : "\u221d" ,
4059 "\\varsubsetneq" : "\u228a" ,
4060 "\\varsubsetneqq" : "\u2acb" ,
4061 "\\varsupsetneq" : "\u228b" ,
4062 "\\varsupsetneqq" : "\u2acc" ,
4063 "\\vartriangle" : "\u25b5" ,
4064 "\\vartriangleleft" : "\u22b2" ,
4065 "\\vartriangleright" : "\u22b3" ,
4066 "\\vdash" : "\u22a2" ,
4067 "\\vDash" : "\u22a8" ,
4068 "\\Vdash" : "\u22a9" ,
4069 "\\Vvdash" : "\u22aa" ,
4070 // AMS Arrows
4071 "\\dashleftarrow" : "\u21e0" ,
4072 "\\dashrightarrow" : "\u21e2" ,
4073 }
4074 ;
4075 var g_named_identifiers
4076 = {"\\arccos" : "arccos" ,
4077 "\\arcsin" : "arcsin" ,
4078 "\\arctan" : "arctan" ,
4079 "\\arg" : "arg" ,
4080 "\\cos" : "cos" ,
4081 "\\cosh" : "cosh" ,
4082 "\\cot" : "cot" ,
4083 "\\coth" : "coth" ,
4084 "\\csc" : "csc" ,
4085 "\\deg" : "deg" ,
4086 "\\det" : "det" ,
4087 "\\dim" : "dim" ,
4088 "\\exp" : "exp" ,
4089 "\\gcd" : "gcd" ,
4090 "\\hom" : "hom" ,
4091 "\\ker" : "ker" ,
4092 "\\lg" : "lg" ,
4093 "\\ln" : "ln" ,
4094 "\\log" : "log" ,
4095 "\\Pr" : "Pr" ,
4096 "\\sec" : "sec" ,
4097 "\\sin" : "sin" ,
4098 "\\sinh" : "sinh" ,
4099 "\\tan" : "tan" ,
4100 "\\tanh" : "tanh" ,
4101 "\\inf" : "inf" ,
4102 "\\injlim" : "inj lim" ,
4103 "\\lim" : "lim" ,
4104 "\\liminf" : "lim inf" ,
4105 "\\limsup" : "lum sup" ,
4106 "\\max" : "max" ,
4107 "\\min" : "min" ,
4108 "\\projlim" : "proj lim" ,
4109 "\\sup" : "sup" ,
4110 "\\alpha" : "\u03b1" ,
4111 "\\beta" : "\u03b2" ,
4112 "\\chi" : "\u03c7" ,
4113 "\\delta" : "\u03b4" ,
4114 "\\Delta" : "\u0394" ,
4115 "\\digamma" : "\u03dd" ,
4116 "\\epsilon" : "\u03f5" ,
4117 "\\eta" : "\u03b7" ,
4118 "\\gamma" : "\u03b3" ,
4119 "\\Gamma" : "\u0393" ,
4120 "\\iota" : "\u03b9" ,
4121 "\\kappa" : "\u03ba" ,
4122 "\\lambda" : "\u03bb" ,
4123 "\\Lambda" : "\u039b" ,
4124 "\\mu" : "\u03bc" ,
4125 "\\nu" : "\u03bd" ,
4126 "\\omega" : "\u03c9" ,
4127 "\\Omega" : "\u03a9" ,
4128 "\\phi" : "\u03c6" ,
4129 "\\Phi" : "\u03a6" ,
4130 "\\pi" : "\u03c0" ,
4131 "\\Pi" : "\u03a0" ,
4132 "\\psi" : "\u03c8" ,
4133 "\\Psi" : "\u03a8" ,
4134 "\\rho" : "\u03c1" ,
4135 "\\sigma" : "\u03c3" ,
4136 "\\Sigma" : "\u03a3" ,
4137 "\\tau" : "\u03c4" ,
4138 "\\theta" : "\u03b8" ,
4139 "\\Theta" : "\u0398" ,
4140 "\\upsilon" : "\u03c5" ,
4141 "\\Upsilon" : "\u03d2" ,
4142 "\\varepsilon" : "\u03b5" ,
4143 "\\varkappa" : "\u03f0" ,
4144 "\\varphi" : "\u03d5" ,
4145 "\\varpi" : "\u03d6" ,
4146 "\\varrho" : "\u03f1" ,
4147 "\\varsigma" : "\u03c2" ,
4148 "\\vartheta" : "\u03d1" ,
4149 "\\xi" : "\u03be" ,
4150 "\\Xi" : "\u039e" ,
4151 "\\zeta" : "\u03b6" ,
4152 "a" : "a" ,
4153 "b" : "b" ,
4154 "c" : "c" ,
4155 "d" : "d" ,
4156 "e" : "e" ,
4157 "f" : "f" ,
4158 "g" : "g" ,
4159 "h" : "h" ,
4160 "i" : "i" ,
4161 "j" : "j" ,
4162 "k" : "k" ,
4163 "l" : "l" ,
4164 "m" : "m" ,
4165 "n" : "n" ,
4166 "o" : "o" ,
4167 "p" : "p" ,
4168 "q" : "q" ,
4169 "r" : "r" ,
4170 "s" : "s" ,
4171 "t" : "t" ,
4172 "u" : "u" ,
4173 "v" : "v" ,
4174 "w" : "w" ,
4175 "x" : "x" ,
4176 "y" : "y" ,
4177 "z" : "z" ,
4178 "A" : "A" ,
4179 "B" : "B" ,
4180 "C" : "C" ,
4181 "D" : "D" ,
4182 "E" : "E" ,
4183 "F" : "F" ,
4184 "G" : "G" ,
4185 "H" : "H" ,
4186 "I" : "I" ,
4187 "J" : "J" ,
4188 "K" : "K" ,
4189 "L" : "L" ,
4190 "M" : "M" ,
4191 "N" : "N" ,
4192 "O" : "O" ,
4193 "P" : "P" ,
4194 "Q" : "Q" ,
4195 "R" : "R" ,
4196 "S" : "S" ,
4197 "T" : "T" ,
4198 "U" : "U" ,
4199 "V" : "V" ,
4200 "W" : "W" ,
4201 "X" : "X" ,
4202 "Y" : "Y" ,
4203 "Z" : "Z" ,
4204 "\\vdots" : "\u22ee" ,
4205 "\\hdots" : "\u2026" ,
4206 "\\ldots" : "\u2026" ,
4207 "\\dots" : "\u2026" ,
4208 "\\cdots" : "\u00b7\u00b7\u00b7" ,
4209 "\\dotsb" : "\u00b7\u00b7\u00b7" ,
4210 "\\dotsc" : "\u2026" ,
4211 "\\dotsi" : "\u22c5\u22c5\u22c5" ,
4212 "\\dotsm" : "\u22c5\u22c5\u22c5" ,
4213 "\\dotso" : "\u2026" ,
4214 "\\ddots" : "\u22f1" ,
4215     // Common abbreviation for \mathbb letters
4216 "\\A" : "\uD835\uDD38" ,
4217 "\\bA" : "\uD835\uDD38" ,
4218 "\\B" : "\uD835\uDD39" ,
4219 "\\bB" : "\uD835\uDD39" ,
4220 "\\C" : "\u2102" ,
4221 "\\bC" : "\u2102" ,
4222 "\\D" : "\uD835\uDD3B" ,
4223 "\\bD" : "\uD835\uDD3B" ,
4224 "\\E" : "\uD835\uDD3C" ,
4225 "\\bE" : "\uD835\uDD3C" ,
4226 "\\F" : "\uD835\uDD3D" ,
4227 "\\bF" : "\uD835\uDD3D" ,
4228 "\\G" : "\uD835\uDD3E" ,
4229 "\\bG" : "\uD835\uDD3E" ,
4230 "\\H" : "\u210D" ,
4231 "\\bH" : "\u210D" ,
4232 "\\I" : "\uD835\uDD40" ,
4233 "\\bI" : "\uD835\uDD40" ,
4234 "\\J" : "\uD835\uDD41" ,
4235 "\\bJ" : "\uD835\uDD41" ,
4236 "\\K" : "\uD835\uDD42" ,
4237 "\\bK" : "\uD835\uDD42" ,
4238 "\\L" : "\uD835\uDD43" ,
4239 "\\bL" : "\uD835\uDD43" ,
4240 "\\M" : "\uD835\uDD44" ,
4241 "\\bM" : "\uD835\uDD44" ,
4242 "\\N" : "\u2115" ,
4243 "\\bN" : "\u2115" ,
4244 "\\O" : "\uD835\uDD46" ,
4245 "\\bO" : "\uD835\uDD46" ,
4246 "\\P" : "\u2119" ,
4247 "\\bP" : "\u2119" ,
4248 "\\Q" : "\u211A" ,
4249 "\\bQ" : "\u211A" ,
4250 "\\R" : "\u211D" ,
4251 "\\bR" : "\u211D" ,
4252 "\\S" : "\uD835\uDD4A" ,
4253 "\\bS" : "\uD835\uDD4A" ,
4254 "\\T" : "\uD835\uDD4B" ,
4255 "\\bT" : "\uD835\uDD4B" ,
4256 "\\U" : "\uD835\uDD4C" ,
4257 "\\bU" : "\uD835\uDD4C" ,
4258 "\\V" : "\uD835\uDD4D" ,
4259 "\\bV" : "\uD835\uDD4D" ,
4260 "\\W" : "\uD835\uDD4E" ,
4261 "\\bW" : "\uD835\uDD4E" ,
4262 "\\X" : "\uD835\uDD4F" ,
4263 "\\bX" : "\uD835\uDD4F" ,
4264 "\\Y" : "\uD835\uDD50" ,
4265 "\\bY" : "\uD835\uDD50" ,
4266 "\\Z" : "\u2124" ,
4267 "\\bZ" : "\u2124" ,
4268     // Common abbreviations for \mathcal letters
4269 "\\cA" : "\uD835\uDC9C" ,
4270 "\\cB" : "\u212C" ,
4271 "\\cC" : "\uD835\uDC9E" ,
4272 "\\cD" : "\uD835\uDC9F" ,
4273 "\\cE" : "\u2130" ,
4274 "\\cF" : "\u2131" ,
4275 "\\cG" : "\uD835\uDCA2" ,
4276 "\\cH" : "\u210B" ,
4277 "\\cI" : "\u2110" ,
4278 "\\cJ" : "\uD835\uDCA5" ,
4279 "\\cK" : "\uD835\uDCA6" ,
4280 "\\cL" : "\u2112" ,
4281 "\\cM" : "\u2133" ,
4282 "\\cN" : "\uD835\uDCA9" ,
4283 "\\cO" : "\uD835\uDCAA" ,
4284 "\\OO" : "\uD835\uDCAA" ,
4285 "\\cP" : "\uD835\uDCAB" ,
4286 "\\cQ" : "\uD835\uDCAC" ,
4287 "\\cR" : "\u211B" ,
4288 "\\cS" : "\uD835\uDCAE" ,
4289 "\\cT" : "\uD835\uDCAF" ,
4290 "\\cU" : "\uD835\uDCB0" ,
4291 "\\cV" : "\uD835\uDCB1" ,
4292 "\\cW" : "\uD835\uDCB2" ,
4293 "\\cX" : "\uD835\uDCB3" ,
4294 "\\cY" : "\uD835\uDCB4" ,
4295 "\\cZ" : "\uD835\uDCB5" ,
4296     // Common operators
4297     "\\Pic" : "Pic" ,
4298     "\\Spec" : "Spec" ,
4299     "\\Proj" : "Proj" ,
4300     // Misc
4301 "\\eps" : "\u03f5" ,
4302 }
4303 ;
4304 var g_word_operators
4305 = {"\\arccos" : "arccos" ,
4306 "\\arcsin" : "arcsin" ,
4307 "\\arctan" : "arctan" ,
4308 "\\arg" : "arg" ,
4309 "\\cos" : "cos" ,
4310 "\\cosh" : "cosh" ,
4311 "\\cot" : "cot" ,
4312 "\\coth" : "coth" ,
4313 "\\csc" : "csc" ,
4314 "\\deg" : "deg" ,
4315 "\\det" : "det" ,
4316 "\\dim" : "dim" ,
4317 "\\exp" : "exp" ,
4318 "\\gcd" : "gcd" ,
4319 "\\hom" : "hom" ,
4320 "\\ker" : "ker" ,
4321 "\\lg" : "lg" ,
4322 "\\ln" : "ln" ,
4323 "\\log" : "log" ,
4324 "\\Pr" : "Pr" ,
4325 "\\sec" : "sec" ,
4326 "\\sin" : "sin" ,
4327 "\\sinh" : "sinh" ,
4328 "\\tan" : "tan" ,
4329 "\\tanh" : "tanh" ,
4330 }
4331 ;
4332 var g_big_word_operators
4333 = {"\\inf" : "inf" ,
4334 "\\injlim" : "inj lim" ,
4335 "\\lim" : "lim" ,
4336 "\\liminf" : "lim inf" ,
4337 "\\limsup" : "lum sup" ,
4338 "\\max" : "max" ,
4339 "\\min" : "min" ,
4340 "\\projlim" : "proj lim" ,
4341 "\\sup" : "sup" ,
4342 }
4343 ;
4344 var g_greek_letters
4345 = {"\\alpha" : "\u03b1" ,
4346 "\\beta" : "\u03b2" ,
4347 "\\chi" : "\u03c7" ,
4348 "\\delta" : "\u03b4" ,
4349 "\\Delta" : "\u0394" ,
4350 "\\digamma" : "\u03dd" ,
4351 "\\epsilon" : "\u03f5" ,
4352 "\\eta" : "\u03b7" ,
4353 "\\gamma" : "\u03b3" ,
4354 "\\Gamma" : "\u0393" ,
4355 "\\iota" : "\u03b9" ,
4356 "\\kappa" : "\u03ba" ,
4357 "\\lambda" : "\u03bb" ,
4358 "\\Lambda" : "\u039b" ,
4359 "\\mu" : "\u03bc" ,
4360 "\\nu" : "\u03bd" ,
4361 "\\omega" : "\u03c9" ,
4362 "\\Omega" : "\u03a9" ,
4363 "\\phi" : "\u03c6" ,
4364 "\\Phi" : "\u03a6" ,
4365 "\\pi" : "\u03c0" ,
4366 "\\Pi" : "\u03a0" ,
4367 "\\psi" : "\u03c8" ,
4368 "\\Psi" : "\u03a8" ,
4369 "\\rho" : "\u03c1" ,
4370 "\\sigma" : "\u03c3" ,
4371 "\\Sigma" : "\u03a3" ,
4372 "\\tau" : "\u03c4" ,
4373 "\\theta" : "\u03b8" ,
4374 "\\Theta" : "\u0398" ,
4375 "\\upsilon" : "\u03c5" ,
4376 "\\Upsilon" : "\u03d2" ,
4377 "\\varepsilon" : "\u03b5" ,
4378 "\\varkappa" : "\u03f0" ,
4379 "\\varphi" : "\u03d5" ,
4380 "\\varpi" : "\u03d6" ,
4381 "\\varrho" : "\u03f1" ,
4382 "\\varsigma" : "\u03c2" ,
4383 "\\vartheta" : "\u03d1" ,
4384 "\\xi" : "\u03be" ,
4385 "\\Xi" : "\u039e" ,
4386 "\\zeta" : "\u03b6" ,
4387 }
4388 ;
4389 function v_fraction_to_mathml (tokens ) {
4390  var v_numerator = v_piece_to_mathml (tokens ) ;
4391  var v_denominator = v_piece_to_mathml (tokens ) ;
4392  return result_element( "mfrac" ,0 , v_numerator , v_denominator ) ;
4393 }
4394 function v_binom_to_mathml (tokens ) {
4395  var v_top = v_piece_to_mathml (tokens ) ;
4396  var v_bottom = v_piece_to_mathml (tokens ) ;
4397  return result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , result_element( "mfrac" , 1
4398 , "linethickness" , "0" , v_top , v_bottom ) , result_element( "mo" ,0 , ")" ) ) ;
4399 }
4400 function v_sqrt_to_mathml (tokens ) {
4401  var v_index = v_optional_arg_to_mathml (tokens ) ;
4402  var v_object = v_piece_to_mathml (tokens ) ;
4403  if( ( v_index != null ) ) {
4404   return result_element( "mroot" ,0 , v_object , v_index ) ;
4405  }
4406  else {
4407   return result_element( "msqrt" ,0 , v_object ) ;
4408  }
4409 }
4410 function v_parenthesized_operator (tokens , v_word ) {
4411  var v_object = v_piece_to_mathml (tokens ) ;
4412  if( ( v_word != null ) ) {
4413   return result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , result_element( "mo" ,0 , v_word ) , v_object , result_element( "mo" ,0 , ")" ) ) ;
4414  }
4415  else {
4416   return result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , v_object , result_element( "mo" ,0 , ")" ) ) ;
4417  }
4418 }
4419 function v_operatorname_to_mathml (tokens ) {
4420  var v_result = result_element( "mo" ,0 , tokens.list[tokens.index] ) ;
4421  tokens.index++;
4422  return v_result ;
4423 }
4424 function v_displaystyle_to_mathml (tokens ) {
4425  var v_result = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4426 ) ;
4427  return result_element( "mstyle" , 2
4428 , "displaystyle" , "true" , "scriptlevel" , "0" , v_result ) ;
4429 }
4430 function v_displaymath_to_mathml (tokens ) {
4431  var v_result = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4432 ) ;
4433   v_finish_latex_block (tokens );
4434  return result_element( "mstyle" , 2
4435 , "displaystyle" , "true" , "scriptlevel" , "0" , v_result ) ;
4436 }
4437 function v_font_to_mathml (tokens , v_font_name ) {
4438  if( ( tokens.list[tokens.index] != "{" ) ) {
4439   var v_result = result_element( "mi" , 1
4440 , "mathvariant" , v_font_name , tokens.list[tokens.index] ) ;
4441   if( ( v_font_name == "normal" ) ) {
4442    result_set_attr(
4443 v_result , "fontstyle" , "normal" );
4444   }
4445   tokens.index++;
4446   return v_result ;
4447  }
4448  else {
4449   var v_result = v_piece_to_mathml (tokens ) ;
4450   result_set_attr(
4451 v_result , "mathvariant" , v_font_name );
4452   if( ( v_font_name == "normal" ) ) {
4453    result_set_attr(
4454 v_result , "fontstyle" , "normal" );
4455   }
4456   return v_result ;
4457  }
4458 }
4459 function v_old_font_to_mathml (tokens , v_font_name ) {
4460  return result_element( "mstyle" , 2
4461 , "mathvariant" , v_font_name , "fontstyle" , ( ( v_font_name == "normal" ) ? "normal" : null ) , v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4462 ) ) ;
4463 }
4464 function v_size_to_mathml (tokens , v_min_size , v_max_size ) {
4465  var v_result = v_piece_to_mathml (tokens ) ;
4466  result_set_attr(
4467 v_result , "minsize" , v_min_size );
4468  result_set_attr(
4469 v_result , "maxsize" , v_max_size );
4470  return v_result ;
4471 }
4472 function v_accent_to_mathml (tokens , v_char ) {
4473  return result_element( "mover" , 1
4474 , "accent" , "true" , v_piece_to_mathml (tokens ) , result_element( "mo" ,0 , v_char ) ) ;
4475 }
4476 function v_matrix_to_mathml (tokens , v_open_delim , v_close_delim ) {
4477  var v_mtable = v_matrix_to_mtable (tokens , result_element( "mtable" ,0) ) ;
4478  if( ( ( v_open_delim != null )  ||  ( v_close_delim != null ) ) ) {
4479   var v_mrow = result_element( "mrow" ,0) ;
4480   if( ( v_open_delim != null ) ) {
4481    result_element_append( v_mrow , result_element( "mo" ,0 , v_open_delim ) );
4482   }
4483   result_element_append( v_mrow , v_mtable );
4484   if( ( v_close_delim != null ) ) {
4485    result_element_append( v_mrow , result_element( "mo" ,0 , v_close_delim ) );
4486   }
4487   return v_mrow ;
4488  }
4489  else {
4490   return v_mtable ;
4491  }
4492 }
4493 function v_array_to_mathml (tokens ) {
4494  var v_mtable = result_element( "mtable" ,0) ;
4495  if( ( tokens.list[tokens.index] == "{" ) ) {
4496   tokens.index++;
4497   while( ( ( tokens.list[tokens.index] != null )  &&  ( tokens.list[tokens.index] != "}" ) ) ) {
4498    if( ( tokens.list[tokens.index] == "c" ) ) {
4499     result_append_attr(
4500 v_mtable , "columnalign" , "center " );
4501    }
4502    else if( ( tokens.list[tokens.index] == "l" ) ) {
4503     result_append_attr(
4504 v_mtable , "columnalign" , "left " );
4505    }
4506    else if( ( tokens.list[tokens.index] == "r" ) ) {
4507     result_append_attr(
4508 v_mtable , "columnalign" , "right " );
4509    }
4510    tokens.index++;
4511   }
4512   if( ( tokens.list[tokens.index] != null ) ) {
4513    tokens.index++;
4514   }
4515  }
4516  return v_matrix_to_mtable (tokens , v_mtable ) ;
4517 }
4518 function v_matrix_to_mtable (tokens , v_mtable ) {
4519  var v_mtr = result_element( "mtr" ,0) ;
4520  var v_mtd = result_element( "mtd" ,0) ;
4521  var v_token = tokens.list[tokens.index] ;
4522  result_element_append( v_mtable , v_mtr );
4523  result_element_append( v_mtr , v_mtd );
4524  while( ( ( v_token != null )  &&  ( v_token != "\\end" ) ) ) {
4525   if( ( v_token == "\\\\" ) ) {
4526     v_mtr = result_element( "mtr" ,0) ;
4527     v_mtd = result_element( "mtd" ,0) ;
4528    result_element_append( v_mtable , v_mtr );
4529    result_element_append( v_mtr , v_mtd );
4530    tokens.index++;
4531   }
4532   else if( ( v_token == "&" ) ) {
4533     v_mtd = result_element( "mtd" ,0) ;
4534    result_element_append( v_mtr , v_mtd );
4535    tokens.index++;
4536   }
4537   else {
4538    result_element_append( v_mtd , v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4539 ) );
4540   }
4541    v_token = tokens.list[tokens.index] ;
4542  }
4543   v_finish_latex_block (tokens );
4544  return v_mtable ;
4545 }
4546 function v_over_to_mathml (tokens , v_char ) {
4547  return result_element( "mover" ,0 , v_piece_to_mathml (tokens ) , result_element( "mo" ,0 , v_char ) ) ;
4548 }
4549 function v_under_to_mathml (tokens , v_char ) {
4550  return result_element( "munder" ,0 , v_piece_to_mathml (tokens ) , result_element( "mo" ,0 , v_char ) ) ;
4551 }
4552 function v_delimiter_to_mathml (tokens , v_end_command , v_min_size , v_max_size ) {
4553  var v_mrow = result_element( "mrow" ,0) ;
4554  result_element_append( v_mrow , result_element( "mo" , 2
4555 , "minsize" , v_min_size , "maxsize" , v_max_size , v_read_delimiter (tokens ) ) );
4556  result_element_append( v_mrow , v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4557 ) );
4558  if( ( tokens.list[tokens.index] != v_end_command ) ) {
4559   return v_mrow ;
4560  }
4561  tokens.index++;
4562  result_element_append( v_mrow , result_element( "mo" , 2
4563 , "minsize" , v_min_size , "maxsize" , v_max_size , v_read_delimiter (tokens ) ) );
4564  return v_mrow ;
4565 }
4566 function v_read_delimiter (tokens ) {
4567  var v_token = tokens.list[tokens.index] ;
4568  if( ( v_token == null ) ) {
4569   throw "unexpected eof" ;
4570  }
4571  else if( ( v_token == "." ) ) {
4572   tokens.index++;
4573   return "" ;
4574  }
4575  else if( ( v_token == "<" ) ) {
4576   tokens.index++;
4577   return "\u2329" ;
4578  }
4579  else if( ( v_token == ">" ) ) {
4580   tokens.index++;
4581   return "\u232a" ;
4582  }
4583  else if( ( v_token in g_punct_and_space
4584 ) ) {
4585   tokens.index++;
4586   return g_punct_and_space
4587 [ v_token ] ;
4588  }
4589  else if( ( v_token in g_left_delimiters
4590 ) ) {
4591   tokens.index++;
4592   return g_left_delimiters
4593 [ v_token ] ;
4594  }
4595  else if( ( v_token in g_right_delimiters
4596 ) ) {
4597   tokens.index++;
4598   return g_right_delimiters
4599 [ v_token ] ;
4600  }
4601  else if( ( v_token in g_operator_symbols
4602 ) ) {
4603   tokens.index++;
4604   return g_operator_symbols
4605 [ v_token ] ;
4606  }
4607  else {
4608   throw "invalid delimiter" ;
4609  }
4610 }
4611 function v_latex_block_to_mathml (tokens ) {
4612   v_cmd = tokens.list[tokens.index] ;
4613  if( ( v_cmd in g_tex_environments
4614 ) ) {
4615   tokens.index++;
4616   return g_tex_environments
4617 [ v_cmd ] (tokens ) ;
4618  }
4619  else {
4620   throw "unknown command" ;
4621  }
4622 }
4623 function v_finish_latex_block (tokens ) {
4624  if( ( tokens.list[tokens.index] == null ) ) {
4625   throw "unexpected eof" ;
4626  }
4627  tokens.index++;
4628  tokens.index++;
4629 }
4630 function v_combining_to_mathml (tokens , v_char ) {
4631  var v_base = tokens.list[tokens.index] ;
4632  tokens.index++;
4633  return result_element( "mo" ,0 , v_base , v_char ) ;
4634 }
4635 var g_char_escape_codes
4636 = {"93" : "#" ,
4637 }
4638 ;
4639 function v_char_escape_to_mathml (tokens ) {
4640  var v_result = null ;
4641  if( ( tokens.list[tokens.index] in g_char_escape_codes
4642 ) ) {
4643    v_result = result_element( "mtext" ,0 , g_char_escape_codes
4644 [ tokens.list[tokens.index] ] ) ;
4645  }
4646  else {
4647    v_result = result_element( "merror" ,0 , "\\char" , tokens.list[tokens.index] ) ;
4648  }
4649  tokens.index++;
4650  return v_result ;
4651 }
4652 function v_text_to_mathml (tokens ) {
4653  if( ( tokens.list[tokens.index] != "{" ) ) {
4654   var v_result = result_element( "mtext" ,0 , tokens.list[tokens.index] ) ;
4655   tokens.index++;
4656   return v_result ;
4657  }
4658  tokens.index++;
4659  var v_result = null ;
4660  var v_mrow = null ;
4661  var v_node = null ;
4662  while( ( tokens.list[tokens.index] != null ) ) {
4663   if( ( tokens.list[tokens.index] == "}" ) ) {
4664    tokens.index++;
4665    return v_result ;
4666   }
4667   else if( ( tokens.list[tokens.index] == "$" ) ) {
4668    tokens.index++;
4669     v_node = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4670 ) ;
4671    tokens.index++;
4672   }
4673   else {
4674     v_node = result_element( "mtext" ,0 , tokens.list[tokens.index] ) ;
4675    tokens.index++;
4676   }
4677   if( ( v_mrow != null ) ) {
4678    result_element_append( v_mrow , v_node );
4679   }
4680   else if( ( v_result != null ) ) {
4681     v_mrow = result_element( "mrow" ,0 , v_result , v_node ) ;
4682     v_result = v_mrow ;
4683   }
4684   else {
4685     v_result = v_node ;
4686   }
4687  }
4688  return v_result ;
4689 }
4690 var g_tex_commands
4691 = {
4692 "\\frac" : v_fraction_to_mathml ,
4693 "\\dfrac" : v_fraction_to_mathml ,
4694 "\\tfrac" : v_fraction_to_mathml ,
4695 "\\binom" : v_binom_to_mathml ,
4696 "\\sqrt" : v_sqrt_to_mathml ,
4697 "\\operatorname" : v_operatorname_to_mathml ,
4698 "\\displaystyle" : v_displaystyle_to_mathml ,
4699 "\\pod" : function(tokens ) {return v_parenthesized_operator (tokens , null ) ;} ,
4700 "\\pmod" : function(tokens ) {return v_parenthesized_operator (tokens , "mod" ) ;} ,
4701 "\\boldsymbol" : function(tokens ) {return v_font_to_mathml (tokens , "bold" ) ;} ,
4702 "\\bold" : function(tokens ) {return v_font_to_mathml (tokens , "bold" ) ;} ,
4703 "\\Bbb" : function(tokens ) {return v_font_to_mathml (tokens , "double-struck" ) ;} ,
4704 "\\mathbb" : function(tokens ) {return v_font_to_mathml (tokens , "double-struck" ) ;} ,
4705 "\\mathbbmss" : function(tokens ) {return v_font_to_mathml (tokens , "double-struck" ) ;} ,
4706 "\\mathbf" : function(tokens ) {return v_font_to_mathml (tokens , "bold" ) ;} ,
4707 "\\mathop" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4708 "\\mathopen" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4709 "\\mathclose" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4710 "\\mathrm" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4711 "\\mathfrak" : function(tokens ) {return v_font_to_mathml (tokens , "fraktur" ) ;} ,
4712 "\\germ" : function(tokens ) {return v_font_to_mathml (tokens , "fraktur" ) ;} ,
4713 "\\mathit" : function(tokens ) {return v_font_to_mathml (tokens , "italic" ) ;} ,
4714 "\\mathscr" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4715 "\\scr" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4716 "\\mathcal" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4717 "\\mathsf" : function(tokens ) {return v_font_to_mathml (tokens , "sans-serif" ) ;} ,
4718 "\\mathtt" : function(tokens ) {return v_font_to_mathml (tokens , "monospace" ) ;} ,
4719 "\\EuScript" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4720 "\\bf" : function(tokens ) {return v_old_font_to_mathml (tokens , "bold" ) ;} ,
4721 "\\rm" : function(tokens ) {return v_old_font_to_mathml (tokens , "normal" ) ;} ,
4722 "\\roman" : function(tokens ) {return v_old_font_to_mathml (tokens , "normal" ) ;} ,
4723 "\\tag" : function(tokens ) {return v_old_font_to_mathml (tokens , "bold" ) ;} ,
4724 "\\big" : function(tokens ) {return v_size_to_mathml (tokens , "2" , "2" ) ;} ,
4725 "\\Big" : function(tokens ) {return v_size_to_mathml (tokens , "3" , "3" ) ;} ,
4726 "\\bigg" : function(tokens ) {return v_size_to_mathml (tokens , "4" , "4" ) ;} ,
4727 "\\Bigg" : function(tokens ) {return v_size_to_mathml (tokens , "5" , "5" ) ;} ,
4728 "\\acute" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0301" ) ;} ,
4729 "\\grave" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0300" ) ;} ,
4730 "\\tilde" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0303" ) ;} ,
4731 "\\bar" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0304" ) ;} ,
4732 "\\breve" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0306" ) ;} ,
4733 "\\check" : function(tokens ) {return v_accent_to_mathml (tokens , "\u030c" ) ;} ,
4734 "\\hat" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0302" ) ;} ,
4735 "\\vec" : function(tokens ) {return v_accent_to_mathml (tokens , "\u20d7" ) ;} ,
4736 "\\dot" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0307" ) ;} ,
4737 "\\ddot" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0308" ) ;} ,
4738 "\\dddot" : function(tokens ) {return v_accent_to_mathml (tokens , "\u20db" ) ;} ,
4739 "\\underbrace" : function(tokens ) {return v_under_to_mathml (tokens , "\ufe38" ) ;} ,
4740 "\\overbrace" : function(tokens ) {return v_over_to_mathml (tokens , "\ufe37" ) ;} ,
4741 "\\underline" : function(tokens ) {return v_under_to_mathml (tokens , "\u0332" ) ;} ,
4742 "\\overline" : function(tokens ) {return v_over_to_mathml (tokens , "\u00af" ) ;} ,
4743 "\\widetilde" : function(tokens ) {return v_over_to_mathml (tokens , "\u0303" ) ;} ,
4744 "\\widehat" : function(tokens ) {return v_over_to_mathml (tokens , "\u0302" ) ;} ,
4745 "\\not" : function(tokens ) {return v_combining_to_mathml (tokens , "\u0338" ) ;} ,
4746 "\\left" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\right" , "1" , null ) ;} ,
4747 "\\bigl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\bigr" , "2" , "2" ) ;} ,
4748 "\\Bigl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\Bigr" , "3" , "3" ) ;} ,
4749 "\\biggl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\biggr" , "4" , "4" ) ;} ,
4750 "\\Biggl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\Biggr" , "5" , "5" ) ;} ,
4751 "\\char" : v_char_escape_to_mathml ,
4752 "\\!" : function(tokens ) {return null ;} ,
4753 "\\text" : v_text_to_mathml ,
4754 "\\textnormal" : v_text_to_mathml ,
4755 "\\textrm" : v_text_to_mathml ,
4756 "\\textsl" : v_text_to_mathml ,
4757 "\\textit" : v_text_to_mathml ,
4758 "\\texttt" : v_text_to_mathml ,
4759 "\\textbf" : v_text_to_mathml ,
4760 "\\hbox" : v_text_to_mathml ,
4761 "\\mbox" : v_text_to_mathml ,
4762 "\\begin" : v_latex_block_to_mathml ,
4763 }
4764 ;
4765 var g_tex_environments
4766 = {"smallmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "(" , ")" ) ;} ,
4767 "pmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "(" , ")" ) ;} ,
4768 "bmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "[" , "]" ) ;} ,
4769 "Bmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "{" , "}" ) ;} ,
4770 "vmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "|" , "|" ) ;} ,
4771 "Vmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "\u2016" , "\u2016" ) ;} ,
4772 "cases" : function(tokens ) {return v_matrix_to_mathml (tokens , "{" , null ) ;} ,
4773 "array" : v_array_to_mathml ,
4774 "displaymath" : v_displaymath_to_mathml ,
4775 }
4776 ;
4777 var g_limit_commands
4778 = {"\\bigcap" : "\u22c2" ,
4779 "\\bigcup" : "\u22c3" ,
4780 "\\bigodot" : "\u2a00" ,
4781 "\\bigoplus" : "\u2a01" ,
4782 "\\bigotimes" : "\u2a02" ,
4783 "\\bigsqcup" : "\u2a06" ,
4784 "\\biguplus" : "\u2a04" ,
4785 "\\bigvee" : "\u22c1" ,
4786 "\\bigwedge" : "\u22c0" ,
4787 "\\coprod" : "\u2210" ,
4788 "\\prod" : "\u220f" ,
4789 "\\sum" : "\u2211" ,
4790 "\\inf" : "inf" ,
4791 "\\injlim" : "inj lim" ,
4792 "\\lim" : "lim" ,
4793 "\\liminf" : "lim inf" ,
4794 "\\limsup" : "lum sup" ,
4795 "\\max" : "max" ,
4796 "\\min" : "min" ,
4797 "\\projlim" : "proj lim" ,
4798 "\\sup" : "sup" ,
4799 "\\underbrace" : null ,
4800 "\\overbrace" : null ,
4801 "\\underline" : null ,
4802 "\\overline" : null ,
4803 }
4804 ;
4805 function v_piece_to_mathml (tokens ) {
4806  var v_token = tokens.list[tokens.index] ;
4807  var v_result = null ;
4808  if( ( v_token == "{" ) ) {
4809   tokens.index++;
4810    v_result = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4811 ) ;
4812   if( ( tokens.list[tokens.index] == "}" ) ) {
4813    tokens.index++;
4814   }
4815  }
4816  else if( ( v_token in g_relation_symbols
4817 ) ) {
4818    v_result = result_element( "mo" ,0 , g_relation_symbols
4819 [ v_token ] ) ;
4820   tokens.index++;
4821  }
4822  else if( ( v_token in g_operator_symbols
4823 ) ) {
4824    v_result = result_element( "mo" ,0 , g_operator_symbols
4825 [ v_token ] ) ;
4826   tokens.index++;
4827  }
4828  else if( ( v_token in g_left_delimiters
4829 ) ) {
4830    v_result = result_element( "mo" ,0 , g_left_delimiters
4831 [ v_token ] ) ;
4832   tokens.index++;
4833  }
4834  else if( ( v_token in g_right_delimiters
4835 ) ) {
4836    v_result = result_element( "mo" ,0 , g_right_delimiters
4837 [ v_token ] ) ;
4838   tokens.index++;
4839  }
4840  else if( ( v_token in g_word_operators
4841 ) ) {
4842    v_result = result_element( "mi" , 1
4843 , "mathvariant" , "normal" , g_word_operators
4844 [ v_token ] ) ;
4845   tokens.index++;
4846  }
4847  else if( ( v_token in g_greek_letters
4848 ) ) {
4849    v_result = result_element( "mi" , 1
4850 , "fontstyle" , "normal" , g_greek_letters
4851 [ v_token ] ) ;
4852   tokens.index++;
4853  }
4854  else if( ( v_token in g_named_identifiers
4855 ) ) {
4856    v_result = result_element( "mi" ,0 , g_named_identifiers
4857 [ v_token ] ) ;
4858   tokens.index++;
4859  }
4860  else if( ( v_token in g_punct_and_space
4861 ) ) {
4862    v_result = result_element( "mtext" ,0 , g_punct_and_space
4863 [ v_token ] ) ;
4864   tokens.index++;
4865  }
4866  else if( ( v_token in g_tex_commands
4867 ) ) {
4868   tokens.index++;
4869    v_result = g_tex_commands
4870 [ v_token ] (tokens ) ;
4871  }
4872  else {
4873    v_result = result_element( "mn" ,0 , v_token ) ;
4874   tokens.index++;
4875  }
4876  return v_result ;
4877 }
4878 function v_subexpr_to_mathml (tokens ) {
4879  var v_result = null ;
4880  var v_mmultiscripts = null ;
4881  var v_mprescripts = null ;
4882  if( ( ( tokens.list[tokens.length<=tokens.index+ 0 ? tokens.length-1 : tokens.index+ 0 ]
4883 == "{" )  &&  ( tokens.list[tokens.length<=tokens.index+ 1 ? tokens.length-1 : tokens.index+ 1 ]
4884 == "}" )  &&  ( ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4885 == "_" )  ||  ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4886 == "^" ) ) ) ) {
4887    v_mmultiscripts = result_element( "mmultiscripts" ,0) ;
4888    v_mprescripts = result_element( "mprescripts" ,0) ;
4889   result_element_append( v_mmultiscripts , v_mprescripts );
4890   while( ( ( tokens.list[tokens.length<=tokens.index+ 0 ? tokens.length-1 : tokens.index+ 0 ]
4891 == "{" )  &&  ( tokens.list[tokens.length<=tokens.index+ 1 ? tokens.length-1 : tokens.index+ 1 ]
4892 == "}" )  &&  ( ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4893 == "_" )  ||  ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4894 == "^" ) ) ) ) {
4895    var v_subscript = null ;
4896    var v_superscript = null ;
4897    tokens.index++;
4898    tokens.index++;
4899    if( ( tokens.list[tokens.index] == "_" ) ) {
4900     tokens.index++;
4901      v_subscript = v_piece_to_mathml (tokens ) ;
4902    }
4903    else if( ( tokens.list[tokens.index] == "^" ) ) {
4904     tokens.index++;
4905      v_superscript = v_piece_to_mathml (tokens ) ;
4906    }
4907    if( ( tokens.list[tokens.index] == "_" ) ) {
4908     tokens.index++;
4909      v_subscript = v_piece_to_mathml (tokens ) ;
4910    }
4911    else if( ( tokens.list[tokens.index] == "^" ) ) {
4912     tokens.index++;
4913      v_superscript = v_piece_to_mathml (tokens ) ;
4914    }
4915    result_element_append( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) );
4916    result_element_append( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) );
4917   }
4918  }
4919  var v_limit_style = ( tokens.list[tokens.index] in g_limit_commands
4920 ) ;
4921  if( ( tokens.list[tokens.index] == null ) ) {
4922   if( ( v_mmultiscripts != null ) ) {
4923    result_element_prepend( v_mmultiscripts , result_element( "mrow" ,0) , v_mprescripts );
4924    return v_mmultiscripts ;
4925   }
4926   else {
4927    return result_element( "mrow" ,0) ;
4928   }
4929  }
4930  else if( ( tokens.list[tokens.index] in g_left_delimiters
4931 ) ) {
4932    v_result = v_heuristic_subexpression (tokens ) ;
4933  }
4934  else {
4935    v_result = v_piece_to_mathml (tokens ) ;
4936  }
4937  var v_base = v_result ;
4938  var v_subscript = null ;
4939  var v_superscript = null ;
4940  if( ( tokens.list[tokens.index] == "_" ) ) {
4941   tokens.index++;
4942    v_subscript = v_piece_to_mathml (tokens ) ;
4943  }
4944  else if( ( tokens.list[tokens.index] == "^" ) ) {
4945   tokens.index++;
4946    v_superscript = v_piece_to_mathml (tokens ) ;
4947  }
4948  if( ( tokens.list[tokens.index] == "_" ) ) {
4949   tokens.index++;
4950    v_subscript = v_piece_to_mathml (tokens ) ;
4951  }
4952  else if( ( tokens.list[tokens.index] == "^" ) ) {
4953   tokens.index++;
4954    v_superscript = v_piece_to_mathml (tokens ) ;
4955  }
4956  if( ( v_mmultiscripts != null ) ) {
4957   result_element_prepend( v_mmultiscripts , v_base , v_mprescripts );
4958   result_element_prepend( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) , v_mprescripts );
4959   result_element_prepend( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) , v_mprescripts );
4960  }
4961  while( ( ( tokens.list[tokens.length<=tokens.index+ 0 ? tokens.length-1 : tokens.index+ 0 ]
4962 == "{" )  &&  ( tokens.list[tokens.length<=tokens.index+ 1 ? tokens.length-1 : tokens.index+ 1 ]
4963 == "}" )  &&  ( ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4964 == "_" )  ||  ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4965 == "^" ) ) ) ) {
4966   if( ( v_mmultiscripts == null ) ) {
4967     v_mmultiscripts = result_element( "mmultiscripts" ,0 , v_base ) ;
4968     v_mprescripts = null ;
4969    if( ( ( v_superscript != null )  ||  ( v_subscript != null ) ) ) {
4970     result_element_append( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) );
4971     result_element_append( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) );
4972    }
4973   }
4974   var v_subscript = null ;
4975   var v_superscript = null ;
4976   tokens.index++;
4977   tokens.index++;
4978   if( ( tokens.list[tokens.index] == "_" ) ) {
4979    tokens.index++;
4980     v_subscript = v_piece_to_mathml (tokens ) ;
4981   }
4982   else if( ( tokens.list[tokens.index] == "^" ) ) {
4983    tokens.index++;
4984     v_superscript = v_piece_to_mathml (tokens ) ;
4985   }
4986   if( ( tokens.list[tokens.index] == "_" ) ) {
4987    tokens.index++;
4988     v_subscript = v_piece_to_mathml (tokens ) ;
4989   }
4990   else if( ( tokens.list[tokens.index] == "^" ) ) {
4991    tokens.index++;
4992     v_superscript = v_piece_to_mathml (tokens ) ;
4993   }
4994   result_element_prepend( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) , v_mprescripts );
4995   result_element_prepend( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) , v_mprescripts );
4996  }
4997  if( ( v_mmultiscripts != null ) ) {
4998    v_result = v_mmultiscripts ;
4999  }
5000  else if( ( ( v_subscript != null )  &&  ( v_superscript != null ) ) ) {
5001    v_result = result_element( ( v_limit_style ? "munderover" : "msubsup" ) ,0 , v_base , v_subscript , v_superscript ) ;
5002  }
5003  else if( ( v_subscript != null ) ) {
5004    v_result = result_element( ( v_limit_style ? "munder" : "msub" ) ,0 , v_base , v_subscript ) ;
5005  }
5006  else if( ( v_superscript != null ) ) {
5007    v_result = result_element( ( v_limit_style ? "mover" : "msup" ) ,0 , v_base , v_superscript ) ;
5008  }
5009  return v_result ;
5010 }
5011 function v_subexpr_chain_to_mathml (tokens , v_stop_tokens ) {
5012  var v_result = null ;
5013  var v_mrow = null ;
5014  var v_mfrac = null ;
5015  var v_wrapped_result = null ;
5016  while( ( ( tokens.list[tokens.index] != null )  &&  !( ( tokens.list[tokens.index] in v_stop_tokens ) ) ) ) {
5017   if( ( tokens.list[tokens.index] == "\\over" ) ) {
5018    tokens.index++;
5019     v_mfrac = result_element( "mfrac" ,0 , v_result ) ;
5020     v_wrapped_result = v_mfrac ;
5021     v_mrow = null ;
5022     v_result = null ;
5023   }
5024   else if( ( tokens.list[tokens.index] == "\\choose" ) ) {
5025    tokens.index++;
5026     v_mfrac = result_element( "mfrac" , 1
5027 , "linethickness" , "0" , v_result ) ;
5028     v_wrapped_result = result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , v_mfrac , result_element( "mo" ,0 , ")" ) ) ;
5029     v_mrow = null ;
5030     v_result = null ;
5031   }
5032   else {
5033    var v_node = v_collect_precedence_group (tokens , g_relations_precedence_group
5034 , v_stop_tokens , function(tokens , v_stop_tokens ) {return v_collect_precedence_group (tokens , g_addition_precedence_group
5035 , v_stop_tokens , function(tokens , v_stop_tokens ) {return v_collect_precedence_group (tokens , g_multiplication_precedence_group
5036 , v_stop_tokens , v_collect_invisible_group ) ;} ) ;} ) ;
5037    if( ( v_mrow != null ) ) {
5038     result_element_append( v_mrow , v_node );
5039    }
5040    else if( ( v_result != null ) ) {
5041      v_mrow = result_element( "mrow" ,0 , v_result , v_node ) ;
5042      v_result = v_mrow ;
5043    }
5044    else {
5045      v_result = v_node ;
5046    }
5047   }
5048  }
5049  if( ( v_mfrac != null ) ) {
5050   result_element_append( v_mfrac , v_result );
5051   return v_wrapped_result ;
5052  }
5053  else {
5054   return v_result ;
5055  }
5056 }
5057 var g_optional_arg_stop_tokens
5058 = {"&" : null ,
5059 "\\\\" : null ,
5060 "}" : null ,
5061 "$" : null ,
5062 "\\end" : null ,
5063 "\\right" : null ,
5064 "\\bigr" : null ,
5065 "\\Bigr" : null ,
5066 "\\biggr" : null ,
5067 "\\Biggr" : null ,
5068 "\\choose" : null ,
5069 "\\over" : null ,
5070 "]" : null ,
5071 }
5072 ;
5073 function v_optional_arg_to_mathml (tokens ) {
5074  if( ( tokens.list[tokens.index] != "[" ) ) {
5075   return null ;
5076  }
5077  tokens.index++;
5078  var v_result = v_subexpr_chain_to_mathml (tokens , g_optional_arg_stop_tokens
5079 ) ;
5080  if( ( tokens.list[tokens.index] == "]" ) ) {
5081   tokens.index++;
5082  }
5083  return v_result ;
5084 }
5085 var g_hard_stop_tokens
5086 = {"&" : null ,
5087 "\\\\" : null ,
5088 "}" : null ,
5089 "$" : null ,
5090 "\\end" : null ,
5091 "\\right" : null ,
5092 "\\bigr" : null ,
5093 "\\Bigr" : null ,
5094 "\\biggr" : null ,
5095 "\\Biggr" : null ,
5096 "\\choose" : null ,
5097 "\\over" : null ,
5098 }
5099 ;
5100 var g_right_delimiter_stop_tokens
5101 = {"&" : null ,
5102 "\\\\" : null ,
5103 "}" : null ,
5104 "$" : null ,
5105 "\\end" : null ,
5106 "\\right" : null ,
5107 "\\bigr" : null ,
5108 "\\Bigr" : null ,
5109 "\\biggr" : null ,
5110 "\\Biggr" : null ,
5111 "\\choose" : null ,
5112 "\\over" : null ,
5113 ")" : ")" ,
5114 "]" : "]" ,
5115 "\\}" : "}" ,
5116 "\\rbrace" : "}" ,
5117 "\\rgroup" : ")" ,
5118 "\\rvert" : "|" ,
5119 "\\rVert" : "\u2016" ,
5120 "\\rceil" : "\u2309" ,
5121 "\\rfloor" : "\u230b" ,
5122 "\\rmoustache" : "\u23b1" ,
5123 "\\rangle" : "\u232a" ,
5124 }
5125 ;
5126 function v_heuristic_subexpression (tokens ) {
5127  var v_result = result_element( "mrow" ,0) ;
5128  result_element_append( v_result , v_piece_to_mathml (tokens ) );
5129  result_element_append( v_result , v_subexpr_chain_to_mathml (tokens , g_right_delimiter_stop_tokens
5130 ) );
5131  if( ( ( tokens.list[tokens.index] != null )  &&  !( ( tokens.list[tokens.index] in g_hard_stop_tokens
5132 ) ) ) ) {
5133   result_element_append( v_result , v_piece_to_mathml (tokens ) );
5134  }
5135  return v_result ;
5136 }
5137 var g_relations_precedence_group
5138 = g_relation_symbols
5139 ;
5140 var g_addition_precedence_group
5141 = {"+" : null ,
5142 "-" : null ,
5143 "\\oplus" : null ,
5144 }
5145 ;
5146 var g_multiplication_precedence_group
5147 = {"*" : null ,
5148 "\\times" : null ,
5149 "\\cdot" : null ,
5150 "/" : null ,
5151 }
5152 ;
5153 function v_collect_precedence_group (tokens , v_operators , v_stop_tokens , v_reader ) {
5154  var v_result = v_reader (tokens , v_stop_tokens ) ;
5155  var v_mrow = null ;
5156  while( ( ( tokens.list[tokens.index] != null )  &&  !( ( tokens.list[tokens.index] in v_stop_tokens ) )  &&  ( tokens.list[tokens.index] in v_operators ) ) ) {
5157   if( ( v_mrow == null ) ) {
5158     v_mrow = result_element( "mrow" ,0 , v_result ) ;
5159     v_result = v_mrow ;
5160   }
5161   result_element_append( v_mrow , v_piece_to_mathml (tokens ) );
5162   if( ( ( tokens.list[tokens.index] != null )  &&  ( tokens.list[tokens.index] in v_stop_tokens ) ) ) {
5163    return v_result ;
5164   }
5165   else {
5166    result_element_append( v_mrow , v_reader (tokens , v_stop_tokens ) );
5167   }
5168  }
5169  return v_result ;
5170 }
5171 function v_collect_invisible_group (tokens , v_stop_tokens ) {
5172  var v_result = v_subexpr_to_mathml (tokens ) ;
5173  var v_mrow = null ;
5174  while( ( ( tokens.list[tokens.index] != null )  &&  !( ( tokens.list[tokens.index] in v_stop_tokens ) )  &&  ( ( tokens.list[tokens.index] in g_named_identifiers
5175 )  ||  ( tokens.list[tokens.index] in g_left_delimiters
5176 ) ) ) ) {
5177   if( ( v_mrow == null ) ) {
5178     v_mrow = result_element( "mrow" ,0 , v_result ) ;
5179     v_result = v_mrow ;
5180   }
5181   result_element_append( v_mrow , result_element( "mo" ,0 , "\u2062" ) );
5182   if( ( ( tokens.list[tokens.index] != null )  &&  ( tokens.list[tokens.index] in v_stop_tokens ) ) ) {
5183    return v_result ;
5184   }
5185   else {
5186    result_element_append( v_mrow , v_subexpr_to_mathml (tokens ) );
5187   }
5188  }
5189  return v_result ;
5190 }
5191
5192
5193 var/*const*/ tokenize_re = /(\\begin|\\operatorname|\\mathrm|\\mathop|\\end)\s*\{\s*([A-Z a-z]+)\s*\}|(\\[a-zA-Z]+|\\[\\#\{\},:;!])|(\s+)|([0-9\.]+)|([\$!"#%&'()*+,-.\/:;<=>?\[\]^_`\{\|\}~])|([a-zA-Z])/g;
5194
5195 var/*const*/ tokenize_text_re = /[\${}\\]|\\[a-zA-Z]+|[^{}\$]+/g;
5196
5197 var/*const*/ tokenize_text_commands = {
5198   '\\textrm': 1,
5199   '\\textsl': 1,
5200   '\\textit': 1,
5201   '\\texttt': 1,
5202   '\\textbf': 1,
5203   '\\textnormal': 1,
5204   '\\text': 1,
5205   '\\hbox': 1,
5206   '\\mbox': 1
5207 };
5208
5209 function tokenize_latex_math(input)
5210 {
5211   var result = new Array();
5212   var in_text_mode = 0;
5213   var brace_level = [];
5214   var pos = 0;
5215
5216   if(input.charAt(0) == '$' && 
5217      input.charAt(input.length-1) == '$')
5218     input = input.slice(1, input.length-1);
5219
5220   while(1) {
5221     if(!in_text_mode) {
5222       tokenize_re.lastIndex = pos;
5223       var m = tokenize_re.exec(input);
5224       pos = tokenize_re.lastIndex;
5225
5226       if(m == null) {
5227         return result;
5228       } else if(m[1] != null) {
5229         result.push(m[1], m[2]);
5230       } else if(m[3] == '\\sp') {
5231         result.push('^');
5232       } else if(m[3] == '\\sb') {
5233         result.push('_');
5234       } else {
5235         if(m[0] == '$') {
5236           in_text_mode = 1;
5237         } else if(m[4] != null) {
5238           continue;
5239         } else if(m[3] != null && m[3] in tokenize_text_commands) {
5240           in_text_mode = 2;
5241           brace_level.push(0);
5242         } 
5243
5244         result.push(m[0]);
5245       }
5246     } else {
5247       tokenize_text_re.lastIndex = pos;
5248       var m = tokenize_text_re.exec(input);
5249       pos = tokenize_text_re.lastIndex;
5250       
5251       if(m == null) {
5252         return result;
5253       } else if(m[0] == '$') {
5254         in_text_mode = 0;
5255       } else if(m[0] == '{') {
5256         brace_level[brace_level.length-1]++;
5257       } else if(m[0] == '}') {
5258         if(--brace_level[brace_level.length-1] <= 0) {
5259           in_text_mode = 0;
5260           brace_level.pop();
5261         }
5262       }
5263       result.push(m[0]);
5264     }
5265   }
5266 }
5267
5268 /*
5269 function post_process_mathml(event)
5270 {
5271   var url = GM_getValue('click-post-url', null);
5272   if(url == null)
5273     return;
5274
5275   var ser = new XMLSerializer();
5276   var xhr = GM_xmlhttpRequest({ 
5277     method: 'POST',
5278     url: url,
5279     headers: { 'Content-Type': 'text/xml; charset=utf-8',
5280                'Content-Location': document.location },
5281     data: ser.serializeToString(event.currentTarget),
5282     onerror: function(details) {
5283       alert("There was an error processing the request. " +
5284             "HTTP status code " + details.status + ' ' + details.statusText);
5285     },
5286     onload: function(details) {
5287       window.status = "Successfully posted MathML.  Status: " 
5288             + details.status + ' ' + details.statusText;
5289     }});
5290
5291   window.status = "Posting MathML to " + url + "...";
5292 }
5293 */
5294
5295 function patch_img(node)
5296 {
5297
5298     if(node.currentTarget)
5299     node = node.currentTarget;
5300
5301   var alt = node.getAttribute('alt');
5302
5303   if(alt == null || 
5304      /^\\includegraphics|^\$\\displaystyle \\xymatrix/.test(alt))
5305     return;
5306
5307   var latex_string = null;
5308   
5309   
5310
5311   
5312   if((node.parentNode.tagName == 'DIV' && 
5313       node.parentNode.getAttribute('CLASS') == 'mathdisplay')
5314      || (node.parentNode.tagName == 'SPAN' &&
5315          node.parentNode.getAttribute('CLASS') == 'MATH'))
5316   {
5317     var parent = node.parentNode;
5318     var previous = parent.previousSibling;
5319     var/*const*/ non_whitespace = /[^\s]/;
5320
5321         if(previous &&
5322        previous.nodeType == node.TEXT_NODE &&
5323        !non_whitespace.test(previous.data))
5324       previous = previous.previousSibling;
5325
5326         if(previous &&
5327        previous.nodeType == node.ELEMENT_NODE &&
5328        previous.tagName == 'P' &&
5329        previous.lastChild) 
5330     {
5331       previous = previous.lastChild;
5332       if(previous &&
5333          previous.nodeType == node.TEXT_NODE &&
5334          !non_whitespace.test(previous.data))
5335         previous = previous.previousSibling;
5336     }
5337
5338         if(previous &&
5339        previous.nodeType == node.COMMENT_NODE) {
5340       latex_string = previous.data.replace(/^\s*MATH\s*/, '')
5341                                   .replace(/\s+$/, '');
5342     }
5343   }
5344
5345
5346   if(!latex_string && /^\$.+\$$/.test(alt)
5347      && !(/\.{3} \.{3}/.test(alt)))
5348   {
5349     latex_string = alt;
5350   }
5351
5352   if(latex_string == null)
5353     return;
5354
5355   
5356   tokens = new Object();
5357   tokens.list = tokenize_latex_math(latex_string);
5358   tokens.list.push(null);
5359   tokens.index = 0;
5360
5361   var mathml = null;
5362   try {
5363     var mrow = v_subexpr_chain_to_mathml(tokens, {});
5364     fix_mathvariant(mrow, null);
5365
5366     mathml = document.createElementNS(mmlns, 'math');
5367     mathml.setAttribute("latex", latex_string);
5368     mathml.setAttribute("mathvariant", "normal");
5369     mathml.appendChild(mrow);
5370
5371     mathml.addEventListener("click", post_process_mathml, false);
5372
5373   } catch(e) {
5374     GM_log("Display LaTeX failed with error " + e + " on " + latex_string);
5375   }
5376
5377   
5378   if(mathml == null)
5379     return;
5380
5381   node.parentNode.replaceChild(mathml, node);
5382 }
5383
5384
5385 function patch_text(node0) 
5386 {
5387   var text = node0.nodeValue;
5388   var results = /\$[^$]+\$|\[tex\](.+?)\[\/tex\]/.exec(text);
5389
5390   if(results) {
5391     var latex_string = (results[1] == null ? results[0] : '$'+results[1]+'$');
5392
5393     
5394   tokens = new Object();
5395   tokens.list = tokenize_latex_math(latex_string);
5396   tokens.list.push(null);
5397   tokens.index = 0;
5398
5399   var mathml = null;
5400   try {
5401     var mrow = v_subexpr_chain_to_mathml(tokens, {});
5402     fix_mathvariant(mrow, null);
5403
5404     mathml = document.createElementNS(mmlns, 'math');
5405     mathml.setAttribute("latex", latex_string);
5406     mathml.setAttribute("mathvariant", "normal");
5407     mathml.appendChild(mrow);
5408
5409     mathml.addEventListener("click", post_process_mathml, false);
5410
5411   } catch(e) {
5412     GM_log("Display LaTeX failed with error " + e + " on " + latex_string);
5413   }
5414
5415
5416     if(mathml == null)
5417       return;
5418
5419     var node2 = node0.splitText(results.index);
5420     node2.deleteData(0, results[0].length);
5421     
5422     node2.parentNode.insertBefore(mathml, node2);
5423
5424
5425     patch_text(node2);
5426   }
5427 }
5428
5429
5430
5431 function patch_element(node)
5432 {
5433   if(node.nodeType == node.TEXT_NODE)
5434     patch_text(node);
5435   else if(node.nodeType == node.ELEMENT_NODE) {if(node.tagName == 'TEXTAREA' || node.tagName == 'textarea' || 
5436        node.tagName == 'INPUT' || node.tagName == 'input' || 
5437        node.tagName == 'SCRIPT' || node.tagName == 'script')
5438       return;
5439
5440
5441     if(do_patch_images && (node.tagName == 'IMG' || node.tagName == 'img')) {
5442       if(!delayed_patch)
5443         patch_img(node);
5444       else
5445         node.addEventListener("click", patch_img, false);
5446
5447       return;
5448     }
5449
5450     var child = node.firstChild;
5451     while(child) {
5452       var next = child.nextSibling;
5453       if (child.className == 'stopLatex2mml') {
5454           break;
5455       }
5456       patch_element(child);
5457       child = next;
5458     }
5459   }
5460 }
5461 this.patch_element = patch_element;
5462
5463 /*
5464 var do_patch_images = GM_getValue("patch-images", false);
5465 var delayed_patch = GM_getValue("delayed-patch", false);
5466 */
5467 var do_patch_images = true;
5468 var delayed_patch = false;
5469
5470 /*
5471 if( va_view == 'web' ){
5472     patch_element(document.documentElement);
5473 }
5474 */
5475 };
5476
5477
5478
5479 /*!
5480 Deck JS - deck.simplemath
5481 Copyright (c) 2012 RĂ©mi Emonet,
5482 using a modified version of the script from http://gold-saucer.afraid.org/mathml/greasemonkey/ by Steve Cheng
5483 */
5484
5485 /*
5486 This module provides a support for latex equation syntax.
5487 */
5488
5489 (function($, deck, undefined) {
5490     var $d = $(document);
5491     var may = function(f) {return f ? f : function() {}};
5492     
5493     $d.bind('deck.init', function() {
5494         var container = $[deck]('getContainer');
5495         $('.latex', container).each(function() {
5496             var it = this;
5497             var v = $(it).text();
5498             it.innerHTML = "$\\displaystyle "+v+"$";
5499             new latex2mml().patch_element(it);
5500         });
5501     });
5502
5503 })(jQuery, 'deck');
5504
5505 /*!
5506 Deck JS - deck.clone
5507 Copyright (c) 2011-2014 RĂ©mi Emonet, original version from RĂ©mi BARRAQUAND
5508 Licensed under the MIT license.
5509 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
5510 */
5511
5512 /*
5513 This module provides a support for cloning the deck and enabling a presenter view.
5514 It also provides the behavior that copies the current "notes" to a "notes-target", to be used in the presenter view.
5515 */
5516
5517 (function($, deck, undefined) {
5518     var $d = $(document);
5519     var clones = new Array();
5520         
5521     $.extend(true, $[deck].defaults, {  
5522         selectors: {
5523             clonepointer: '.clonepointer',
5524             cloneNotes: '.notes',
5525             cloneNotesTarget: '.notes-target'
5526         },
5527         classes: {
5528             isClone: 'is-clone',
5529             hasClones: 'has-clones',
5530             pointerClick: 'pointer-click'
5531         },
5532         snippets: {
5533             clone: true
5534         },
5535         keys: {
5536             clone: 67 // c
5537         },
5538         fitFollowsClone: true
5539     });
5540
5541     var hadClones = false;
5542     var cleanClones = function() {
5543         var opts = $[deck]('getOptions');
5544         // remove closed windows
5545         $.each(clones, function(index, clone) {
5546             if (clone.closed()) {
5547                 clones.splice(index, 1); // remove element "index"
5548             }
5549         });
5550         // tag/untag the current container depending on the presence of clones
5551         if (clones.length > 0) {
5552             $("body").addClass(opts.classes.hasClones);
5553             if (opts.fitFollowsClone && !hadClones) $[deck]('disableScale');
5554             hadClones = true;
5555         } else {
5556             $("body").removeClass(opts.classes.hasClones);
5557             if (opts.fitFollowsClone && hadClones) $[deck]('enableScale');
5558             hadClones = false;
5559         }
5560     };
5561
5562     /*
5563       jQuery.deck('addClone')
5564       Create a clone of this window and add it to the clones list.
5565     */
5566     $[deck]('extend', 'addClone', function() {
5567         clone = new DeckClone();
5568         clones.push(clone);
5569         cleanClones();
5570         return clone;
5571     });
5572     $[deck]('extend', 'cleanClones', function() { // to be triggered by the closing of a clone window
5573         setTimeout(cleanClones, 1);
5574     });
5575     $[deck]('extend', 'pointerAt', function(rx, ry) {
5576         var pos = {left: (rx*100)+"%", top: (ry*100)+"%"};
5577         var opts = $[deck]('getOptions');
5578         var current = $[deck]('getToplevelSlideOf', $[deck]('getSlide')).node; // actually uses the step extension
5579         var pointers = $(opts.selectors.clonepointer);
5580         if (!current.is(pointers.parent())) { // move them within the new slide if it changed
5581             pointers.show().appendTo(current);
5582         }
5583         pointers.css(pos);
5584         // using % position instead of ".offset" as there are jitter/glitches with it
5585     });
5586     $[deck]('extend', 'pointerDown', function() {
5587         var opts = $[deck]('getOptions');
5588         var pointers = $(opts.selectors.clonepointer);
5589         pointers.addClass(opts.classes.pointerClick);
5590     });
5591     $[deck]('extend', 'pointerUp', function() {
5592         var opts = $[deck]('getOptions');
5593         var pointers = $(opts.selectors.clonepointer);
5594         pointers.removeClass(opts.classes.pointerClick);
5595     });
5596     
5597     var isClone = false;
5598     var parentDeck = null;
5599     /*
5600       jQuery.deck('Init')
5601     */
5602     $d.bind('deck.init', function() {
5603         var opts = $[deck]('getOptions');
5604         var container = $[deck]('getContainer');
5605         
5606         if (opts.snippets.clone) {
5607             var d = function() {return $('<div/>');}
5608             d().addClass("clonepointer scale-on-click").append(
5609                 d().attr("style", "border: 2px solid red; border-radius: 50%; z-index:10;"
5610                          +"margin: -11px 0 0 -11px; width:20px; height:20px; opacity: .5;")
5611                 ).appendTo(container);
5612             d().addClass("clonepointer scale-on-click").append(
5613                 d().attr("style", "border: 2px solid red; border-radius: 50%; z-index:10;"
5614                          +"margin: -16px 0 0 -16px; width:30px; height:30px;")
5615                 ).appendTo(container);
5616             d().addClass(opts.selectors.cloneNotesTarget.replace(/\./, ''))
5617                 .appendTo(container);
5618         }
5619
5620         $(opts.selectors.clonepointer).hide();
5621
5622         function safeIsClone(w) {
5623             try {
5624                 return w.opener && w.opener.___iscloner___;
5625             } catch(e) {
5626                 // when linked from another origin, there is an opener
5627                 // but accessing its properties throws a security exception
5628                 return false;
5629             }
5630         }
5631
5632         isClone = safeIsClone(window);
5633
5634         if (isClone) { // it's a clone!
5635             $("body").addClass(opts.classes.isClone);
5636             $(".anim-continue", container).removeClass("anim-continue"); // friend with anim extension
5637             window.___fromparent___ = false;
5638             parentDeck = function() {
5639                 if (! window.___fromparent___) {
5640                     window.opener.$.deck.apply(window.opener.$, arguments);
5641                 }
5642             }
5643             $(window).on('unload', function() {
5644                 parentDeck('cleanClones');
5645             });
5646         } else { // it is a normal window
5647             /* bind clone key events */
5648             $d.unbind('keydown.deckclone').bind('keydown.deckclone', function(e) {
5649                 if (e.which === opts.keys.clone || $.inArray(e.which, opts.keys.clone) > -1) {
5650                     if (e.ctrlKey) return; // do not trigger on Ctrl+C (by default)
5651                     $[deck]('addClone');
5652                     window.___iscloner___ = true;
5653                     e.preventDefault();
5654                 }
5655             });
5656         }
5657     })
5658     /* Update current slide number with each change event */
5659     .bind('deck.change', function(e, from, to) {
5660         if (isClone) {
5661             parentDeck('go', to);
5662         } else {
5663             cleanClones();
5664             $.each(clones, function(index, clone) {
5665                 clone.deck('go', to);
5666             });
5667             
5668             var opts = $[deck]('getOptions');
5669             var currentTopLevel = $[deck]('getToplevelSlideOf', $[deck]('getSlide', to)).node;
5670             var notes = $(opts.selectors.cloneNotes, currentTopLevel).html();
5671             if (notes === undefined) {
5672                 $(opts.selectors.cloneNotesTarget).html("");
5673             } else {
5674                 $(opts.selectors.cloneNotesTarget).html(notes);
5675             }
5676         }
5677     })
5678     /* Replicate mouse cursor */
5679     .bind('mousemove', function(e) {
5680         if (isClone) return;
5681         var current = $[deck]('getToplevelSlideOf', $[deck]('getSlide')).node; // actually uses the step extension (dependency can be removed if needed)
5682         var r = current.get(0).getBoundingClientRect();
5683         var x = (e.clientX - r.left) / r.width;
5684         var y = (e.clientY - r.top) / r.height;
5685         cleanClones();
5686         if (x < 0 || y < 0 || x > 1 || y > 1) return;
5687         $.each(clones, function(index, clone) {
5688             clone.deck('pointerAt', x, y);
5689         });
5690     })
5691     .bind('mousedown', function(e) {
5692         if (isClone) return;
5693         cleanClones();
5694         $.each(clones, function(index, clone) {
5695             clone.deck('pointerDown');
5696         });
5697     })
5698     .bind('mouseup', function(e) {
5699         if (isClone) return;
5700         cleanClones();
5701         $.each(clones, function(index, clone) {
5702             clone.deck('pointerUp');
5703         });
5704     });
5705     
5706     /*
5707         Simple Clone manager (must be improved, by for instance adding cloning
5708         option e.g. propagate change, etc.)
5709         */
5710     var DeckClone = function() {
5711         var clone = window.open(window.location);
5712         this.closed = function() {return clone.closed;}
5713         this.deck = function() {
5714             if (clone.closed) return;
5715             if (clone.$) {
5716                 clone.___fromparent___ = true;
5717                 clone.$.deck.apply(clone.$, arguments);
5718                 clone.___fromparent___ = false;
5719             }
5720         }
5721     }
5722 })(jQuery, 'deck');
5723
5724
5725 /*!
5726 Deck JS - deck.goto
5727 Copyright (c) 2011-2014 Caleb Troughton
5728 Dual licensed under the MIT license.
5729 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
5730 */
5731
5732 /*
5733 This module adds the necessary methods and key bindings to show and hide a form
5734 for jumping to any slide number/id in the deck (and processes that form
5735 accordingly). The form-showing state is indicated by the presence of a class on
5736 the deck container.
5737 */
5738 (function($, undefined) {
5739   var $document = $(document);
5740   var rootCounter;
5741
5742   var maybeAddSnippet = function() {
5743     var options = $.deck('getOptions');
5744     if (options.snippets.goto) {
5745       if ($(options.selectors.gotoForm).size() > 0 && options.alert.goto) {
5746         alert("'options.snippets.goto' is true but a "+options.selectors.gotoForm+" has been found."
5747               +"\nThis might cause interaction glitches."
5748               +"\n"
5749               +"\nSuggestion: remove your html snippet or pass the {snippets: {goto: false}} option."
5750              );
5751       }
5752       $('<form/>').addClass('goto-form').attr('action', '.').attr('method', 'get')
5753         .append($('<label/>').attr('for', 'goto-slide').text('Go to slide:'))
5754         .append($('<input/>').attr('type', 'text').attr('id', 'goto-slide').attr('name', 'slidenum').attr('list', 'goto-datalist'))
5755         .append($('<datalist/>').attr('id', 'goto-datalist'))
5756         .append($('<input/>').attr('type', 'submit').attr('value', 'Go'))
5757       .appendTo($.deck('getContainer'));
5758     }
5759   };
5760
5761   var bindKeyEvents = function() {
5762     $document.unbind('keydown.deckgoto');
5763     $document.bind('keydown.deckgoto', function(event) {
5764       var key = $.deck('getOptions').keys.goto;
5765       if (event.which === key || $.inArray(event.which, key) > -1) {
5766         event.preventDefault();
5767         $.deck('toggleGoTo');
5768       }
5769     });
5770   };
5771
5772   var populateDatalist = function() {
5773     var options = $.deck('getOptions');
5774     var $datalist = $(options.selectors.gotoDatalist);
5775
5776     $.each($.deck('getSlides'), function(i, $slide) {
5777       var id = $slide.attr('id');
5778       if (id) {
5779         $datalist.append('<option value="' + id + '">');
5780       }
5781     });
5782   };
5783
5784   var markRootSlides = function() {
5785     var options = $.deck('getOptions');
5786     var slideTest = $.map([
5787       options.classes.before,
5788       options.classes.previous,
5789       options.classes.current,
5790       options.classes.next,
5791       options.classes.after
5792     ], function(el, i) {
5793       return '.' + el;
5794     }).join(', ');
5795
5796     rootCounter = 0;
5797     $.each($.deck('getSlides'), function(i, $slide) {
5798       var $parentSlides = $slide.parentsUntil(
5799         options.selectors.container,
5800         slideTest
5801       );
5802
5803       if ($parentSlides.length) {
5804         $slide.removeData('rootIndex');
5805       }
5806       else if (!options.countNested) {
5807         ++rootCounter;
5808         $slide.data('rootIndex', rootCounter);
5809       }
5810     });
5811   };
5812
5813   var handleFormSubmit = function() {
5814     var options = $.deck('getOptions');
5815     var $form = $(options.selectors.gotoForm);
5816
5817     $form.unbind('submit.deckgoto');
5818     $form.bind('submit.deckgoto', function(event) {
5819       var $field = $(options.selectors.gotoInput);
5820       var indexOrId = $field.val();
5821       var index = parseInt(indexOrId, 10);
5822
5823       if (!options.countNested) {
5824         if (!isNaN(index) && (index > rootCounter || index <= 0)) {
5825           return false;
5826         }
5827         $.each($.deck('getSlides'), function(i, $slide) {
5828           if ($slide.data('rootIndex') === index) {
5829             index = i + 1;
5830             return false;
5831           }
5832         });
5833       }
5834
5835       $.deck('go', isNaN(index) ? indexOrId : index - 1);
5836       $.deck('hideGoTo');
5837       $field.val('');
5838       event.preventDefault();
5839     });
5840   };
5841
5842   /*
5843   Extends defaults/options.
5844
5845   options.classes.goto
5846     This class is added to the deck container when showing the Go To Slide
5847     form.
5848
5849   options.selectors.gotoDatalist
5850     The element that matches this selector is the datalist element that will
5851     be populated with options for each of the slide ids.  In browsers that
5852     support the datalist element, this provides a drop list of slide ids to
5853     aid the user in selecting a slide.
5854
5855   options.selectors.gotoForm
5856     The element that matches this selector is the form that is submitted
5857     when a user hits enter after typing a slide number/id in the gotoInput
5858     element.
5859
5860   options.selectors.gotoInput
5861     The element that matches this selector is the text input field for
5862     entering a slide number/id in the Go To Slide form.
5863
5864   options.keys.goto
5865     The numeric keycode used to show the Go To Slide form.
5866
5867   options.countNested
5868     If false, only top level slides will be counted when entering a
5869     slide number.
5870   */
5871   $.extend(true, $.deck.defaults, {
5872     classes: {
5873       goto: 'deck-goto'
5874     },
5875
5876     selectors: {
5877       gotoDatalist: '#goto-datalist',
5878       gotoForm: '.goto-form',
5879       gotoInput: '#goto-slide'
5880     },
5881
5882     snippets: {
5883       goto: true
5884     },
5885
5886     alert: {
5887       goto: true
5888     },
5889
5890     keys: {
5891       goto: 71 // g
5892     },
5893
5894     countNested: true
5895   });
5896
5897   /*
5898   jQuery.deck('showGoTo')
5899
5900   Shows the Go To Slide form by adding the class specified by the goto class
5901   option to the deck container.
5902   */
5903   $.deck('extend', 'showGoTo', function() {
5904     var options = $.deck('getOptions');
5905     $.deck('getContainer').addClass(options.classes.goto);
5906     $(options.selectors.gotoForm).attr('aria-hidden', false);
5907     $(options.selectors.gotoInput).focus();
5908   });
5909
5910   /*
5911   jQuery.deck('hideGoTo')
5912
5913   Hides the Go To Slide form by removing the class specified by the goto class
5914   option from the deck container.
5915   */
5916   $.deck('extend', 'hideGoTo', function() {
5917     var options = $.deck('getOptions');
5918     $(options.selectors.gotoInput).blur();
5919     $.deck('getContainer').removeClass(options.classes.goto);
5920     $(options.selectors.gotoForm).attr('aria-hidden', true);
5921   });
5922
5923   /*
5924   jQuery.deck('toggleGoTo')
5925
5926   Toggles between showing and hiding the Go To Slide form.
5927   */
5928   $.deck('extend', 'toggleGoTo', function() {
5929     var options = $.deck('getOptions');
5930     var hasGotoClass = $.deck('getContainer').hasClass(options.classes.goto);
5931     $.deck(hasGotoClass ? 'hideGoTo' : 'showGoTo');
5932   });
5933
5934   $document.bind('deck.init', function() {
5935     maybeAddSnippet();
5936     bindKeyEvents();
5937     populateDatalist();
5938     markRootSlides();
5939     handleFormSubmit();
5940   });
5941 })(jQuery);
5942
5943
5944 /*!
5945 Deck JS - deck.progress
5946 Copyright (c) 2014 RĂ©mi Emonet
5947 Dual licensed under the MIT license.
5948 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
5949 */
5950
5951 /*
5952 This module adds a (current)/(total) style status indicator to the deck.
5953
5954 It is designed to be a drop-in replacement of deck.status, but on steroĂ¯ds.
5955 Note however, that it does not handle the countNested=true case.
5956 */
5957 (function($, undefined) {
5958     var $document = $(document);
5959     var rootCounter;
5960     var INITEVENT = "dummyinit";
5961     var SIZEEVENT = "dummysize";
5962     
5963     var updateCurrent = function(event, from, to) {
5964         var opts = $.deck('getOptions');
5965         var currentSlideNumber = to + 1;
5966         var $container = $.deck('getContainer');
5967         currentSlideNumber = $.deck('getSlide', to).data('rootSlide');
5968         $(opts.selectors.statusCurrent).text(currentSlideNumber);
5969
5970         var icur = 0;
5971         for (; icur < $.deck('getSlides').length; icur++) {
5972             var top = $.deck('getSlide', icur).data('rootSlide');
5973             if (top == currentSlideNumber) {
5974                 break;
5975             }
5976         }
5977         var last = null;
5978         var currentDetail = to;
5979         var lastDetail = icur;
5980         for (; icur < $.deck('getSlides').length; icur++) {
5981             last = $.deck('getSlide', icur).data('rootSlide');
5982             lastDetail = icur+1;
5983             if ($.deck('getSlide', icur).filter(opts.selectors.statusFakeEnd).size() > 0) break;
5984         }
5985         $(opts.selectors.statusTotal).text(last);
5986
5987         // handle the data-progress
5988         var progresses = $('*['+opts.dataProgress+'], *['+opts.dataProgressOnce+'], *['+opts.dataProgressSize+']');
5989         if (progresses.size() > 0) {
5990             var visibleSlide = $.deck('getSlide').parentsUntil(opts.selectors.container).addBack().filter(opts.selectors.slides);
5991             // the eval context
5992             var slide = visibleSlide.get(0).getBoundingClientRect();
5993             var screen = {width: $container.innerWidth(), height: $container.innerHeight()};
5994             var n = currentSlideNumber;
5995             var N = last;
5996             var fullTotal = $.deck('getTopLevelSlides').length;
5997             var detail = {n: currentDetail+1, N: lastDetail, fullTotal: $.deck('getSlides').length};
5998             var designRatio = Math.max(slide.width / opts.designWidth, slide.height / opts.designHeight);
5999             var o = opts;
6000             var p = n/N;
6001             var pFull = n/fullTotal;
6002             detail.p = detail.n/detail.N;
6003             detail.pFull = detail.n/detail.fullTotal;
6004             // 
6005             progresses.each(function(i, el) {
6006                 var spe = {
6007                     bottom: function(fontSize, botByRatio, botFixed) {
6008                         botFixed = botFixed || 0;
6009                         $(el).css('font-size', (fontSize * designRatio)+"px");
6010                         $(el).css('top', (slide.bottom - botFixed - botByRatio*designRatio)+'px');
6011                     },
6012                     top: function(fontSize, topByRatio, topFixed) {
6013                         topFixed = topFixed || 0;
6014                         $(el).css('font-size', (fontSize * designRatio)+"px");
6015                         $(el).css('top', (slide.top + topFixed + topByRatio*designRatio)+'px');
6016                     }
6017                 };
6018                 var att = $(el).attr(event == INITEVENT ? opts.dataProgressOnce : event == SIZEEVENT ? opts.dataProgressSize : opts.dataProgress);
6019                 if (att == null || att.length == 0) return;
6020                 var tasks = att.split(/ *; */);
6021                 for (t in tasks) {
6022                     var parts = tasks[t].split(/ *: */);
6023                     if (parts.length != 2) {
6024                         if (opts.alert.wrongDataProgress) alert(
6025                             "There seem to be a problem with the following data-progress of\n   '" +tasks[t]+ "'\n");
6026                     } else {
6027                         var what = parts[0];
6028                         var expr = parts[1];
6029                         var val = eval(expr);
6030                         if (what == "") {
6031                             // skip: expected to be some "magic", e.g. custom code or call to helpers
6032                         } else if (what.substring(0,1) == "@") {
6033                             // special attribute setting, not css
6034                             what = what.substring(1);
6035                             $(el).attr(what, val);
6036                         } else if (what == "$text") {
6037                             $(el).text(val);
6038                         } else if (what == "$html") {
6039                             $(el).html(val);
6040                         } else {
6041                             $(el).css(what, val);
6042                         }
6043                     }
6044                 }
6045             });
6046         }
6047     };
6048     
6049     var markRootSlides = function() {
6050         var opts = $.deck('getOptions');
6051         var slideTest = $.map([
6052             opts.classes.before,
6053             opts.classes.previous,
6054             opts.classes.current,
6055             opts.classes.next,
6056             opts.classes.after
6057         ], function(el, i) {
6058             return '.' + el;
6059         }).join(', ');
6060         
6061         rootCounter = 0;
6062         $.each($.deck('getSlides'), function(i, $slide) {
6063             var $parentSlides = $slide.parentsUntil(
6064                 opts.selectors.container,
6065                 slideTest
6066             );
6067             
6068             if ($parentSlides.length) {
6069                 $slide.data('rootSlide', $parentSlides.last().data('rootSlide'));
6070             }
6071             else {
6072                 ++rootCounter;
6073                 $slide.data('rootSlide', rootCounter);
6074             }
6075         });
6076     };
6077     
6078     var fireEventOnCurrentSlide = function(ev) {
6079         var slides = $.deck('getSlides');
6080         var $currentSlide = $.deck('getSlide');
6081         var index;
6082         
6083         $.each(slides, function(i, $slide) {
6084             if ($slide === $currentSlide) {
6085                 index = i;
6086                 return false;
6087             }
6088         });
6089         updateCurrent(ev, index, index);
6090     };
6091     
6092     var setTotalSlideNumber = function() {
6093         var opts = $.deck('getOptions');
6094         var slides = $.deck('getSlides');
6095         
6096         var nSlides = $.deck('getTopLevelSlides').length;
6097         $(opts.selectors.statusFullTotal).text(nSlides);
6098
6099     };
6100     
6101     /*
6102       Extends defaults/options.
6103       
6104       opts.selectors.statusCurrent
6105       The element matching this selector displays the current slide number.
6106       
6107       opts.selectors.statusTotal
6108       The element matching this selector displays the total number of slides.
6109       
6110       opts.countNested
6111       If false, only top level slides will be counted in the current and
6112       total numbers.
6113     */
6114     $.extend(true, $.deck.defaults, {
6115         selectors: {
6116             statusCurrent: '.deck-status-current',
6117             statusTotal: '.deck-status-total',
6118             statusFakeEnd: '.deck-status-fake-end',
6119             statusFullTotal: '.deck-status-full-total',
6120             progress10: '.deck-progress-10'
6121         },
6122         alert: {
6123             wrongDataProgress: true,
6124             possibleDebounceProblem: true
6125         },
6126         dataProgress: "data-progress",
6127         dataProgressOnce: "data-progress-once",
6128         dataProgressSize: "data-progress-size",
6129         progressSizeDebounce: 201 /* somewhat, it should be bigger that the fit debounce */
6130     });
6131     
6132     $document.bind('deck.init', function() {
6133         var opts = $.deck('getOptions');
6134         $(opts.selectors.progress10).attr(opts.dataProgressSize, ':spe.bottom(10, 12)')
6135         markRootSlides();
6136         fireEventOnCurrentSlide(INITEVENT);
6137         fireEventOnCurrentSlide(SIZEEVENT);
6138         setTotalSlideNumber();
6139     });
6140     var timer = -1;
6141     $(window).unbind('resize.deckprogress').bind('resize.deckprogress', function() {
6142         var opts = $.deck('getOptions');
6143         if (opts.alert.possibleDebounceProblem && opts.progressSizeDebounce < opts.scaleDebounce + 1) {
6144             alert(
6145                 "There might be a problem with the respective debounce value:\n   progressSizeDebounce: "+opts.progressSizeDebounce+"\n   scaleDebounce: "+opts.scaleDebounce);
6146
6147         }
6148         window.clearTimeout(timer);
6149         timer = window.setTimeout( function() {
6150             fireEventOnCurrentSlide(SIZEEVENT);
6151             fireEventOnCurrentSlide("fire also the update event as some things might also need resizing");
6152         }, opts.progressSizeDebounce);
6153     });
6154     $document.bind('deck.change', updateCurrent);
6155 })(jQuery, 'deck');
6156
6157
6158 /*!
6159 Deck JS - deck.navigation
6160 Copyright (c) 2011-2014 Caleb Troughton
6161 Dual licensed under the MIT license.
6162 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6163 */
6164
6165 /*
6166 This module adds clickable previous and next links to the deck.
6167 */
6168 (function($, undefined) {
6169   var $document = $(document);
6170
6171   /* Updates link hrefs, and disabled states if last/first slide */
6172   var updateButtons = function(event, from, to) {
6173     var options = $.deck('getOptions');
6174     var lastIndex = $.deck('getSlides').length - 1;
6175     var $prevSlide = $.deck('getSlide', to - 1);
6176     var $nextSlide = $.deck('getSlide', to + 1);
6177     var hrefBase = window.location.href.replace(/#.*/, '');
6178     var prevId = $prevSlide ? $prevSlide.attr('id') : undefined;
6179     var nextId = $nextSlide ? $nextSlide.attr('id') : undefined;
6180     var $prevButton = $(options.selectors.previousLink);
6181     var $nextButton = $(options.selectors.nextLink);
6182
6183     $prevButton.toggleClass(options.classes.navDisabled, to === 0);
6184     $prevButton.attr('aria-disabled', to === 0);
6185     $prevButton.attr('href', hrefBase + '#' + (prevId ? prevId : ''));
6186     $nextButton.toggleClass(options.classes.navDisabled, to === lastIndex);
6187     $nextButton.attr('aria-disabled', to === lastIndex);
6188     $nextButton.attr('href', hrefBase + '#' + (nextId ? nextId : ''));
6189   };
6190
6191   /*
6192   Extends defaults/options.
6193
6194   options.classes.navDisabled
6195     This class is added to a navigation link when that action is disabled.
6196     It is added to the previous link when on the first slide, and to the
6197     next link when on the last slide.
6198
6199   options.selectors.nextLink
6200     The elements that match this selector will move the deck to the next
6201     slide when clicked.
6202
6203   options.selectors.previousLink
6204     The elements that match this selector will move to deck to the previous
6205     slide when clicked.
6206   */
6207   $.extend(true, $.deck.defaults, {
6208     classes: {
6209       navDisabled: 'deck-nav-disabled'
6210     },
6211
6212     selectors: {
6213       nextLink: '.deck-next-link',
6214       previousLink: '.deck-prev-link'
6215     }
6216   });
6217
6218   $document.bind('deck.init', function() {
6219     var options = $.deck('getOptions');
6220     var slides = $.deck('getSlides');
6221     var $current = $.deck('getSlide');
6222     var $prevButton = $(options.selectors.previousLink);
6223     var $nextButton = $(options.selectors.nextLink);
6224     var index;
6225
6226     // Setup prev/next link events
6227     $prevButton.unbind('click.decknavigation');
6228     $prevButton.bind('click.decknavigation', function(event) {
6229       $.deck('prev');
6230       event.preventDefault();
6231     });
6232
6233     $nextButton.unbind('click.decknavigation');
6234     $nextButton.bind('click.decknavigation', function(event) {
6235       $.deck('next');
6236       event.preventDefault();
6237     });
6238
6239     // Find where we started in the deck and set initial states
6240     $.each(slides, function(i, $slide) {
6241       if ($slide === $current) {
6242         index = i;
6243         return false;
6244       }
6245     });
6246     updateButtons(null, index, index);
6247   });
6248
6249   $document.bind('deck.change', updateButtons);
6250 })(jQuery);
6251
6252
6253 /*!
6254 Deck JS - deck.menu
6255 Copyright (c) 2011-2014 Caleb Troughton
6256 Dual licensed under the MIT license.
6257 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6258 */
6259
6260 /*
6261 This module adds the methods and key binding to show and hide a menu of all
6262 slides in the deck. The deck menu state is indicated by the presence of a class
6263 on the deck container.
6264 */
6265 (function($, undefined) {
6266   var $document = $(document);
6267   var $html = $('html');
6268   var rootSlides;
6269
6270   var populateRootSlidesArray = function() {
6271     var options = $.deck('getOptions');
6272     var slideTest = $.map([
6273       options.classes.before,
6274       options.classes.previous,
6275       options.classes.current,
6276       options.classes.next,
6277       options.classes.after
6278     ], function(el, i) {
6279       return '.' + el;
6280     }).join(', ');
6281
6282     rootSlides = [];
6283     $.each($.deck('getSlides'), function(i, $slide) {
6284       var $parentSlides = $slide.parentsUntil(
6285         options.selectors.container,
6286         slideTest
6287       );
6288       if (!$parentSlides.length) {
6289         rootSlides.push($slide);
6290       }
6291     });
6292   };
6293
6294   var bindKeyEvents = function() {
6295     var options = $.deck('getOptions');
6296     $document.unbind('keydown.deckmenu');
6297     $document.bind('keydown.deckmenu', function(event) {
6298       var isMenuKey = event.which === options.keys.menu;
6299       isMenuKey = isMenuKey || $.inArray(event.which, options.keys.menu) > -1;
6300       if (isMenuKey && !event.ctrlKey) {
6301         $.deck('toggleMenu');
6302         event.preventDefault();
6303       }
6304     });
6305   };
6306
6307   var bindTouchEvents = function() {
6308     var $container = $.deck('getContainer');
6309     var options = $.deck('getOptions');
6310     var touchEndTime = 0;
6311     var currentSlide;
6312
6313     $container.unbind('touchstart.deckmenu');
6314     $container.bind('touchstart.deckmenu', function() {
6315       currentSlide = $.deck('getSlide');
6316     });
6317     $container.unbind('touchend.deckmenu');
6318     $container.bind('touchend.deckmenu', function(event) {
6319       var now = Date.now();
6320       var isDoubletap = now - touchEndTime < options.touch.doubletapWindow;
6321
6322       // Ignore this touch event if it caused a nav change (swipe)
6323       if (currentSlide !== $.deck('getSlide')) {
6324         return;
6325       }
6326       if (isDoubletap) {
6327         $.deck('toggleMenu');
6328         event.preventDefault();
6329       }
6330       touchEndTime = now;
6331     });
6332   };
6333
6334   var setupMenuSlideSelection = function() {
6335     var options = $.deck('getOptions');
6336
6337     $.each($.deck('getSlides'), function(i, $slide) {
6338       $slide.unbind('click.deckmenu');
6339       $slide.bind('click.deckmenu', function(event) {
6340         if (!$.deck('getContainer').hasClass(options.classes.menu)) {
6341           return;
6342         }
6343         $.deck('go', i);
6344         $.deck('hideMenu');
6345         event.stopPropagation();
6346         event.preventDefault();
6347       });
6348     });
6349   };
6350
6351   /*
6352   Extends defaults/options.
6353
6354   options.classes.menu
6355     This class is added to the deck container when showing the slide menu.
6356
6357   options.keys.menu
6358     The numeric keycode used to toggle between showing and hiding the slide
6359     menu.
6360
6361   options.touch.doubletapWindow
6362     Two consecutive touch events within this number of milliseconds will
6363     be considered a double tap, and will toggle the menu on touch devices.
6364   */
6365   $.extend(true, $.deck.defaults, {
6366     classes: {
6367       menu: 'deck-menu'
6368     },
6369
6370     keys: {
6371       menu: 77 // m
6372     },
6373
6374     touch: {
6375       doubletapWindow: 400
6376     }
6377   });
6378
6379   /*
6380   jQuery.deck('showMenu')
6381
6382   Shows the slide menu by adding the class specified by the menu class option
6383   to the deck container.
6384   */
6385   $.deck('extend', 'showMenu', function() {
6386     var $container = $.deck('getContainer');
6387     var options = $.deck('getOptions');
6388
6389     if ($container.hasClass(options.classes.menu)) {
6390       return;
6391     }
6392
6393     // Hide through loading class to short-circuit transitions (perf)
6394     $container.addClass([
6395       options.classes.loading,
6396       options.classes.menu
6397     ].join(' '));
6398
6399     /* Forced to do this in JS until CSS learns second-grade math. Save old
6400     style value for restoration when menu is hidden. */
6401     if (Modernizr.csstransforms) {
6402       $.each(rootSlides, function(i, $slide) {
6403         $slide.data('oldStyle', $slide.attr('style'));
6404         $slide.css({
6405           'position': 'absolute',
6406           'left': ((i % 4) * 25) + '%',
6407           'top': (Math.floor(i / 4) * 25) + '%'
6408         });
6409       });
6410     }
6411
6412     // Need to ensure the loading class renders first, then remove
6413     window.setTimeout(function() {
6414       $container.removeClass(options.classes.loading);
6415       $container.scrollTop($.deck('getSlide').position().top);
6416     }, 0);
6417   });
6418
6419   /*
6420   jQuery.deck('hideMenu')
6421
6422   Hides the slide menu by removing the class specified by the menu class
6423   option from the deck container.
6424   */
6425   $.deck('extend', 'hideMenu', function() {
6426     var $container = $.deck('getContainer');
6427     var options = $.deck('getOptions');
6428
6429     if (!$container.hasClass(options.classes.menu)) {
6430       return;
6431     }
6432
6433     $container.removeClass(options.classes.menu);
6434     $container.addClass(options.classes.loading);
6435
6436     /* Restore old style value */
6437     if (Modernizr.csstransforms) {
6438       $.each(rootSlides, function(i, $slide) {
6439         var oldStyle = $slide.data('oldStyle');
6440         $slide.attr('style', oldStyle ? oldStyle : '');
6441       });
6442     }
6443
6444     window.setTimeout(function() {
6445       $container.removeClass(options.classes.loading);
6446       $container.scrollTop(0);
6447     }, 0);
6448   });
6449
6450   /*
6451   jQuery.deck('toggleMenu')
6452
6453   Toggles between showing and hiding the slide menu.
6454   */
6455   $.deck('extend', 'toggleMenu', function() {
6456     $.deck('getContainer').hasClass($.deck('getOptions').classes.menu) ?
6457     $.deck('hideMenu') : $.deck('showMenu');
6458   });
6459
6460   $document.bind('deck.init', function() {
6461     populateRootSlidesArray();
6462     bindKeyEvents();
6463     bindTouchEvents();
6464     setupMenuSlideSelection();
6465   });
6466
6467   $document.bind('deck.change', function(event, from, to) {
6468     var $container = $.deck('getContainer');
6469     var containerScroll, slideTop;
6470
6471     if ($container.hasClass($.deck('getOptions').classes.menu)) {
6472       containerScroll = $container.scrollTop();
6473       slideTop = $.deck('getSlide', to).position().top;
6474       $container.scrollTop(containerScroll + slideTop);
6475     }
6476   });
6477 })(jQuery);
6478
6479 /*!
6480 Deck JS - deck.step
6481 Copyright (c) 2011-2014 RĂ©mi Emonet
6482 Licensed under the MIT license.
6483 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6484 */
6485
6486 /*
6487 This module provides new methods for stepping without considering sub-slides, together with tools for finding toplevel slides etc.
6488 It also overrides the defaults keybinding and countNested value (so it is better to include it after "goto" and "status" extensions).
6489 */
6490
6491 (function($, deck, undefined) {
6492     var $d = $(document);
6493     // undo the defaults (to be sure jquery behaves properly when overriding it)
6494     $.extend(true, $[deck].defaults, { keys: {next:null, previous:null}});
6495     // and go on
6496     $.extend(true, $[deck].defaults, {
6497         selectors: {
6498             subslidesToNotify: ".slide,.onshowtoplevel"
6499         },
6500         // Here we redefined the defaults:
6501         //  - we avoid counting nested slides
6502         //  - we keep up/down for top-level slides
6503         //  - we still use pgup/pgdown for inner slides as they are sent by some pluggable remote controls
6504         keys: {
6505             // backspace, left arrow, page down
6506             previous: [8, 37, 33],
6507             // enter, space, right arrow, page up
6508             next: [13, 32, 39, 34],
6509             // up arrow
6510             previousTopLevel: [38],
6511             // down arrow,
6512             nextTopLevel: [40],
6513             // key 'z'
6514             nextEndOfTopLevel: [90],
6515             // key 'a'
6516             previousEndOfTopLevel: [65]
6517         },
6518         countNested: false
6519     });
6520     var myInArray = function(el, arr) {
6521         for (i in arr) if (arr[i].is(el)) return i*1; // cast to int
6522         return -1;
6523     };
6524     $[deck]('extend', 'getSlideIndex', function(node) {
6525         var slides = $[deck]('getSlides');
6526         var ind = myInArray(node, slides);
6527         return ind;
6528     });
6529     $[deck]('extend', 'getToplevelSlideOf', function(node) {
6530         var opts = $[deck]('getOptions');
6531         var slides = $[deck]('getSlides');
6532         var last = {node: $(node), index: myInArray(node, slides)};
6533         $(node).parentsUntil(opts.selectors.container).each( function(ii, v) {
6534             var ind = myInArray(v, slides);
6535             if (ind != -1) {
6536                 last = {node: $(v), index: ind};
6537             }
6538         });
6539         return last;
6540     });
6541     $[deck]('extend', 'getToplevelSlideOfIndex', function(ind) {
6542         return $[deck]('getToplevelSlideOf', $[deck]('getSlide', ind));
6543     });
6544     $[deck]('extend', 'previousTopLevelSlide', function() {
6545         /* Find the real previous parent */
6546         var current = $[deck]('getSlide');
6547         var currentParent = $[deck]('getToplevelSlideOf', current);
6548         var toGo = currentParent.index;
6549         if (current.is(currentParent.node) && toGo > 0) {
6550             // This is already toplevel slide, just go to the previous toplevel one (parent of the previous one)
6551             toGo = $[deck]('getToplevelSlideOfIndex', toGo-1).index;
6552         }
6553         $[deck]('go', toGo);
6554         
6555     });
6556     $[deck]('extend', 'nextTopLevelSlide', function() {
6557         /* Find the real next parent */
6558         var current = $[deck]('getSlide');
6559         var currentParent = $[deck]('getToplevelSlideOf', current);
6560         var icur = currentParent.index;
6561         for (; icur < $[deck]('getSlides').length; icur++) {
6562             var cursorParent = $[deck]('getToplevelSlideOfIndex', icur).node;
6563             if (!cursorParent.is(currentParent.node)) {
6564                 $[deck]('go', icur);
6565                 break;
6566             }
6567         }
6568     });
6569     $[deck]('extend', 'nextEndOfTopLevelSlide', function() {
6570         /* Find the real next parent */
6571         var current = $[deck]('getSlideIndex', $[deck]('getSlide'));
6572         var nextParent = $[deck]('getToplevelSlideOfIndex', current + 1);
6573         var icur = nextParent.index;
6574         for (; icur < $[deck]('getSlides').length; icur++) {
6575             var cursorParent = $[deck]('getToplevelSlideOfIndex', icur).node;
6576             if (!cursorParent.is(nextParent.node)) {
6577                 $[deck]('go', icur-1);
6578                 break;
6579             }
6580         }
6581         if (icur == $[deck]('getSlides').length) {
6582             $[deck]('go', icur-1);            
6583         }
6584     });
6585     $[deck]('extend', 'previousEndOfTopLevelSlide', function() {
6586         /* Find the current parent and take the previous slide (last of previous top level) */
6587         var current = $[deck]('getSlideIndex', $[deck]('getSlide'));
6588         var currentParent = $[deck]('getToplevelSlideOfIndex', current).index;
6589         if (currentParent > 0) {
6590             $[deck]('go', currentParent - 1);
6591         }
6592     });
6593     $d.bind('deck.init', function() {
6594         $d.unbind('keydown.decknexttoplevel').bind('keydown.decknexttoplevel', function(e) {
6595             var $opts = $[deck]('getOptions');
6596             var key = $opts.keys.nextTopLevel;
6597             if (e.which === key || $.inArray(e.which, key) > -1) {
6598                 e.preventDefault();
6599                 $[deck]('nextTopLevelSlide');
6600             }
6601         });
6602         $d.unbind('keydown.decknextendoftoplevel').bind('keydown.decknextendoftoplevel', function(e) {
6603             var $opts = $[deck]('getOptions');
6604             var key = $opts.keys.nextEndOfTopLevel;
6605             if (e.which === key || $.inArray(e.which, key) > -1) {
6606                 e.preventDefault();
6607                 $[deck]('nextEndOfTopLevelSlide');
6608             }
6609         });
6610         $d.unbind('keydown.deckprevioustoplevel').bind('keydown.deckprevioustoplevel', function(e) {
6611             var $opts = $[deck]('getOptions');
6612             var key = $opts.keys.previousTopLevel;
6613             if (e.which === key || $.inArray(e.which, key) > -1) {
6614                 e.preventDefault();
6615                 $[deck]('previousTopLevelSlide');
6616             }
6617         });
6618         $d.unbind('keydown.deckpreviousendoftoplevel').bind('keydown.deckpreviousendoftoplevel', function(e) {
6619             var $opts = $[deck]('getOptions');
6620             var key = $opts.keys.previousEndOfTopLevel;
6621             if (e.which === key || $.inArray(e.which, key) > -1) {
6622                 e.preventDefault();
6623                 $[deck]('previousEndOfTopLevelSlide');
6624             }
6625         });
6626     });
6627     // When jumping (not steping), we will init the subslides (in case they are animations), in a backward order, and then fast forward necessary animations
6628     var bigJump = function(from, to) {
6629         var direction = "forward";
6630         if (from > to){
6631             direction = "reverse";
6632         }
6633         var opts = $[deck]('getOptions');
6634         $($[deck]('getToplevelSlideOfIndex', to).node.find(opts.selectors.subslidesToNotify).get().reverse()).each(function(ind, el) {$(el).triggerHandler('deck.toplevelBecameCurrent', direction)});
6635         for (icur = $[deck]('getToplevelSlideOfIndex', to).index + 1; icur < to+1; icur++) {
6636             $[deck]('getSlides')[icur].triggerHandler('deck.afterToplevelBecameCurrent', 'forward');
6637         }
6638     }
6639     $d.bind('deck.change', function(e, from, to) {
6640         if (  Math.abs(from - to) > 1 || ! $[deck]('getToplevelSlideOfIndex', to).node.is($[deck]('getToplevelSlideOfIndex', from).node)) {
6641             // consider natural jumps and the case where we actually changed (top level) slide (even with a step)
6642             bigJump(from, to);
6643         }
6644     });
6645 })(jQuery, 'deck');
6646
6647 (function($, deck, undefined) {
6648    $(document).bind('deck.change', function(e, from, to) {
6649       var $prev = $[deck]('getSlide', to-1),
6650       $next = $[deck]('getSlide', to+1),
6651       $oldprev = $[deck]('getSlide', from-1),
6652       $oldnext = $[deck]('getSlide', from+1);
6653       
6654       var direction = "forward";
6655       if(from > to){
6656         direction = "reverse";
6657       }
6658
6659       $[deck]('getSlide', from).triggerHandler('deck.lostCurrent', [direction, from, to]);
6660       $[deck]('getSlide', to).triggerHandler('deck.becameCurrent', [direction, from, to]);
6661
6662       $oldprev && $oldprev.triggerHandler('deck.lostPrevious', [direction, from, to]);
6663       $oldnext && $oldnext.triggerHandler('deck.lostNext', [direction, from, to]);
6664
6665       $prev && $prev.triggerHandler('deck.becamePrevious', [direction, from, to]);
6666       $next && $next.triggerHandler('deck.becameNext', [direction, from, to]);
6667    });
6668 })(jQuery, 'deck');
6669
6670
6671 /*!
6672 Deck JS - deck.anim
6673 Copyright (c) 2012-2014 RĂ©mi Emonet
6674 Licensed under the MIT license.
6675 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6676 */
6677
6678
6679 (function($, deck, undefined) {
6680     // The next two lines are the color plugin from jquery
6681     /*! jQuery Color v@2.1.2 http://github.com/jquery/jquery-color | jquery.org/license */
6682     (function(a,b){function m(a,b,c){var d=h[b.type]||{};return a==null?c||!b.def?null:b.def:(a=d.floor?~~a:parseFloat(a),isNaN(a)?b.def:d.mod?(a+d.mod)%d.mod:0>a?0:d.max<a?d.max:a)}function n(b){var c=f(),d=c._rgba=[];return b=b.toLowerCase(),l(e,function(a,e){var f,h=e.re.exec(b),i=h&&e.parse(h),j=e.space||"rgba";if(i)return f=c[j](i),c[g[j].cache]=f[g[j].cache],d=c._rgba=f._rgba,!1}),d.length?(d.join()==="0,0,0,0"&&a.extend(d,k.transparent),c):k[b]}function o(a,b,c){return c=(c+1)%1,c*6<1?a+(b-a)*c*6:c*2<1?b:c*3<2?a+(b-a)*(2/3-c)*6:a}var c="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",d=/^([\-+])=\s*(\d+\.?\d*)/,e=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(a){return[a[1],a[2],a[3],a[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(a){return[a[1]*2.55,a[2]*2.55,a[3]*2.55,a[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(a){return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(a){return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(a){return[a[1],a[2]/100,a[3]/100,a[4]]}}],f=a.Color=function(b,c,d,e){return new a.Color.fn.parse(b,c,d,e)},g={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},h={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},i=f.support={},j=a("<p>")[0],k,l=a.each;j.style.cssText="background-color:rgba(1,1,1,.5)",i.rgba=j.style.backgroundColor.indexOf("rgba")>-1,l(g,function(a,b){b.cache="_"+a,b.props.alpha={idx:3,type:"percent",def:1}}),f.fn=a.extend(f.prototype,{parse:function(c,d,e,h){if(c===b)return this._rgba=[null,null,null,null],this;if(c.jquery||c.nodeType)c=a(c).css(d),d=b;var i=this,j=a.type(c),o=this._rgba=[];d!==b&&(c=[c,d,e,h],j="array");if(j==="string")return this.parse(n(c)||k._default);if(j==="array")return l(g.rgba.props,function(a,b){o[b.idx]=m(c[b.idx],b)}),this;if(j==="object")return c instanceof f?l(g,function(a,b){c[b.cache]&&(i[b.cache]=c[b.cache].slice())}):l(g,function(b,d){var e=d.cache;l(d.props,function(a,b){if(!i[e]&&d.to){if(a==="alpha"||c[a]==null)return;i[e]=d.to(i._rgba)}i[e][b.idx]=m(c[a],b,!0)}),i[e]&&a.inArray(null,i[e].slice(0,3))<0&&(i[e][3]=1,d.from&&(i._rgba=d.from(i[e])))}),this},is:function(a){var b=f(a),c=!0,d=this;return l(g,function(a,e){var f,g=b[e.cache];return g&&(f=d[e.cache]||e.to&&e.to(d._rgba)||[],l(e.props,function(a,b){if(g[b.idx]!=null)return c=g[b.idx]===f[b.idx],c})),c}),c},_space:function(){var a=[],b=this;return l(g,function(c,d){b[d.cache]&&a.push(c)}),a.pop()},transition:function(a,b){var c=f(a),d=c._space(),e=g[d],i=this.alpha()===0?f("transparent"):this,j=i[e.cache]||e.to(i._rgba),k=j.slice();return c=c[e.cache],l(e.props,function(a,d){var e=d.idx,f=j[e],g=c[e],i=h[d.type]||{};if(g===null)return;f===null?k[e]=g:(i.mod&&(g-f>i.mod/2?f+=i.mod:f-g>i.mod/2&&(f-=i.mod)),k[e]=m((g-f)*b+f,d))}),this[d](k)},blend:function(b){if(this._rgba[3]===1)return this;var c=this._rgba.slice(),d=c.pop(),e=f(b)._rgba;return f(a.map(c,function(a,b){return(1-d)*e[b]+d*a}))},toRgbaString:function(){var b="rgba(",c=a.map(this._rgba,function(a,b){return a==null?b>2?1:0:a});return c[3]===1&&(c.pop(),b="rgb("),b+c.join()+")"},toHslaString:function(){var b="hsla(",c=a.map(this.hsla(),function(a,b){return a==null&&(a=b>2?1:0),b&&b<3&&(a=Math.round(a*100)+"%"),a});return c[3]===1&&(c.pop(),b="hsl("),b+c.join()+")"},toHexString:function(b){var c=this._rgba.slice(),d=c.pop();return b&&c.push(~~(d*255)),"#"+a.map(c,function(a){return a=(a||0).toString(16),a.length===1?"0"+a:a}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),f.fn.parse.prototype=f.fn,g.hsla.to=function(a){if(a[0]==null||a[1]==null||a[2]==null)return[null,null,null,a[3]];var b=a[0]/255,c=a[1]/255,d=a[2]/255,e=a[3],f=Math.max(b,c,d),g=Math.min(b,c,d),h=f-g,i=f+g,j=i*.5,k,l;return g===f?k=0:b===f?k=60*(c-d)/h+360:c===f?k=60*(d-b)/h+120:k=60*(b-c)/h+240,h===0?l=0:j<=.5?l=h/i:l=h/(2-i),[Math.round(k)%360,l,j,e==null?1:e]},g.hsla.from=function(a){if(a[0]==null||a[1]==null||a[2]==null)return[null,null,null,a[3]];var b=a[0]/360,c=a[1],d=a[2],e=a[3],f=d<=.5?d*(1+c):d+c-d*c,g=2*d-f;return[Math.round(o(g,f,b+1/3)*255),Math.round(o(g,f,b)*255),Math.round(o(g,f,b-1/3)*255),e]},l(g,function(c,e){var g=e.props,h=e.cache,i=e.to,j=e.from;f.fn[c]=function(c){i&&!this[h]&&(this[h]=i(this._rgba));if(c===b)return this[h].slice();var d,e=a.type(c),k=e==="array"||e==="object"?c:arguments,n=this[h].slice();return l(g,function(a,b){var c=k[e==="object"?a:b.idx];c==null&&(c=n[b.idx]),n[b.idx]=m(c,b)}),j?(d=f(j(n)),d[h]=n,d):f(n)},l(g,function(b,e){if(f.fn[b])return;f.fn[b]=function(f){var g=a.type(f),h=b==="alpha"?this._hsla?"hsla":"rgba":c,i=this[h](),j=i[e.idx],k;return g==="undefined"?j:(g==="function"&&(f=f.call(this,j),g=a.type(f)),f==null&&e.empty?this:(g==="string"&&(k=d.exec(f),k&&(f=j+parseFloat(k[2])*(k[1]==="+"?1:-1))),i[e.idx]=f,this[h](i)))}})}),f.hook=function(b){var c=b.split(" ");l(c,function(b,c){a.cssHooks[c]={set:function(b,d){var e,g,h="";if(d!=="transparent"&&(a.type(d)!=="string"||(e=n(d)))){d=f(e||d);if(!i.rgba&&d._rgba[3]!==1){g=c==="backgroundColor"?b.parentNode:b;while((h===""||h==="transparent")&&g&&g.style)try{h=a.css(g,"backgroundColor"),g=g.parentNode}catch(j){}d=d.blend(h&&h!=="transparent"?h:"_default")}d=d.toRgbaString()}try{b.style[c]=d}catch(j){}}},a.fx.step[c]=function(b){b.colorInit||(b.start=f(b.elem,c),b.end=f(b.end),b.colorInit=!0),a.cssHooks[c].set(b.elem,b.start.transition(b.end,b.pos))}})},f.hook(c),a.cssHooks.borderColor={expand:function(a){var b={};return l(["Top","Right","Bottom","Left"],function(c,d){b["border"+d+"Color"]=a}),b}},k=a.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}})(jQuery);
6683
6684     var $d = $(document);
6685     var may = function(o,f) {return f ? f.bind(o) : function() {}};
6686
6687     $.extend(true, $[deck].defaults, {
6688         selectors: {
6689             animShow: ".anim-show",
6690             animHide: ".anim-hide",
6691             animAddClass: ".anim-addclass",
6692             animRemoveClass: ".anim-removeclass",
6693             animAttribute: ".anim-attribute",
6694             animWait: ".anim-wait",
6695             // specific ones
6696             animPlay: ".anim-play",
6697             animPause: ".anim-pause",
6698             animViewboxAs: ".anim-viewboxas",
6699             animAlong: ".anim-along",
6700             //
6701             animContinue: ".anim-continue"
6702         },
6703         classes: {
6704             animReady: "deck-anim-ready"
6705         },
6706         anim: {
6707             duration: 400
6708         }
6709     });
6710
6711     var doInit = function() {
6712         // first we define some tools and grab some info from deck.js
6713         var o = $[deck]('getOptions');
6714         var context = function(el) {
6715             return {
6716                 what: function() {return $(el).attr("data-what")},
6717                 dur: function() {return $(el).attr("data-dur")*1 || o.anim.duration},
6718                 delay: function() {return $(el).attr("data-delay")*1 || 0},
6719                 classs: function() {return $(el).attr("data-class")},
6720                 attribute: function() {return $(el).attr("data-attr").split(':')[0]},
6721                 as: function() {return $(el).attr("data-as")},
6722                 path: function() {return $(el).attr("data-path")},
6723                 reverse: function() {var r = $(el).attr("data-reverse"); return r && r.toUpperCase() == "TRUE";},
6724                 value: function() {return $(el).attr("data-attr").split(':')[1]},
6725                 toplevel: function() {return $[deck]('getToplevelSlideOf', el).node},
6726                 all: function() {return $(this.what(),this.toplevel())}
6727             }
6728         };
6729         var globalHasAnimContinue = false;
6730         var classical = function(selector, methods) {
6731             $(selector).each(function(i, el) {
6732                 var c = context(el);
6733                 may(methods, methods.create)(c);
6734                 $(el).bind('deck.toplevelBecameCurrent', function(_, direction) {
6735                     may(methods, methods.init)(c);
6736                 }).bind('deck.afterToplevelBecameCurrent', function(_, direction) {
6737                     may(methods, methods.fast)(c);
6738                 }).bind('deck.lostCurrent', function(_, direction, from, to) {
6739                     if (direction == 'forward' || Math.abs(from - to)>1 ) return; // if a big step, let the "step" extension do its job
6740                     may(methods, methods.undo)(c);
6741                 }).bind('deck.becameCurrent', function(_, direction, from, to) {
6742                     if (direction == 'reverse' || Math.abs(from - to)>1 ) return; // if a big step, let the "step" extension do its job
6743                     if (c.delay()>0) {
6744                         setTimeout(function() {
6745                             may(methods, methods.doit)(c);
6746                         }, c.delay());
6747                     } else {
6748                         may(methods, methods.doit)(c);
6749                     }
6750                 });
6751             });
6752         };
6753         
6754         // here come the real animations
6755         classical(o.selectors.animShow, {
6756             init: function(c) {c.all().animate({'opacity': 0.}, 0)},
6757             undo: function(c) {c.all().animate({'opacity': 0.}, c.dur()/100)},
6758             doit: function(c) {c.all().animate({'opacity': 1.}, c.dur())},
6759             fast: function(c) {c.all().animate({'opacity': 1.}, 0)}
6760         });
6761         classical(o.selectors.animHide, {
6762             init: function(c) {c.all().animate({'opacity': 1.}, 0)},
6763             undo: function(c) {c.all().animate({'opacity': 1.}, c.dur()/100)},
6764             doit: function(c) {c.all().animate({'opacity': 0.}, c.dur())},
6765             fast: function(c) {c.all().animate({'opacity': 0.}, 0)}
6766         });
6767         classical(o.selectors.animAddClass, {
6768             init: function(c) {c.all().each(function() { this.classList.remove(c.classs()) })},
6769             undo: function(c) {c.all().each(function() { this.classList.remove(c.classs()) })},
6770             doit: function(c) {c.all().each(function() { this.classList.add(c.classs()) })},
6771             fast: function(c) {c.all().each(function() { this.classList.add(c.classs()) })} 
6772         });
6773         classical(o.selectors.animRemoveClass, {
6774             init: function(c) {c.all().each(function() { this.classList.add(c.classs()) })},
6775             undo: function(c) {c.all().each(function() { this.classList.add(c.classs()) })},
6776             doit: function(c) {c.all().each(function() { this.classList.remove(c.classs()) })},
6777             fast: function(c) {c.all().each(function() { this.classList.remove(c.classs()) })} 
6778         });
6779         function svgRealAttrName(a) {
6780             if (startsWith(a, "svg")) {
6781                 return REST.substr(0, 1).toLowerCase() + REST.slice(1);
6782             }
6783             return null;
6784         }
6785         function startsWith(longStr, part) {
6786             var res = longStr.substr(0, part.length) == part;
6787             REST = res ? longStr.slice(part.length) : null;
6788             return res;
6789         }
6790         classical(o.selectors.animAttribute, {
6791             init: function(c) {
6792                 this.undo(c);
6793             },
6794             undo: function(c) {
6795                 // TODO: [feature] could allow multiple attributes to be passed and animated simultaneously
6796                 var k = c.attribute()
6797                 for (i in c.previousElement) { // use the saved list of elements and values
6798                     var whatTo = {};
6799                     whatTo[k] = c.previousCss[i];
6800                     $(c.previousElement[i]).finish();
6801                     if (c.previousElement[i] instanceof SVGElement) {
6802                         if (whatTo[k] != null) {
6803                             var realAttrName = svgRealAttrName(k) || k;
6804                             c.previousElement[i].attributes.getNamedItem(realAttrName).value = whatTo[k];
6805                         } else {
6806                             var realAttrName = svgRealAttrName(k) || k;
6807                             c.previousElement[i].attributes.removeNamedItem(realAttrName);
6808                         }
6809                     } else {
6810                         $(c.previousElement[i]).animate(whatTo, 0);
6811                     }
6812                 }
6813             },
6814             doit: function(c, factor) {
6815                 if (factor === undefined) factor = 1
6816                 c.all().each( function() {
6817                     // finish all previous animations
6818                     if (!globalHasAnimContinue && $(this).queue().length) {
6819                         $(this).finish();
6820                     }
6821                 });
6822                 var k = c.attribute()
6823                 c.previousCss = []
6824                 c.previousElement = []
6825                 c.all().each( function(){
6826                     c.previousElement.push(this);
6827                     var v = $(this).css(k);
6828                     if (v == null && this instanceof SVGElement) {
6829                         var realAttrName = svgRealAttrName(k) || k;
6830                         var attr = this.attributes.getNamedItem(realAttrName);
6831                         c.previousCss.push(attr ? attr.value : null);
6832                     } else {
6833                         c.previousCss.push(v);
6834                     }
6835                 }); // save a list of elements and values
6836                 var whatTo = {}
6837                 whatTo[c.attribute()] = c.value()
6838                 c.all().animate(whatTo, c.dur()*factor)
6839             },
6840             fast: function(c) {this.doit(c,0)}
6841         });
6842         classical(o.selectors.animViewboxAs, {
6843             create: function(c) {
6844                 c.attribute = function() {return "svgViewBox"};
6845                 c.value = function() {
6846                     var asWhat = $(c.as());
6847                     var a = function (i) {return asWhat.attr(i)}
6848                     var toViewBox = a('x')+" "+a('y')+" "+a('width')+" "+a('height');
6849                     return toViewBox;
6850                 };
6851             },
6852             init: function(c) {this.undo(c)},
6853             undo: function(c) {
6854                 var k = c.attribute()
6855                 for (i in c.previousElement) { // use the saved list of elements and values
6856                     var whatTo = {}
6857                     whatTo[k] = c.previousValue[i]
6858                     $(c.previousElement[i]).finish();
6859                     $(c.previousElement[i]).animate(whatTo, 0)
6860                 }
6861             },
6862             doit: function(c, factor) {
6863                 if (factor === undefined) factor = 1
6864                 c.all().each( function() {
6865                     // finish all previous animations
6866                     if (!globalHasAnimContinue && $(this).queue().length) {
6867                         $(this).finish();
6868                     }
6869                 });
6870                 var k = c.attribute()
6871                 c.previousValue = []
6872                 c.previousElement = []
6873                 c.all().each( function() {
6874                     c.previousElement.push(this);
6875                     c.previousValue.push(this.attributes.getNamedItem('viewBox').value);
6876                 }); // save a list of elements and values
6877                 var whatTo = {}
6878                 whatTo[k] = c.value()
6879                 c.all().animate(whatTo, c.dur()*factor)
6880             },
6881             fast: function(c) {this.doit(c,0)}
6882         });
6883         classical(o.selectors.animAlong, {
6884             init: function(c) {this.undo(c)},
6885             undo: function(c) {
6886                 for (i in c.previousElement) { // use the saved list of elements and values
6887                     var prev = c.previousValue[i];
6888                     $(c.previousElement[i]).finish();
6889                     $(c.previousElement[i]).attr("transform", prev);
6890                 }
6891             },
6892             doit: function(c, factor) {
6893                 if (factor === undefined) factor = 1;
6894                 c.all().each( function() {
6895                     // finish all previous animations
6896                     if (!globalHasAnimContinue && $(this).queue().length) {
6897                         $(this).finish();
6898                     }
6899                 });
6900                 var path = $(c.path()).get(0);
6901                 var rev = c.reverse();
6902                 var len = path.getTotalLength()
6903                 var s = path.getPointAtLength(rev?len:0);
6904                 c.previousValue = [];
6905                 c.previousElement = [];
6906                 c.all().each( function() {
6907                     var base = "";
6908                     if ($(this).attr("transform") != null) {
6909                         base = $(this).attr("transform"); // TODO maybe can use attr also above (anim-attr)
6910                         c.previousValue.push(base);
6911                     } else {
6912                         c.previousValue.push(null);
6913                     }
6914                     c.previousElement.push(this);
6915                     $(this).css({svgDeckAnim: 0.});
6916                     $(this).animate({svgDeckAnim: 1.}, {
6917                         duration: c.dur()*factor,
6918                         step: function(v) {
6919                             if (rev) v = 1-v;
6920                             var p = path.getPointAtLength(v * len);
6921                             $(this).attr("transform", 'translate('+(p.x-s.x)+','+(p.y-s.y)+')' + base);
6922                         }
6923                     });
6924                 });
6925             },
6926             fast: function(c) {this.doit(c, 0);}
6927         });
6928         classical(o.selectors.animPlay, {
6929             init: function(c) {c.all().each(function(){this.pause(); try{this.currentTime=0}catch(e){} })},
6930             undo: function(c) {c.all().each(function(){this.pause()})},
6931             doit: function(c) {c.all().each(function(){this.play()})},
6932             fast: function(c) {c.all().each(function(){this.play()})}
6933         });
6934         classical(o.selectors.animPause, {
6935             undo: function(c) {c.all().each(function(){this.play()})},
6936             doit: function(c) {c.all().each(function(){this.pause()})},
6937             fast: function(c) {c.all().each(function(){this.pause()})}
6938         });
6939         classical(o.selectors.animContinue, {
6940             doit: function(c) {setTimeout(function(){ globalHasAnimContinue = true; $[deck]('next') ; globalHasAnimContinue = false; }, 1)}
6941             // do not do it in fast mode
6942         });
6943         classical(o.selectors.animWait, {
6944             doit: function(c) {setTimeout(function(){ globalHasAnimContinue = true; $[deck]('next') ; globalHasAnimContinue = false; }, c.dur())}
6945         });
6946         // handle the chained undo for "anim-continue"
6947         $(o.selectors.animContinue + "," + o.selectors.animWait).each(function(i, curSlide) {
6948             $(curSlide).bind('deck.becameCurrent', function(_, direction) {
6949                 if (direction == 'forward') return;
6950                 setTimeout(function(){$[deck]('prev')}, 1)
6951             });
6952
6953         });
6954
6955         // finally force "refresh" (notification of slide change)
6956         var current = $[deck]('getSlide')
6957         var icur = 0
6958         for (; icur < $[deck]('getSlides').length; icur++) {
6959             if ($[deck]('getSlides')[icur] == current) break;                
6960         }
6961         $d.trigger("deck.change", [icur, 0]);
6962         $d.trigger("deck.change", [0, icur]);
6963
6964         var container = $[deck]('getContainer');
6965         $(container).addClass(o.classes.animReady)
6966     }
6967     $(document).bind('deck.init', function() {
6968         doInit();
6969     });
6970         
6971 })(jQuery, 'deck');
6972
6973
6974 (function(e){function d(){this._settings=[];this._extensions=[];this.regional=[];this.regional[""]={errorLoadingText:"Error loading",notSupportedText:"This browser does not support SVG"};this.local=this.regional[""];this._uuid=new Date().getTime();this._renesis=c("RenesisX.RenesisCtrl")}function c(i){try{return !!(window.ActiveXObject&&new ActiveXObject(i))}catch(j){return false}}var g="svgwrapper";e.extend(d.prototype,{markerClassName:"hasSVG",svgNS:"http://www.w3.org/2000/svg",xlinkNS:"http://www.w3.org/1999/xlink",_wrapperClass:b,_attrNames:{class_:"class",in_:"in",alignmentBaseline:"alignment-baseline",baselineShift:"baseline-shift",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorRendering:"color-rendering",dominantBaseline:"dominant-baseline",enableBackground:"enable-background",fillOpacity:"fill-opacity",fillRule:"fill-rule",floodColor:"flood-color",floodOpacity:"flood-opacity",fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",imageRendering:"image-rendering",letterSpacing:"letter-spacing",lightingColor:"lighting-color",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",strokeDashArray:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeLineCap:"stroke-linecap",strokeLineJoin:"stroke-linejoin",strokeMiterLimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",underlinePosition:"underline-position",underlineThickness:"underline-thickness",vertAdvY:"vert-adv-y",vertOriginY:"vert-origin-y",wordSpacing:"word-spacing",writingMode:"writing-mode"},_attachSVG:function(i,k){var j=(i.namespaceURI==this.svgNS?i:null);var i=(j?null:i);if(e(i||j).hasClass(this.markerClassName)){return}if(typeof k=="string"){k={loadURL:k}}else{if(typeof k=="function"){k={onLoad:k}}}e(i||j).addClass(this.markerClassName);try{if(!j){j=document.createElementNS(this.svgNS,"svg");j.setAttribute("version","1.1");if(i.clientWidth>0){j.setAttribute("width",i.clientWidth)}if(i.clientHeight>0){j.setAttribute("height",i.clientHeight)}i.appendChild(j)}this._afterLoad(i,j,k||{})}catch(l){if(!e.support.noCloneChecked){if(!i.id){i.id="svg"+(this._uuid++)}this._settings[i.id]=k;i.innerHTML='<embed type="image/svg+xml" width="100%" height="100%" src="'+(k.initPath||"")+'blank.svg" pluginspage="http://www.adobe.com/svg/viewer/install/main.html"/>'}else{i.innerHTML='<p class="svg_error">'+this.local.notSupportedText+"</p>"}}},_registerSVG:function(){for(var l=0;l<document.embeds.length;l++){var j=document.embeds[l].parentNode;if(!e(j).hasClass(e.svg.markerClassName)||e.data(j,g)){continue}var k=null;try{k=document.embeds[l].getSVGDocument()}catch(m){setTimeout(e.svg._registerSVG,250);return}k=(k?k.documentElement:null);if(k){e.svg._afterLoad(j,k)}}},_afterLoad:function(i,j,k){var k=k||this._settings[i.id];this._settings[i?i.id:""]=null;var m=new this._wrapperClass(j,i);e.data(i||j,g,m);try{if(k.loadURL){m.load(k.loadURL,k)}if(k.settings){m.configure(k.settings)}if(k.onLoad&&!k.loadURL){k.onLoad.apply(i||j,[m])}}catch(l){alert(l)}},_getSVG:function(i){i=(typeof i=="string"?e(i)[0]:(i.jquery?i[0]:i));return e.data(i,g)},_destroySVG:function(i){var j=e(i);if(!j.hasClass(this.markerClassName)){return}j.removeClass(this.markerClassName);if(i.namespaceURI!=this.svgNS){j.empty()}e.removeData(i,g)},addExtension:function(j,i){this._extensions.push([j,i])},isSVGElem:function(i){return(i.nodeType==1&&i.namespaceURI==e.svg.svgNS)}});function b(k,j){this._svg=k;this._container=j;for(var l=0;l<e.svg._extensions.length;l++){var m=e.svg._extensions[l];this[m[0]]=new m[1](this)}}e.extend(b.prototype,{_width:function(){return(this._container?this._container.clientWidth:this._svg.width)},_height:function(){return(this._container?this._container.clientHeight:this._svg.height)},root:function(){return this._svg},configure:function(o,n,k){if(!o.nodeName){k=n;n=o;o=this._svg}if(k){for(var m=o.attributes.length-1;m>=0;m--){var j=o.attributes.item(m);if(!(j.nodeName=="onload"||j.nodeName=="version"||j.nodeName.substring(0,5)=="xmlns")){o.attributes.removeNamedItem(j.nodeName)}}}for(var l in n){o.setAttribute(e.svg._attrNames[l]||l,n[l])}return this},getElementById:function(i){return this._svg.ownerDocument.getElementById(i)},change:function(j,k){if(j){for(var i in k){if(k[i]==null){j.removeAttribute(e.svg._attrNames[i]||i)}else{j.setAttribute(e.svg._attrNames[i]||i,k[i])}}}return this},_args:function(k,n,j){n.splice(0,0,"parent");n.splice(n.length,0,"settings");var l={};var o=0;if(k[0]!=null&&k[0].jquery){k[0]=k[0][0]}if(k[0]!=null&&!(typeof k[0]=="object"&&k[0].nodeName)){l.parent=null;o=1}for(var m=0;m<k.length;m++){l[n[m+o]]=k[m]}if(j){e.each(j,function(p,q){if(typeof l[q]=="object"){l.settings=l[q];l[q]=null}})}return l},title:function(k,m,j){var i=this._args(arguments,["text"]);var l=this._makeNode(i.parent,"title",i.settings||{});l.appendChild(this._svg.ownerDocument.createTextNode(i.text));return l},describe:function(k,m,j){var i=this._args(arguments,["text"]);var l=this._makeNode(i.parent,"desc",i.settings||{});l.appendChild(this._svg.ownerDocument.createTextNode(i.text));return l},defs:function(k,l,j){var i=this._args(arguments,["id"],["id"]);return this._makeNode(i.parent,"defs",e.extend((i.id?{id:i.id}:{}),i.settings||{}))},symbol:function(o,p,k,n,m,i,l){var j=this._args(arguments,["id","x1","y1","width","height"]);return this._makeNode(j.parent,"symbol",e.extend({id:j.id,viewBox:j.x1+" "+j.y1+" "+j.width+" "+j.height},j.settings||{}))},marker:function(o,i,q,p,l,j,m,k){var n=this._args(arguments,["id","refX","refY","mWidth","mHeight","orient"],["orient"]);return this._makeNode(n.parent,"marker",e.extend({id:n.id,refX:n.refX,refY:n.refY,markerWidth:n.mWidth,markerHeight:n.mHeight,orient:n.orient||"auto"},n.settings||{}))},style:function(k,m,j){var i=this._args(arguments,["styles"]);var l=this._makeNode(i.parent,"style",e.extend({type:"text/css"},i.settings||{}));l.appendChild(this._svg.ownerDocument.createTextNode(i.styles));return l},script:function(m,i,l,k){var j=this._args(arguments,["script","type"],["type"]);var n=this._makeNode(j.parent,"script",e.extend({type:j.type||"text/javascript"},j.settings||{}));n.appendChild(this._svg.ownerDocument.createTextNode(j.script));return n},linearGradient:function(q,j,r,k,p,i,o,l){var n=this._args(arguments,["id","stops","x1","y1","x2","y2"],["x1"]);var m=e.extend({id:n.id},(n.x1!=null?{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2}:{}));return this._gradient(n.parent,"linearGradient",e.extend(m,n.settings||{}),n.stops)},radialGradient:function(s,j,t,o,m,i,n,k,l){var q=this._args(arguments,["id","stops","cx","cy","r","fx","fy"],["cx"]);var p=e.extend({id:q.id},(q.cx!=null?{cx:q.cx,cy:q.cy,r:q.r,fx:q.fx,fy:q.fy}:{}));return this._gradient(q.parent,"radialGradient",e.extend(p,q.settings||{}),q.stops)},_gradient:function(n,j,m,p){var o=this._makeNode(n,j,m);for(var l=0;l<p.length;l++){var k=p[l];this._makeNode(o,"stop",e.extend({offset:k[0],stopColor:k[1]},(k[2]!=null?{stopOpacity:k[2]}:{})))}return o},pattern:function(s,i,r,p,j,t,q,o,l,u,k){var n=this._args(arguments,["id","x","y","width","height","vx","vy","vwidth","vheight"],["vx"]);var m=e.extend({id:n.id,x:n.x,y:n.y,width:n.width,height:n.height},(n.vx!=null?{viewBox:n.vx+" "+n.vy+" "+n.vwidth+" "+n.vheight}:{}));return this._makeNode(n.parent,"pattern",e.extend(m,n.settings||{}))},clipPath:function(l,m,i,k){var j=this._args(arguments,["id","units"]);j.units=j.units||"userSpaceOnUse";return this._makeNode(j.parent,"clipPath",e.extend({id:j.id,clipPathUnits:j.units},j.settings||{}))},mask:function(n,p,j,o,m,i,l){var k=this._args(arguments,["id","x","y","width","height"]);return this._makeNode(k.parent,"mask",e.extend({id:k.id,x:k.x,y:k.y,width:k.width,height:k.height},k.settings||{}))},createPath:function(){return new f()},createText:function(){return new h()},svg:function(r,q,o,i,s,p,n,k,t,j){var m=this._args(arguments,["x","y","width","height","vx","vy","vwidth","vheight"],["vx"]);var l=e.extend({x:m.x,y:m.y,width:m.width,height:m.height},(m.vx!=null?{viewBox:m.vx+" "+m.vy+" "+m.vwidth+" "+m.vheight}:{}));return this._makeNode(m.parent,"svg",e.extend(l,m.settings||{}))},group:function(k,l,j){var i=this._args(arguments,["id"],["id"]);return this._makeNode(i.parent,"g",e.extend({id:i.id},i.settings||{}))},use:function(p,o,n,i,q,j,l){var m=this._args(arguments,["x","y","width","height","ref"]);if(typeof m.x=="string"){m.ref=m.x;m.settings=m.y;m.x=m.y=m.width=m.height=null}var k=this._makeNode(m.parent,"use",e.extend({x:m.x,y:m.y,width:m.width,height:m.height},m.settings||{}));k.setAttributeNS(e.svg.xlinkNS,"href",m.ref);return k},link:function(k,m,j){var i=this._args(arguments,["ref"]);var l=this._makeNode(i.parent,"a",i.settings);l.setAttributeNS(e.svg.xlinkNS,"href",i.ref);return l},image:function(p,o,n,i,q,j,l){var m=this._args(arguments,["x","y","width","height","ref"]);var k=this._makeNode(m.parent,"image",e.extend({x:m.x,y:m.y,width:m.width,height:m.height},m.settings||{}));k.setAttributeNS(e.svg.xlinkNS,"href",m.ref);return k},path:function(k,l,j){var i=this._args(arguments,["path"]);return this._makeNode(i.parent,"path",e.extend({d:(i.path.path?i.path.path():i.path)},i.settings||{}))},rect:function(p,o,n,k,q,j,i,l){var m=this._args(arguments,["x","y","width","height","rx","ry"],["rx"]);return this._makeNode(m.parent,"rect",e.extend({x:m.x,y:m.y,width:m.width,height:m.height},(m.rx?{rx:m.rx,ry:m.ry}:{}),m.settings||{}))},circle:function(l,i,n,m,k){var j=this._args(arguments,["cx","cy","r"]);return this._makeNode(j.parent,"circle",e.extend({cx:j.cx,cy:j.cy,r:j.r},j.settings||{}))},ellipse:function(l,i,o,n,m,k){var j=this._args(arguments,["cx","cy","rx","ry"]);return this._makeNode(j.parent,"ellipse",e.extend({cx:j.cx,cy:j.cy,rx:j.rx,ry:j.ry},j.settings||{}))},line:function(o,k,n,i,l,m){var j=this._args(arguments,["x1","y1","x2","y2"]);return this._makeNode(j.parent,"line",e.extend({x1:j.x1,y1:j.y1,x2:j.x2,y2:j.y2},j.settings||{}))},polyline:function(l,k,j){var i=this._args(arguments,["points"]);return this._poly(i.parent,"polyline",i.points,i.settings)},polygon:function(l,k,j){var i=this._args(arguments,["points"]);return this._poly(i.parent,"polygon",i.points,i.settings)},_poly:function(n,j,m,l){var o="";for(var k=0;k<m.length;k++){o+=m[k].join()+" "}return this._makeNode(n,j,e.extend({points:e.trim(o)},l||{}))},text:function(l,i,n,m,k){var j=this._args(arguments,["x","y","value"]);if(typeof j.x=="string"&&arguments.length<4){j.value=j.x;j.settings=j.y;j.x=j.y=null}return this._text(j.parent,"text",j.value,e.extend({x:(j.x&&a(j.x)?j.x.join(" "):j.x),y:(j.y&&a(j.y)?j.y.join(" "):j.y)},j.settings||{}))},textpath:function(k,n,m,j){var i=this._args(arguments,["path","value"]);var l=this._text(i.parent,"textPath",i.value,i.settings||{});l.setAttributeNS(e.svg.xlinkNS,"href",i.path);return l},_text:function(r,j,q,n){var m=this._makeNode(r,j,n);if(typeof q=="string"){m.appendChild(m.ownerDocument.createTextNode(q))}else{for(var o=0;o<q._parts.length;o++){var l=q._parts[o];if(l[0]=="tspan"){var k=this._makeNode(m,l[0],l[2]);k.appendChild(m.ownerDocument.createTextNode(l[1]));m.appendChild(k)}else{if(l[0]=="tref"){var k=this._makeNode(m,l[0],l[2]);k.setAttributeNS(e.svg.xlinkNS,"href",l[1]);m.appendChild(k)}else{if(l[0]=="textpath"){var p=e.extend({},l[2]);p.href=null;var k=this._makeNode(m,l[0],p);k.setAttributeNS(e.svg.xlinkNS,"href",l[2].href);k.appendChild(m.ownerDocument.createTextNode(l[1]));m.appendChild(k)}else{m.appendChild(m.ownerDocument.createTextNode(l[1]))}}}}}return m},other:function(l,j,k){var i=this._args(arguments,["name"]);return this._makeNode(i.parent,i.name,i.settings||{})},_makeNode:function(k,i,j){k=k||this._svg;var l=this._svg.ownerDocument.createElementNS(e.svg.svgNS,i);for(var i in j){var m=j[i];if(m!=null&&m!=null&&(typeof m!="string"||m!="")){l.setAttribute(e.svg._attrNames[i]||i,m)}}k.appendChild(l);return l},add:function(k,l){var j=this._args((arguments.length==1?[null,k]:arguments),["node"]);var i=this;j.parent=j.parent||this._svg;j.node=(j.node.jquery?j.node:e(j.node));try{if(e.svg._renesis){throw"Force traversal"}j.parent.appendChild(j.node.cloneNode(true))}catch(m){j.node.each(function(){var n=i._cloneAsSVG(this);if(n){j.parent.appendChild(n)}})}return this},clone:function(l,m){var i=this;var k=this._args((arguments.length==1?[null,l]:arguments),["node"]);k.parent=k.parent||this._svg;k.node=(k.node.jquery?k.node:e(k.node));var j=[];k.node.each(function(){var n=i._cloneAsSVG(this);if(n){n.id="";k.parent.appendChild(n);j.push(n)}});return j},_cloneAsSVG:function(m){var l=null;if(m.nodeType==1){l=this._svg.ownerDocument.createElementNS(e.svg.svgNS,this._checkName(m.nodeName));for(var k=0;k<m.attributes.length;k++){var j=m.attributes.item(k);if(j.nodeName!="xmlns"&&j.nodeValue){if(j.prefix=="xlink"){l.setAttributeNS(e.svg.xlinkNS,j.localName||j.baseName,j.nodeValue)}else{l.setAttribute(this._checkName(j.nodeName),j.nodeValue)}}}for(var k=0;k<m.childNodes.length;k++){var o=this._cloneAsSVG(m.childNodes[k]);if(o){l.appendChild(o)}}}else{if(m.nodeType==3){if(e.trim(m.nodeValue)){l=this._svg.ownerDocument.createTextNode(m.nodeValue)}}else{if(m.nodeType==4){if(e.trim(m.nodeValue)){try{l=this._svg.ownerDocument.createCDATASection(m.nodeValue)}catch(n){l=this._svg.ownerDocument.createTextNode(m.nodeValue.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"))}}}}}return l},_checkName:function(i){i=(i.substring(0,1)>="A"&&i.substring(0,1)<="Z"?i.toLowerCase():i);return(i.substring(0,4)=="svg:"?i.substring(4):i)},load:function(i,l){l=(typeof l=="boolean"?{addTo:l}:(typeof l=="function"?{onLoad:l}:(typeof l=="string"?{parent:l}:(typeof l=="object"&&l.nodeName?{parent:l}:(typeof l=="object"&&l.jquery?{parent:l}:l||{})))));if(!l.parent&&!l.addTo){this.clear(false)}var j=[this._svg.getAttribute("width"),this._svg.getAttribute("height")];var o=this;var n=function(p){p=e.svg.local.errorLoadingText+": "+p;if(l.onLoad){l.onLoad.apply(o._container||o._svg,[o,p])}else{o.text(null,10,20,p)}};var m=function(q){var p=new ActiveXObject("Microsoft.XMLDOM");p.validateOnParse=false;p.resolveExternals=false;p.async=false;p.loadXML(q);if(p.parseError.errorCode!=0){n(p.parseError.reason);return null}return p};var k=function(s){if(!s){return}if(s.documentElement.nodeName!="svg"){var z=s.getElementsByTagName("parsererror");var r=(z.length?z[0].getElementsByTagName("div"):[]);n(!z.length?"???":(r.length?r[0]:z[0]).firstChild.nodeValue);return}if(!l.forceKeepRelativePath&&i.search(/\//)!=-1){var q=i.replace(/\/[^\/]*$/,"/");e("*[xlink\\:href]",s.documentElement).each(function(C,D){var w=e(D).attr("xlink:href")+"";if(!w.match(/(^[a-z]([-a-z0-9+.])*:.*$)|(^\/.*$)/i)&&w[0]!="#"){e(D).attr("xlink:href",q+e(D).attr("xlink:href"))}})}var A=(l.parent?e(l.parent)[0]:o._svg);var B={};for(var t=0;t<s.documentElement.attributes.length;t++){var x=s.documentElement.attributes.item(t);if(!(x.nodeName=="version"||x.nodeName.substring(0,5)=="xmlns")){B[x.nodeName]=x.nodeValue}}o.configure(A,B,!l.parent);var p=s.documentElement.childNodes;for(var t=0;t<p.length;t++){try{if(e.svg._renesis){throw"Force traversal"}A.appendChild(o._svg.ownerDocument.importNode(p[t],true));if(p[t].nodeName=="script"){e.globalEval(p[t].textContent)}}catch(v){o.add(A,p[t])}}if(!l.changeSize){o.configure(A,{width:j[0],height:j[1]})}if(l.onLoad){var y=s.documentElement.getAttribute("width");var u=s.documentElement.getAttribute("height");l.onLoad.apply(o._container||o._svg,[o,y,u])}};if(i.match("<svg")){k(!e.support.noCloneChecked?m(i):new DOMParser().parseFromString(i,"text/xml"))}else{e.ajax({url:i,dataType:(!e.support.noCloneChecked?"text":"xml"),success:function(p){k(!e.support.noCloneChecked?m(p):p)},error:function(q,r,p){n(r+(p?" "+p.message:""))}})}return this},remove:function(i){i=(i.jquery?i[0]:i);i.parentNode.removeChild(i);return this},clear:function(i){if(i){this.configure({},true)}while(this._svg.firstChild){this._svg.removeChild(this._svg.firstChild)}return this},toSVG:function(i){i=i||this._svg;return(typeof XMLSerializer=="undefined"?this._toSVG(i):new XMLSerializer().serializeToString(i))},_toSVG:function(m){var l="";if(!m){return l}if(m.nodeType==3){l=m.nodeValue}else{if(m.nodeType==4){l="<![CDATA["+m.nodeValue+"]]>"}else{l="<"+m.nodeName;if(m.attributes){for(var k=0;k<m.attributes.length;k++){var j=m.attributes.item(k);if(!(e.trim(j.nodeValue)==""||j.nodeValue.match(/^\[object/)||j.nodeValue.match(/^function/))){l+=" "+(j.namespaceURI==e.svg.xlinkNS?"xlink:":"")+j.nodeName+'="'+j.nodeValue+'"'}}}if(m.firstChild){l+=">";var n=m.firstChild;while(n){l+=this._toSVG(n);n=n.nextSibling}l+="</"+m.nodeName+">"}else{l+="/>"}}}return l}});function f(){this._path=""}e.extend(f.prototype,{reset:function(){this._path="";return this},move:function(i,k,j){j=(a(i)?k:j);return this._coords((j?"m":"M"),i,k)},line:function(i,k,j){j=(a(i)?k:j);return this._coords((j?"l":"L"),i,k)},horiz:function(i,j){this._path+=(j?"h":"H")+(a(i)?i.join(" "):i);return this},vert:function(j,i){this._path+=(i?"v":"V")+(a(j)?j.join(" "):j);return this},curveC:function(k,m,j,l,i,o,n){n=(a(k)?m:n);return this._coords((n?"c":"C"),k,m,j,l,i,o)},smoothC:function(j,k,i,m,l){l=(a(j)?k:l);return this._coords((l?"s":"S"),j,k,i,m)},curveQ:function(j,k,i,m,l){l=(a(j)?k:l);return this._coords((l?"q":"Q"),j,k,i,m)},smoothQ:function(i,k,j){j=(a(i)?k:j);return this._coords((j?"t":"T"),i,k)},_coords:function(m,l,r,k,q,j,p){if(a(l)){for(var n=0;n<l.length;n++){var o=l[n];this._path+=(n==0?m:" ")+o[0]+","+o[1]+(o.length<4?"":" "+o[2]+","+o[3]+(o.length<6?"":" "+o[4]+","+o[5]))}}else{this._path+=m+l+","+r+(k==null?"":" "+k+","+q+(j==null?"":" "+j+","+p))}return this},arc:function(m,j,p,s,l,r,q,k){k=(a(m)?j:k);this._path+=(k?"a":"A");if(a(m)){for(var n=0;n<m.length;n++){var o=m[n];this._path+=(n==0?"":" ")+o[0]+","+o[1]+" "+o[2]+" "+(o[3]?"1":"0")+","+(o[4]?"1":"0")+" "+o[5]+","+o[6]}}else{this._path+=m+","+j+" "+p+" "+(s?"1":"0")+","+(l?"1":"0")+" "+r+","+q}return this},close:function(){this._path+="z";return this},path:function(){return this._path}});f.prototype.moveTo=f.prototype.move;f.prototype.lineTo=f.prototype.line;f.prototype.horizTo=f.prototype.horiz;f.prototype.vertTo=f.prototype.vert;f.prototype.curveCTo=f.prototype.curveC;f.prototype.smoothCTo=f.prototype.smoothC;f.prototype.curveQTo=f.prototype.curveQ;f.prototype.smoothQTo=f.prototype.smoothQ;f.prototype.arcTo=f.prototype.arc;function h(){this._parts=[]}e.extend(h.prototype,{reset:function(){this._parts=[];return this},string:function(i){this._parts[this._parts.length]=["text",i];return this},span:function(j,i){this._parts[this._parts.length]=["tspan",j,i];return this},ref:function(j,i){this._parts[this._parts.length]=["tref",j,i];return this},path:function(k,j,i){this._parts[this._parts.length]=["textpath",j,e.extend({href:k},i||{})];return this}});e.fn.svg=function(j){var i=Array.prototype.slice.call(arguments,1);if(typeof j=="string"&&j=="get"){return e.svg["_"+j+"SVG"].apply(e.svg,[this[0]].concat(i))}return this.each(function(){if(typeof j=="string"){e.svg["_"+j+"SVG"].apply(e.svg,[this].concat(i))}else{e.svg._attachSVG(this,j||{})}})};function a(i){return(i&&i.constructor==Array)}e.svg=new d()})(jQuery);
6975 (function(a){a.each(["x","y","width","height","rx","ry","cx","cy","r","x1","y1","x2","y2","stroke-width","strokeWidth","opacity","fill-opacity","fillOpacity","stroke-opacity","strokeOpacity","stroke-dashoffset","strokeDashOffset","font-size","fontSize","font-weight","fontWeight","letter-spacing","letterSpacing","word-spacing","wordSpacing"],function(h,g){var f=g.charAt(0).toUpperCase()+g.substr(1);if(a.cssProps){a.cssProps["svg"+f]=a.cssProps["svg-"+g]=g}a.fx.step["svg"+f]=a.fx.step["svg-"+g]=function(k){var j=a.svg._attrNames[g]||g;var i=k.elem.attributes.getNamedItem(j);if(!k.set){k.start=(i?parseFloat(i.value):0);var m="";if(/^[+-]=/.exec(m)){k.end=k.start+parseFloat(m.replace(/=/,""))}a(k.elem).css(j,"");k.set=true}var l=(k.pos*(k.end-k.start)+k.start)+(k.unit=="%"?"%":"");(i?i.value=l:k.elem.setAttribute(j,l))}});a.fx.step.svgStrokeDashArray=a.fx.step["svg-strokeDashArray"]=a.fx.step["svgStroke-dasharray"]=a.fx.step["svg-stroke-dasharray"]=function(j){var g=j.elem.attributes.getNamedItem("stroke-dasharray");if(!j.set){j.start=c(g?g.value:"");var l=j.end;j.end=c(l);if(/^[+-]=/.exec(l)){l=l.split(/[, ]+/);if(l.length%2==1){var f=l.length;for(var h=0;h<f;h++){l.push(l[h])}}for(var h=0;h<l.length;h++){if(/^[+-]=/.exec(l[h])){j.end[h]=j.start[h]+parseFloat(l[h].replace(/=/,""))}}}j.set=true}var k=a.map(j.start,function(o,m){return(j.pos*(j.end[m]-o)+o)}).join(",");(g?g.value=k:j.elem.setAttribute("stroke-dasharray",k))};function c(j){var g=j.split(/[, ]+/);for(var h=0;h<g.length;h++){g[h]=parseFloat(g[h]);if(isNaN(g[h])){g[h]=0}}if(g.length%2==1){var f=g.length;for(var h=0;h<f;h++){g.push(g[h])}}return g}a.fx.step.svgViewBox=a.fx.step["svg-viewBox"]=function(h){var f=h.elem.attributes.getNamedItem("viewBox");if(!h.set){h.start=b(f?f.value:"");var k=h.end;h.end=b(k);if(/^[+-]=/.exec(k)){k=k.split(/[, ]+/);while(k.length<4){k.push("0")}for(var g=0;g<4;g++){if(/^[+-]=/.exec(k[g])){h.end[g]=h.start[g]+parseFloat(k[g].replace(/=/,""))}}}h.set=true}var j=a.map(h.start,function(m,l){return(h.pos*(h.end[l]-m)+m)}).join(" ");(f?f.value=j:h.elem.setAttribute("viewBox",j))};function b(g){var h=g.split(/[, ]+/);for(var f=0;f<h.length;f++){h[f]=parseFloat(h[f]);if(isNaN(h[f])){h[f]=0}}while(h.length<4){h.push(0)}return h}a.fx.step.svgTransform=a.fx.step["svg-transform"]=function(m){var f=m.elem.attributes.getNamedItem("transform");if(!m.set){m.start=e(f?f.value:"");m.end=e(m.end,m.start);m.set=true}var k="";for(var l=0;l<m.end.order.length;l++){switch(m.end.order.charAt(l)){case"t":k+=" translate("+(m.pos*(m.end.translateX-m.start.translateX)+m.start.translateX)+","+(m.pos*(m.end.translateY-m.start.translateY)+m.start.translateY)+")";break;case"s":k+=" scale("+(m.pos*(m.end.scaleX-m.start.scaleX)+m.start.scaleX)+","+(m.pos*(m.end.scaleY-m.start.scaleY)+m.start.scaleY)+")";break;case"r":k+=" rotate("+(m.pos*(m.end.rotateA-m.start.rotateA)+m.start.rotateA)+","+(m.pos*(m.end.rotateX-m.start.rotateX)+m.start.rotateX)+","+(m.pos*(m.end.rotateY-m.start.rotateY)+m.start.rotateY)+")";break;case"x":k+=" skewX("+(m.pos*(m.end.skewX-m.start.skewX)+m.start.skewX)+")";case"y":k+=" skewY("+(m.pos*(m.end.skewY-m.start.skewY)+m.start.skewY)+")";break;case"m":var g="";for(var h=0;h<6;h++){g+=","+(m.pos*(m.end.matrix[h]-m.start.matrix[h])+m.start.matrix[h])}k+=" matrix("+g.substr(1)+")";break}}(f?f.value=k:m.elem.setAttribute("transform",k))};function e(j,h){j=j||"";if(typeof j=="object"){j=j.value}var g=a.extend({translateX:0,translateY:0,scaleX:0,scaleY:0,rotateA:0,rotateX:0,rotateY:0,skewX:0,skewY:0,matrix:[0,0,0,0,0,0]},h||{});g.order="";var i=/([a-zA-Z]+)\(\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*)?)?)?\)/g;var f=i.exec(j);while(f){switch(f[1]){case"translate":g.order+="t";g.translateX=parseFloat(f[2]);g.translateY=(f[3]?parseFloat(f[3]):0);break;case"scale":g.order+="s";g.scaleX=parseFloat(f[2]);g.scaleY=(f[3]?parseFloat(f[3]):g.scaleX);break;case"rotate":g.order+="r";g.rotateA=parseFloat(f[2]);g.rotateX=(f[3]?parseFloat(f[3]):0);g.rotateY=(f[4]?parseFloat(f[4]):0);break;case"skewX":g.order+="x";g.skewX=parseFloat(f[2]);break;case"skewY":g.order+="y";g.skewY=parseFloat(f[2]);break;case"matrix":g.order+="m";g.matrix=[parseFloat(f[2]),parseFloat(f[3]),parseFloat(f[4]),parseFloat(f[5]),parseFloat(f[6]),parseFloat(f[7])];break}f=i.exec(j)}if(g.order=="m"&&Math.abs(g.matrix[0])==Math.abs(g.matrix[3])&&g.matrix[1]!=0&&Math.abs(g.matrix[1])==Math.abs(g.matrix[2])){var k=Math.acos(g.matrix[0])*180/Math.PI;k=(g.matrix[1]<0?360-k:k);g.order="rt";g.rotateA=k;g.rotateX=g.rotateY=0;g.translateX=g.matrix[4];g.translateY=g.matrix[5]}return g}a.each(["fill","stroke"],function(h,g){var f=g.charAt(0).toUpperCase()+g.substr(1);a.fx.step["svg"+f]=a.fx.step["svg-"+g]=function(k){if(!k.set){k.start=a.svg._getColour(k.elem,g);var j=(k.end=="none");k.end=(j?a.svg._getColour(k.elem.parentNode,g):a.svg._getRGB(k.end));k.end[3]=j;a(k.elem).css(g,"");k.set=true}var i=k.elem.attributes.getNamedItem(g);var l="rgb("+[Math.min(Math.max(parseInt((k.pos*(k.end[0]-k.start[0]))+k.start[0],10),0),255),Math.min(Math.max(parseInt((k.pos*(k.end[1]-k.start[1]))+k.start[1],10),0),255),Math.min(Math.max(parseInt((k.pos*(k.end[2]-k.start[2]))+k.start[2],10),0),255)].join(",")+")";l=(k.end[3]&&k.state==1?"none":l);(i?i.value=l:k.elem.setAttribute(g,l))}});a.svg._getColour=function(g,f){g=a(g);var h;do{h=g.attr(f)||g.css(f);if((h!=""&&h!="none")||g.hasClass(a.svg.markerClassName)){break}}while(g=g.parent());return a.svg._getRGB(h)};a.svg._getRGB=function(g){var f;if(g&&g.constructor==Array){return(g.length==3||g.length==4?g:d.none)}if(f=/^rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)$/.exec(g)){return[parseInt(f[1],10),parseInt(f[2],10),parseInt(f[3],10)]}if(f=/^rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)$/.exec(g)){return[parseFloat(f[1])*2.55,parseFloat(f[2])*2.55,parseFloat(f[3])*2.55]}if(f=/^#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(g)){return[parseInt(f[1],16),parseInt(f[2],16),parseInt(f[3],16)]}if(f=/^#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(g)){return[parseInt(f[1]+f[1],16),parseInt(f[2]+f[2],16),parseInt(f[3]+f[3],16)]}return d[a.trim(g).toLowerCase()]||d.none};var d={"":[255,255,255,1],none:[255,255,255,1],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}})(jQuery);
6976 /*!
6977 Deck JS - deck.svg
6978 Copyright (c) 2012-2014 RĂ©mi Emonet, as a major refactor from an early version from RĂ©mi Barraquand.
6979 Licensed under the MIT license.
6980 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6981 */
6982
6983 /*
6984 This module provides a support for managed svg inclusion (allowing proper DOM access subsequently for animations, etc.).
6985 */
6986
6987 (function($, deck, undefined) {
6988     var $d = $(document);
6989     var may = function(f) {return f ? f : function() {}};
6990
6991     $.extend(true, $[deck].defaults, {
6992         classes: {
6993             svgPlaceholder: 'deck-svg'
6994         },
6995         selectors: {
6996             svgObject: "object[type='deckjs/svg'], div.svg-object",
6997             svgObjectDisable: {
6998                 idrewrite: ".no-idrewrite",
6999                 stylerewrite: ".no-stylerewrite"
7000             }
7001         },
7002         alert: {
7003             missingSVG: true
7004         }
7005     });
7006
7007     function walk(node, fn) {
7008         if (node) do {
7009             if (node.nodeType === 1) {
7010                 fn.call(node);
7011                 walk(node.firstChild, fn);
7012             }
7013         } while (node = node.nextSibling);
7014     }
7015     var svgPatcher = {
7016         styleToAttributes: function(root, svgfile) {
7017             walk(root, function() {
7018                 var $n = $(this);
7019                 if ($n.attr("style")) {
7020                     $($n.attr("style").trim().split(/ *; */)).each(function(index, style) {
7021                         if (style && style.substring(0,1) != "-") {
7022                             var s = style.trim().split(/ *: */);
7023                             $n.attr(s[0], s[1]);
7024                         }
7025                     });
7026                 }
7027                 $n.attr("style", null);
7028             })
7029         },
7030         referencingAttributes: ["clip-path", "color-profile", "fill", "filter", "marker-start", "marker-mid", "marker-end", "mask", "stroke"],
7031         nextId: 1,
7032         generateId: function(oldId) {
7033             var id = "uniquesvg"+svgPatcher.nextId;
7034             svgPatcher.nextId++;
7035             return id;
7036         },
7037         makeReferencedIdsUnique: function(root, svgfile, continuation) {
7038             var andThen = continuation || function(){}
7039             var byId = {};
7040             var referencersIds = {};
7041             var pushAdd = function(k, o) {
7042                 if (referencersIds[k]) {
7043                     referencersIds[k].push(o);
7044                 } else {
7045                     referencersIds[k] = [ o ];
7046                 }
7047             };
7048             // gather all ids and references
7049             walk(root, function() {
7050                 var that = this;
7051                 var $n = $(this);
7052                 var id = that.id;
7053                 if (id) {
7054                     byId[id] = this;
7055                 }
7056                 $(svgPatcher.referencingAttributes).each(function(i,attr) {
7057                     var val = $n.attr(attr);
7058                     if (val) {
7059                         var groups = val.trim().match(/^url\(#(.+?)\)$/)
7060                         if (groups) pushAdd(groups[1], {o:that, a:attr})
7061                     }
7062                 });
7063                 var xlink = $n.attr("xlink:href");
7064                 if (xlink) {
7065                     var groups = xlink.trim().match(/^#(.+?)$/)
7066                     if (groups) pushAdd(groups[1], {o:that, a:"xlink:href"})
7067                 }
7068             })
7069             // patch used ids and references (keep unreferenced ids fixed (to allow for identification from the editor to the css, even if classes should be preferred))
7070             var newIds = {};
7071             for (id in referencersIds) {
7072                 var newId = svgPatcher.generateId(id);
7073                 byId[id].id = newId;
7074                 newIds[id] = newId;
7075             }
7076
7077             setTimeout( // to help firefox in having updated ids
7078                 (function() {
7079                 for (id in referencersIds) {
7080                     var newId = newIds[id];
7081                     var refs = referencersIds[id];
7082                     $(refs).each(function(i,pair){
7083                         var prev = $(pair.o).attr(pair.a);
7084                         if (pair.a == "xlink:href") {
7085                             pair.o.setAttributeNS($.svg.xlinkNS, "href", prev.replace("#" + id, "#" + newId));
7086                         } else {
7087                             $(pair.o).attr(pair.a, prev.replace("#" + id, "#" + newId));
7088                         }
7089                     })
7090                         }
7091                     andThen();
7092                 }), 0)
7093
7094         }
7095     }
7096
7097
7098     $d.bind('deck.beforeInit', function (event) {
7099         event.lockInit();
7100         var opts = $[deck]('getOptions');
7101         var container = $[deck]('getContainer');
7102
7103         /*
7104           Load parameters from an Object element
7105         */
7106         var loadObjectParams = function(objectElement) {
7107             var attributes = {};
7108             $(objectElement).children("param").each(function(index){
7109                 attributes[$(this).attr("name")] = $(this).attr("value");
7110             });
7111             $.each(objectElement.attributes, function (index, attr) {
7112                 if ("data-" == attr.name.substr(0, 5)) {
7113                     attributes[attr.name.substr(5)] = attr.value;
7114                 }
7115             });
7116             return attributes;
7117         }
7118         
7119         /*
7120           Return true if default params are set.
7121         */
7122         var validateParams = function(params) {
7123             return params['src'];// && params['width'] && params['height'];// && params['animator'];
7124         }
7125         
7126         /*
7127           Create SVG placeholder
7128         */
7129         var createSVG = function(object, attributes) {
7130             var $canvas, $control, $next, $reload, $placeholder;
7131             /* Create svg canvas */
7132             $canvas = $("<div />").attr({
7133                 'id':  $(object).attr('id'),
7134                 'data-src': attributes['src'],
7135                 'class': opts.classes.svgPlaceholder + " " + $(object).attr('class')
7136             }).css({
7137                 'height': attributes['height'],
7138                 'width': attributes['width']
7139             });
7140             return $canvas;
7141         }
7142
7143         
7144         /* Go through all toplevel slides */
7145         $($[deck]('getTopLevelSlides')).each( function(i, $slide) {
7146
7147             /* Find all the object of type deckjs/svg */
7148             $slide.find(opts.selectors.svgObject).each(function(index, obj) {
7149                 /* Load attributes and validate them */
7150                 var attributes = loadObjectParams(obj);
7151                 if (!validateParams(attributes) ) {
7152                     throw "Error while initializing "+$(obj).attr('id')+", please ensure you have setup the required parameters."
7153                     return false;
7154                 }
7155                 
7156                 /* Create SVG placeholder */
7157                 var SVG = createSVG(obj, attributes);
7158                 $(obj).replaceWith(SVG);
7159                 
7160                 // Finaly load the SVG data
7161                 event.lockInit();
7162
7163                 var notDisabled = function(k) {
7164                     var kk = 'no'+k;
7165                     var disabled = (attributes[kk] && attributes[kk] == "true") || $(obj).filter(opts.selectors.svgObjectDisable[k]).length > 0
7166                     return !disabled;
7167                 };
7168
7169                 SVG.svg({
7170                     loadURL: attributes['src'],
7171                     onLoad: function($svg, w, h) {
7172                         var px = function (str) {return str.replace("px", "")}
7173                         var aa = $($svg.root());
7174                         aa.attr('width', '100%');
7175                         aa.attr('height', '100%');
7176                         if (aa.attr('viewBox') == undefined) {
7177                             if (w==undefined || h==undefined) {
7178                                 if (opts.alert.missingSVG) alert(
7179                                     "There seem to be a problem with the loading of\n   '"+attributes['src'] + "'\n"
7180                                         +"\nMaybe the file does not exist?"
7181                                         +"\nOr maybe"
7182                                         +"\n - it has no w or h attribute?"
7183                                         +"\n - you're using a file that is within a symbolic-link folder?"
7184                                         +"\n - you're using chrome with local files?"
7185                                         +"\n   â‡’ try to restart chrome with '--disable-web-security'");
7186                                 event.releaseInit();
7187                             } else {
7188                                 var to = "0 0 " + px(w) + " " + px(h);
7189                                 $svg.root().setAttribute("viewBox", to);
7190                                 aa.attr("svgViewBox", to);
7191                                 if (attributes['stretch'] == 'true') $svg.root().setAttribute('preserveAspectRatio', "none");
7192                                 if (notDisabled('stylerewrite')) {
7193                                     svgPatcher.styleToAttributes($svg.root(), attributes['src']);
7194                                 }
7195                                 if (notDisabled('idrewrite')) {
7196                                     svgPatcher.makeReferencedIdsUnique($svg.root(), attributes['src'], function() {
7197                                         event.releaseInit();
7198                                     });
7199                                 } else {
7200                                     event.releaseInit();
7201                                 }
7202                             }
7203                         }
7204                     }
7205                 });
7206             });
7207         });
7208         event.releaseInit();
7209     })
7210     
7211     
7212 })(jQuery, 'deck');
7213
7214
7215 /*!
7216 Deck JS - deck.metadata
7217 Copyright (c) 2014 RĂ©mi Emonet
7218 Licensed under the MIT license.
7219 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7220 */
7221
7222 /*
7223 This module automatically takes each meta tag (e.g., author, date, ...) and the page title.
7224 It then replaces the content of all elements having a var-... class by the value of the metadata.
7225
7226 This is very useful for example to repeat the date, title, venue name, author name, etc… in a title page, in the footer and in a closing page (without copy pasting).
7227 */
7228
7229 (function($, deck, undefined) {
7230     $.extend(true, $.deck.defaults, {
7231         selectors: {
7232             metadataPrefix: '.var-',
7233             metadataBrSuffix: '-br',
7234             metadataFullSuffix: '-full'
7235         },
7236         metadataSeparator: /(&nbsp;| )/gi   /* we need to handle '&nbsp;' and ' ' because in the title, ' ' becomes '&nbsp;' */
7237     });
7238
7239     var $d = $(document);
7240     $d.bind('deck.init', function() {
7241         var o = $.deck('getOptions');
7242         var app = function(_sel, v) {
7243             var sel = o.selectors.metadataPrefix + _sel;
7244             var sep = o.metadataSeparator;
7245             $(sel).html(v.replace(sep, ""));
7246             $(sel+o.selectors.metadataFullSuffix).html(v);
7247             $(sel+o.selectors.metadataBrSuffix).html(v.replace(sep, "<br/>"));
7248         };
7249         app("title", $("html>head>title").html());
7250         $("html>head>meta[name]").each(function(i,e) {
7251             app($(e).attr('name'), $(e).attr('content'))
7252         });
7253     });
7254 })(jQuery, 'deck');
7255
7256 /*!
7257 Deck JS - deck.attribution
7258 Copyright (c) 2014 RĂ©mi Emonet
7259 Licensed under the MIT license.
7260 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7261 */
7262
7263 /*
7264 This module automatically adds some text and a link for elements having a "data-attribution" attributes.
7265 */
7266
7267 (function($, deck, undefined) {
7268     $.extend(true, $.deck.defaults, {
7269         classes: {
7270             attributionWrapper: 'attribution-wrap',
7271             attributionLink: 'attribution-link'
7272         },
7273         dataAttribution: "data-attribution",
7274         dataAttributionContent: "data-attribution-content",
7275         dataAttributionClass: "data-attribution-class"
7276     });
7277
7278     var $d = $(document);
7279     $d.bind('deck.init', function() {
7280         var o = $.deck('getOptions');
7281         $('*['+o.dataAttribution+']').each(function(i, el){
7282             var c = $(el).attr(o.dataAttributionContent);
7283             var cc = $(el).attr(o.dataAttributionClass);
7284             var a = $(el).attr(o.dataAttribution);
7285             var w = $("<div>");
7286             w.addClass(o.classes.attributionWrapper);
7287             var link = $("<a>");
7288             link.addClass(o.classes.attributionLink);
7289             if (!! cc) link.addClass(cc);
7290             link.attr("href", a);
7291             link.attr("target", "_blank");
7292             if (!! c) {
7293                 link.html(c);
7294             } else {
7295                 link.html(a);
7296             }
7297             $(el).after(w);
7298             $(w).append(link);
7299         });
7300     });
7301 })(jQuery, 'deck');
7302
7303 /*!
7304 Deck JS - deck.container-styling
7305 Copyright (c) 2014 RĂ©mi Emonet
7306 Licensed under the MIT license.
7307 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7308 */
7309
7310 /*
7311 This module automatically adds/removes to the container the class specified in data-container-class (for toplevel slides).
7312
7313 This extension relies on the events extension.
7314 */
7315
7316 (function($, deck, undefined) {
7317     var $d = $(document);
7318     $d.bind('deck.init', function() {
7319         $('*[data-container-class]').each(function(i, el) {
7320             var toRemove = ""; // one 'toRemove' per element (that's why we do .each
7321             $(el).bind('deck.becameCurrent', function(_, direction) {
7322                 var target = $(_.target);
7323                 var toAdd = target.attr('data-container-class');
7324                 $[deck]('getContainer').addClass(toAdd);
7325                 toRemove = toAdd;
7326             }).bind('deck.lostCurrent', function(_, direction) {
7327                 $[deck]('getContainer').removeClass(toRemove);
7328                 toRemove = "";
7329             });
7330         });
7331     });
7332     $(document).bind('deck.init', function() { // force trigger even if no #slide-... is provided
7333         var current = $[deck]('getSlide')
7334         var icur = 0
7335         for (; icur < $[deck]('getSlides').length; icur++) {
7336             if ($[deck]('getSlides')[icur] == current) break;                
7337         }
7338         $(document).trigger("deck.change", [icur, icur]);
7339     });
7340 })(jQuery, 'deck');
7341
7342 /*!
7343 Deck JS - deck.timekeeper
7344 Copyright (c) 2013-2014 RĂ©mi Emonet
7345 Licensed under the MIT license.
7346 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7347 */
7348
7349 /*
7350 This module provides a support for displaying current time, time from start and logging the time spent on each slide etc.
7351 It also injects some default html for it if none is found (and styles it for the presenter/clone view).
7352 */
7353
7354 (function($, deck, undefined) {
7355     var $d = $(document);
7356
7357     $.extend(true, $[deck].defaults, {  
7358         selectors: {
7359             timekeeper: ".timekeeper", /* inject if this is not present */ // TODO inject
7360             timekeeperTime: ".timekeeper-time",
7361             timekeeperRelativeTime: ".timekeeper-relative-time",
7362             timekeeperLocalRelativeTime: ".timekeeper-local-relative-time",
7363             timekeeperLogs: ".timekeeper-logs",
7364             timekeeperLogsPre: ".timekeeper-logs pre",
7365             timekeeperLogsToggle: ".timekeeper-logs-toggle",
7366             timekeeperBang: ".timekeeper-bang",
7367             timekeeperClear: ".timekeeper-clear"
7368         },
7369         classes: {
7370             timekeeperNotification: "timekeeper-notification",
7371             timekeeperLogsVisible: "timekeeper-logs-visible"
7372         },
7373         snippets: {
7374             timekeeper: true
7375         },
7376         alert: {
7377             localStorageUnsupported: true
7378         },
7379         localStorage: {
7380             timekeeperArchivesMaxSize: 500*1000,
7381             timekeeperArchives: 'deckjs-timekeeper-archives',
7382             timekeeperLogs: 'deckjs-timekeeper-logs',
7383             timekeeperBase: 'deckjs-timekeeper-base',
7384             timekeeperLocalBase: 'deckjs-timekeeper-local-base'
7385         },
7386         timekeeperPeriod: 1000,
7387         timekeeperNotificationPeriod: 100,
7388         keys: {
7389             timekeeper: [27, 75] // escape, k (combine with SHIFT to reset the counter (when starting presenting))
7390         }
7391     });
7392
7393     $d.bind('deck.init', function() {
7394         var opts = $[deck]('getOptions');
7395         var container = $[deck]('getContainer');
7396
7397         // sligthly edited from
7398         var selectText = function(text) {
7399             var doc = document
7400             , range, selection
7401             ;
7402             if (doc.body.createTextRange) { //ms
7403                 range = doc.body.createTextRange();
7404                 range.moveToElementText(text);
7405                 range.select();
7406             } else if (window.getSelection) { //all others
7407                 selection = window.getSelection();
7408                 range = doc.createRange();
7409                 range.selectNodeContents(text);
7410                 selection.removeAllRanges();
7411                 selection.addRange(range);
7412             }
7413         }
7414
7415         if (opts.snippets.timekeeper) {
7416             var d = function() {return $('<div/>');}
7417             var divTK = d().addClass("timekeeper timekeeper-logs-toggle");
7418             divTK.append(d().addClass("timekeeper-local-relative-time"));
7419             divTK.append(d().addClass("timekeeper-time"));
7420             divTK.append(d().addClass("timekeeper-relative-time"));
7421             divTK.append(d().addClass("timekeeper-clear"));
7422             divTK.append(d().addClass("timekeeper-bang"));
7423             divTK.appendTo(container);
7424             var divLog = d().addClass("timekeeper-logs");
7425             var pre = $('<pre/>').appendTo(divLog);
7426             divLog.append(d().addClass("button").click(function() { doBang() }).html("Bang!"));
7427             divLog.append(d().addClass("button").click(function() { selectText(pre.get(0)) }).html("select all"));
7428             divLog.append(d().addClass("button").click(function() { clearStorage() }).html("Clear").css({color:'#f44', marginLeft: '2em'}));
7429             divLog.append(d().addClass("button").addClass("timekeeper-logs-toggle").css({position:'float', float:'right', color:'#0f0'}).html("X"));
7430             divLog.appendTo(container);
7431         }
7432
7433         if (!window.localStorage && opts.alert.localStorageUnsupported) { alert(
7434             "LocalStorage is unsupported in your browser, timing features are disabled (timekeeper extension).");
7435             return;
7436         }
7437
7438         var pad = function(base, right) {
7439             var s = ""+right;
7440             if (s.length >= base.length) return s;
7441             else return base.substring(0, base.length - s.length) + s
7442         }
7443         var formatTime = function(t) {
7444             var min = parseInt(t / 1000 / 60);
7445             var sec = parseInt(t / 1000 - 60 * min);
7446             if (min > 60) {
7447                 var hours = parseInt(t / 1000 / 60 / 60);
7448                 min = parseInt(t / 1000 / 60 - 60 * hours);
7449                 return pad("00", hours) +":"+ pad("00", min) + ":" + pad("00", sec)
7450             } else {
7451                 return pad("00", min) + ":" + pad("00", sec)
7452             }
7453         }
7454         var clearStorage = function(what) {
7455             // TODO archive
7456             localStorage.setItem(opts.localStorage.timekeeperLogs, null);
7457             log("CLEARED BY USER");
7458             localStorage.setItem(opts.localStorage.timekeeperBase, JSON.stringify(new Date()));
7459             $(opts.selectors.timekeeperClear).addClass(opts.classes.timekeeperNotification);
7460             setTimeout(function() {
7461                 $(opts.selectors.timekeeperClear).removeClass(opts.classes.timekeeperNotification);
7462             }, opts.timekeeperNotificationPeriod);
7463         }
7464         var reset = function() {
7465             localStorage.setItem(opts.localStorage.timekeeperLocalBase, JSON.stringify(new Date()));
7466         }
7467         var getDateOrSet = function(k, or) {
7468             var res = localStorage.getItem(k);
7469             if (res == null) {
7470                 res = JSON.stringify(or);
7471                 localStorage.setItem(k, res);
7472             } else {
7473                 res = new Date(JSON.parse(res));
7474             }
7475             return res;
7476         }
7477         var log = function(what) {
7478             var now = new Date();
7479             var time = now.toString()
7480             var localBase = getDateOrSet(opts.localStorage.timekeeperLocalBase, now);
7481             var base = getDateOrSet(opts.localStorage.timekeeperBase, now);
7482             var db = (now - localBase)/1000;
7483             var dcb = (now - base)/1000;
7484             var dbtime = formatTime(now - localBase);
7485             var dcbtime = formatTime(now - base);
7486             var log = time.replace(/GMT.*/, "") + " " + what + " " + dcb + " " + db + " " + dcbtime + " " + dbtime;
7487             
7488             var data = localStorage.getItem(opts.localStorage.timekeeperLogs);
7489             data = log + "\n" + data;
7490             localStorage.setItem(opts.localStorage.timekeeperLogs, data);
7491             $(opts.selectors.timekeeperLogsPre).html(data);
7492         }
7493
7494
7495         var saveCurrent = -1;
7496         $(document).bind('deck.change', function(e, from, to) {
7497             log(from + " " + to);
7498             saveCurrent = to;
7499         });
7500         
7501         // Bind key event to add a marker in the logs
7502         var $d = $(document);
7503         var doBang = function() {
7504             log("BANG " + saveCurrent);
7505             $(opts.selectors.timekeeperBang).addClass(opts.classes.timekeeperNotification);
7506             setTimeout(function() {
7507                 $(opts.selectors.timekeeperBang).removeClass(opts.classes.timekeeperNotification);
7508             }, opts.timekeeperNotificationPeriod);
7509             reset();
7510         }
7511         $d.unbind('keydown.logbang').bind('keydown.logbang', function(e) {
7512             if (e.ctrlKey) return;
7513             var K = opts.keys.timekeeper;
7514             if (e.which === K || $.inArray(e.which, K) > -1) {
7515                 doBang();
7516                 if (e.shiftKey) {
7517                     clearStorage();
7518                 }
7519             }
7520         });
7521         $(opts.selectors.timekeeperLogsToggle).unbind('click.timekeeper').bind('click.timekeeper', function(e) {
7522             $(opts.selectors.timekeeperLogs).toggleClass(opts.classes.timekeeperLogsVisible);
7523         });
7524
7525
7526         // Refresh display
7527         var period = opts.timekeeperPeriod;
7528         setInterval(function() {
7529             var today = new Date();
7530             today.setMinutes(0);
7531             today.setHours(0);
7532             today.setSeconds(0);
7533             var now = new Date();
7534             $(opts.selectors.timekeeperTime).html(formatTime(now - today));
7535             var v = localStorage.getItem(opts.localStorage.timekeeperBase);
7536             if (v != null) {
7537                 var t = now - new Date(JSON.parse(v));
7538                 var time = formatTime(t);
7539                 $(opts.selectors.timekeeperRelativeTime).html(time);
7540             }
7541             var v2 = localStorage.getItem(opts.localStorage.timekeeperLocalBase);
7542             if (v2 != null) {
7543                 var t = now - new Date(JSON.parse(v2));
7544                 var time = formatTime(t);
7545                 $(opts.selectors.timekeeperLocalRelativeTime).html(time);
7546             }
7547         }, period);
7548     
7549     });
7550
7551 })(jQuery, 'deck');
7552
7553
7554 (function(global, document) {
7555
7556   // Popcorn.js does not support archaic browsers
7557   if ( !document.addEventListener ) {
7558     global.Popcorn = {
7559       isSupported: false
7560     };
7561
7562     var methods = ( "byId forEach extend effects error guid sizeOf isArray nop position disable enable destroy" +
7563           "addTrackEvent removeTrackEvent getTrackEvents getTrackEvent getLastTrackEventId " +
7564           "timeUpdate plugin removePlugin compose effect xhr getJSONP getScript" ).split(/\s+/);
7565
7566     while ( methods.length ) {
7567       global.Popcorn[ methods.shift() ] = function() {};
7568     }
7569     return;
7570   }
7571
7572   var
7573
7574   AP = Array.prototype,
7575   OP = Object.prototype,
7576
7577   forEach = AP.forEach,
7578   slice = AP.slice,
7579   hasOwn = OP.hasOwnProperty,
7580   toString = OP.toString,
7581
7582   // Copy global Popcorn (may not exist)
7583   _Popcorn = global.Popcorn,
7584
7585   //  Ready fn cache
7586   readyStack = [],
7587   readyBound = false,
7588   readyFired = false,
7589
7590   //  Non-public internal data object
7591   internal = {
7592     events: {
7593       hash: {},
7594       apis: {}
7595     }
7596   },
7597
7598   //  Non-public `requestAnimFrame`
7599   //  http://paulirish.com/2011/requestanimationframe-for-smart-animating/
7600   requestAnimFrame = (function(){
7601     return global.requestAnimationFrame ||
7602       global.webkitRequestAnimationFrame ||
7603       global.mozRequestAnimationFrame ||
7604       global.oRequestAnimationFrame ||
7605       global.msRequestAnimationFrame ||
7606       function( callback, element ) {
7607         global.setTimeout( callback, 16 );
7608       };
7609   }()),
7610
7611   //  Non-public `getKeys`, return an object's keys as an array
7612   getKeys = function( obj ) {
7613     return Object.keys ? Object.keys( obj ) : (function( obj ) {
7614       var item,
7615           list = [];
7616
7617       for ( item in obj ) {
7618         if ( hasOwn.call( obj, item ) ) {
7619           list.push( item );
7620         }
7621       }
7622       return list;
7623     })( obj );
7624   },
7625
7626   Abstract = {
7627     // [[Put]] props from dictionary onto |this|
7628     // MUST BE CALLED FROM WITHIN A CONSTRUCTOR:
7629     //  Abstract.put.call( this, dictionary );
7630     put: function( dictionary ) {
7631       // For each own property of src, let key be the property key
7632       // and desc be the property descriptor of the property.
7633       Object.getOwnPropertyNames( dictionary ).forEach(function( key ) {
7634         this[ key ] = dictionary[ key ];
7635       }, this);
7636     }
7637   },
7638
7639
7640   //  Declare constructor
7641   //  Returns an instance object.
7642   Popcorn = function( entity, options ) {
7643     //  Return new Popcorn object
7644     return new Popcorn.p.init( entity, options || null );
7645   };
7646
7647   //  Popcorn API version, automatically inserted via build system.
7648   Popcorn.version = "@VERSION";
7649
7650   //  Boolean flag allowing a client to determine if Popcorn can be supported
7651   Popcorn.isSupported = true;
7652
7653   //  Instance caching
7654   Popcorn.instances = [];
7655
7656   //  Declare a shortcut (Popcorn.p) to and a definition of
7657   //  the new prototype for our Popcorn constructor
7658   Popcorn.p = Popcorn.prototype = {
7659
7660     init: function( entity, options ) {
7661
7662       var matches, nodeName,
7663           self = this;
7664
7665       //  Supports Popcorn(function () { /../ })
7666       //  Originally proposed by Daniel Brooks
7667
7668       if ( typeof entity === "function" ) {
7669
7670         //  If document ready has already fired
7671         if ( document.readyState === "complete" ) {
7672
7673           entity( document, Popcorn );
7674
7675           return;
7676         }
7677         //  Add `entity` fn to ready stack
7678         readyStack.push( entity );
7679
7680         //  This process should happen once per page load
7681         if ( !readyBound ) {
7682
7683           //  set readyBound flag
7684           readyBound = true;
7685
7686           var DOMContentLoaded  = function() {
7687
7688             readyFired = true;
7689
7690             //  Remove global DOM ready listener
7691             document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
7692
7693             //  Execute all ready function in the stack
7694             for ( var i = 0, readyStackLength = readyStack.length; i < readyStackLength; i++ ) {
7695
7696               readyStack[ i ].call( document, Popcorn );
7697
7698             }
7699             //  GC readyStack
7700             readyStack = null;
7701           };
7702
7703           //  Register global DOM ready listener
7704           document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
7705         }
7706
7707         return;
7708       }
7709
7710       if ( typeof entity === "string" ) {
7711         try {
7712           matches = document.querySelector( entity );
7713         } catch( e ) {
7714           throw new Error( "Popcorn.js Error: Invalid media element selector: " + entity );
7715         }
7716       }
7717
7718       //  Get media element by id or object reference
7719       this.media = matches || entity;
7720
7721       //  inner reference to this media element's nodeName string value
7722       nodeName = ( this.media.nodeName && this.media.nodeName.toLowerCase() ) || "video";
7723
7724       //  Create an audio or video element property reference
7725       this[ nodeName ] = this.media;
7726
7727       this.options = Popcorn.extend( {}, options ) || {};
7728
7729       //  Resolve custom ID or default prefixed ID
7730       this.id = this.options.id || Popcorn.guid( nodeName );
7731
7732       //  Throw if an attempt is made to use an ID that already exists
7733       if ( Popcorn.byId( this.id ) ) {
7734         throw new Error( "Popcorn.js Error: Cannot use duplicate ID (" + this.id + ")" );
7735       }
7736
7737       this.isDestroyed = false;
7738
7739       this.data = {
7740
7741         // data structure of all
7742         running: {
7743           cue: []
7744         },
7745
7746         // Executed by either timeupdate event or in rAF loop
7747         timeUpdate: Popcorn.nop,
7748
7749         // Allows disabling a plugin per instance
7750         disabled: {},
7751
7752         // Stores DOM event queues by type
7753         events: {},
7754
7755         // Stores Special event hooks data
7756         hooks: {},
7757
7758         // Store track event history data
7759         history: [],
7760
7761         // Stores ad-hoc state related data]
7762         state: {
7763           volume: this.media.volume
7764         },
7765
7766         // Store track event object references by trackId
7767         trackRefs: {},
7768
7769         // Playback track event queues
7770         trackEvents: new TrackEvents( this )
7771       };
7772
7773       //  Register new instance
7774       Popcorn.instances.push( this );
7775
7776       //  function to fire when video is ready
7777       var isReady = function() {
7778
7779         // chrome bug: http://code.google.com/p/chromium/issues/detail?id=119598
7780         // it is possible the video's time is less than 0
7781         // this has the potential to call track events more than once, when they should not
7782         // start: 0, end: 1 will start, end, start again, when it should just start
7783         // just setting it to 0 if it is below 0 fixes this issue
7784         if ( self.media.currentTime < 0 ) {
7785
7786           self.media.currentTime = 0;
7787         }
7788
7789         self.media.removeEventListener( "loadedmetadata", isReady, false );
7790
7791         var duration, videoDurationPlus,
7792             runningPlugins, runningPlugin, rpLength, rpNatives;
7793
7794         //  Adding padding to the front and end of the arrays
7795         //  this is so we do not fall off either end
7796         duration = self.media.duration;
7797
7798         //  Check for no duration info (NaN)
7799         videoDurationPlus = duration != duration ? Number.MAX_VALUE : duration + 1;
7800
7801         Popcorn.addTrackEvent( self, {
7802           start: videoDurationPlus,
7803           end: videoDurationPlus
7804         });
7805
7806         if ( !self.isDestroyed ) {
7807           self.data.durationChange = function() {
7808             var newDuration = self.media.duration,
7809                 newDurationPlus = newDuration + 1,
7810                 byStart = self.data.trackEvents.byStart,
7811                 byEnd = self.data.trackEvents.byEnd;
7812
7813             // Remove old padding events
7814             byStart.pop();
7815             byEnd.pop();
7816
7817             // Remove any internal tracking of events that have end times greater than duration
7818             // otherwise their end events will never be hit.
7819             for ( var k = byEnd.length - 1; k > 0; k-- ) {
7820               if ( byEnd[ k ].end > newDuration ) {
7821                 self.removeTrackEvent( byEnd[ k ]._id );
7822               }
7823             }
7824
7825             // Remove any internal tracking of events that have end times greater than duration
7826             // otherwise their end events will never be hit.
7827             for ( var i = 0; i < byStart.length; i++ ) {
7828               if ( byStart[ i ].end > newDuration ) {
7829                 self.removeTrackEvent( byStart[ i ]._id );
7830               }
7831             }
7832
7833             // References to byEnd/byStart are reset, so accessing it this way is
7834             // forced upon us.
7835             self.data.trackEvents.byEnd.push({
7836               start: newDurationPlus,
7837               end: newDurationPlus
7838             });
7839
7840             self.data.trackEvents.byStart.push({
7841               start: newDurationPlus,
7842               end: newDurationPlus
7843             });
7844           };
7845
7846           // Listen for duration changes and adjust internal tracking of event timings
7847           self.media.addEventListener( "durationchange", self.data.durationChange, false );
7848         }
7849
7850         if ( self.options.frameAnimation ) {
7851
7852           //  if Popcorn is created with frameAnimation option set to true,
7853           //  requestAnimFrame is used instead of "timeupdate" media event.
7854           //  This is for greater frame time accuracy, theoretically up to
7855           //  60 frames per second as opposed to ~4 ( ~every 15-250ms)
7856           self.data.timeUpdate = function () {
7857
7858             Popcorn.timeUpdate( self, {} );
7859
7860             // fire frame for each enabled active plugin of every type
7861             Popcorn.forEach( Popcorn.manifest, function( key, val ) {
7862
7863               runningPlugins = self.data.running[ val ];
7864
7865               // ensure there are running plugins on this type on this instance
7866               if ( runningPlugins ) {
7867
7868                 rpLength = runningPlugins.length;
7869                 for ( var i = 0; i < rpLength; i++ ) {
7870
7871                   runningPlugin = runningPlugins[ i ];
7872                   rpNatives = runningPlugin._natives;
7873                   rpNatives && rpNatives.frame &&
7874                     rpNatives.frame.call( self, {}, runningPlugin, self.currentTime() );
7875                 }
7876               }
7877             });
7878
7879             self.emit( "timeupdate" );
7880
7881             !self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
7882           };
7883
7884           !self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
7885
7886         } else {
7887
7888           self.data.timeUpdate = function( event ) {
7889             Popcorn.timeUpdate( self, event );
7890           };
7891
7892           if ( !self.isDestroyed ) {
7893             self.media.addEventListener( "timeupdate", self.data.timeUpdate, false );
7894           }
7895         }
7896       };
7897
7898       Object.defineProperty( this, "error", {
7899         get: function() {
7900
7901           return self.media.error;
7902         }
7903       });
7904
7905       // http://www.whatwg.org/specs/web-apps/current-work/#dom-media-readystate
7906       //
7907       // If media is in readyState (rS) >= 1, we know the media's duration,
7908       // which is required before running the isReady function.
7909       // If rS is 0, attach a listener for "loadedmetadata",
7910       // ( Which indicates that the media has moved from rS 0 to 1 )
7911       //
7912       // This has been changed from a check for rS 2 because
7913       // in certain conditions, Firefox can enter this code after dropping
7914       // to rS 1 from a higher state such as 2 or 3. This caused a "loadeddata"
7915       // listener to be attached to the media object, an event that had
7916       // already triggered and would not trigger again. This left Popcorn with an
7917       // instance that could never start a timeUpdate loop.
7918       if ( self.media.readyState >= 1 ) {
7919
7920         isReady();
7921       } else {
7922
7923         self.media.addEventListener( "loadedmetadata", isReady, false );
7924       }
7925
7926       return this;
7927     }
7928   };
7929
7930   //  Extend constructor prototype to instance prototype
7931   //  Allows chaining methods to instances
7932   Popcorn.p.init.prototype = Popcorn.p;
7933
7934   Popcorn.byId = function( str ) {
7935     var instances = Popcorn.instances,
7936         length = instances.length,
7937         i = 0;
7938
7939     for ( ; i < length; i++ ) {
7940       if ( instances[ i ].id === str ) {
7941         return instances[ i ];
7942       }
7943     }
7944
7945     return null;
7946   };
7947
7948   Popcorn.forEach = function( obj, fn, context ) {
7949
7950     if ( !obj || !fn ) {
7951       return {};
7952     }
7953
7954     context = context || this;
7955
7956     var key, len;
7957
7958     // Use native whenever possible
7959     if ( forEach && obj.forEach === forEach ) {
7960       return obj.forEach( fn, context );
7961     }
7962
7963     if ( toString.call( obj ) === "[object NodeList]" ) {
7964       for ( key = 0, len = obj.length; key < len; key++ ) {
7965         fn.call( context, obj[ key ], key, obj );
7966       }
7967       return obj;
7968     }
7969
7970     for ( key in obj ) {
7971       if ( hasOwn.call( obj, key ) ) {
7972         fn.call( context, obj[ key ], key, obj );
7973       }
7974     }
7975     return obj;
7976   };
7977
7978   Popcorn.extend = function( obj ) {
7979     var dest = obj, src = slice.call( arguments, 1 );
7980
7981     Popcorn.forEach( src, function( copy ) {
7982       for ( var prop in copy ) {
7983         dest[ prop ] = copy[ prop ];
7984       }
7985     });
7986
7987     return dest;
7988   };
7989
7990
7991   // A Few reusable utils, memoized onto Popcorn
7992   Popcorn.extend( Popcorn, {
7993     noConflict: function( deep ) {
7994
7995       if ( deep ) {
7996         global.Popcorn = _Popcorn;
7997       }
7998
7999       return Popcorn;
8000     },
8001     error: function( msg ) {
8002       throw new Error( msg );
8003     },
8004     guid: function( prefix ) {
8005       Popcorn.guid.counter++;
8006       return  ( prefix ? prefix : "" ) + ( +new Date() + Popcorn.guid.counter );
8007     },
8008     sizeOf: function( obj ) {
8009       var size = 0;
8010
8011       for ( var prop in obj ) {
8012         size++;
8013       }
8014
8015       return size;
8016     },
8017     isArray: Array.isArray || function( array ) {
8018       return toString.call( array ) === "[object Array]";
8019     },
8020
8021     nop: function() {},
8022
8023     position: function( elem ) {
8024
8025       if ( !elem.parentNode ) {
8026         return null;
8027       }
8028
8029       var clientRect = elem.getBoundingClientRect(),
8030           bounds = {},
8031           doc = elem.ownerDocument,
8032           docElem = document.documentElement,
8033           body = document.body,
8034           clientTop, clientLeft, scrollTop, scrollLeft, top, left;
8035
8036       //  Determine correct clientTop/Left
8037       clientTop = docElem.clientTop || body.clientTop || 0;
8038       clientLeft = docElem.clientLeft || body.clientLeft || 0;
8039
8040       //  Determine correct scrollTop/Left
8041       scrollTop = ( global.pageYOffset && docElem.scrollTop || body.scrollTop );
8042       scrollLeft = ( global.pageXOffset && docElem.scrollLeft || body.scrollLeft );
8043
8044       //  Temp top/left
8045       top = Math.ceil( clientRect.top + scrollTop - clientTop );
8046       left = Math.ceil( clientRect.left + scrollLeft - clientLeft );
8047
8048       for ( var p in clientRect ) {
8049         bounds[ p ] = Math.round( clientRect[ p ] );
8050       }
8051
8052       return Popcorn.extend({}, bounds, { top: top, left: left });
8053     },
8054
8055     disable: function( instance, plugin ) {
8056
8057       if ( instance.data.disabled[ plugin ] ) {
8058         return;
8059       }
8060
8061       instance.data.disabled[ plugin ] = true;
8062
8063       if ( plugin in Popcorn.registryByName &&
8064            instance.data.running[ plugin ] ) {
8065
8066         for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) {
8067
8068           event = instance.data.running[ plugin ][ i ];
8069           event._natives.end.call( instance, null, event  );
8070
8071           instance.emit( "trackend",
8072             Popcorn.extend({}, event, {
8073               plugin: event.type,
8074               type: "trackend"
8075             })
8076           );
8077         }
8078       }
8079
8080       return instance;
8081     },
8082     enable: function( instance, plugin ) {
8083
8084       if ( !instance.data.disabled[ plugin ] ) {
8085         return;
8086       }
8087
8088       instance.data.disabled[ plugin ] = false;
8089
8090       if ( plugin in Popcorn.registryByName &&
8091            instance.data.running[ plugin ] ) {
8092
8093         for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) {
8094
8095           event = instance.data.running[ plugin ][ i ];
8096           event._natives.start.call( instance, null, event  );
8097
8098           instance.emit( "trackstart",
8099             Popcorn.extend({}, event, {
8100               plugin: event.type,
8101               type: "trackstart",
8102               track: event
8103             })
8104           );
8105         }
8106       }
8107
8108       return instance;
8109     },
8110     destroy: function( instance ) {
8111       var events = instance.data.events,
8112           trackEvents = instance.data.trackEvents,
8113           singleEvent, item, fn, plugin;
8114
8115       //  Iterate through all events and remove them
8116       for ( item in events ) {
8117         singleEvent = events[ item ];
8118         for ( fn in singleEvent ) {
8119           delete singleEvent[ fn ];
8120         }
8121         events[ item ] = null;
8122       }
8123
8124       // remove all plugins off the given instance
8125       for ( plugin in Popcorn.registryByName ) {
8126         Popcorn.removePlugin( instance, plugin );
8127       }
8128
8129       // Remove all data.trackEvents #1178
8130       trackEvents.byStart.length = 0;
8131       trackEvents.byEnd.length = 0;
8132
8133       if ( !instance.isDestroyed ) {
8134         instance.data.timeUpdate && instance.media.removeEventListener( "timeupdate", instance.data.timeUpdate, false );
8135         instance.isDestroyed = true;
8136       }
8137
8138       Popcorn.instances.splice( Popcorn.instances.indexOf( instance ), 1 );
8139     }
8140   });
8141
8142   //  Memoized GUID Counter
8143   Popcorn.guid.counter = 1;
8144
8145   //  Factory to implement getters, setters and controllers
8146   //  as Popcorn instance methods. The IIFE will create and return
8147   //  an object with defined methods
8148   Popcorn.extend(Popcorn.p, (function() {
8149
8150       var methods = "load play pause currentTime playbackRate volume duration preload playbackRate " +
8151                     "autoplay loop controls muted buffered readyState seeking paused played seekable ended",
8152           ret = {};
8153
8154
8155       //  Build methods, store in object that is returned and passed to extend
8156       Popcorn.forEach( methods.split( /\s+/g ), function( name ) {
8157
8158         ret[ name ] = function( arg ) {
8159           var previous;
8160
8161           if ( typeof this.media[ name ] === "function" ) {
8162
8163             // Support for shorthanded play(n)/pause(n) jump to currentTime
8164             // If arg is not null or undefined and called by one of the
8165             // allowed shorthandable methods, then set the currentTime
8166             // Supports time as seconds or SMPTE
8167             if ( arg != null && /play|pause/.test( name ) ) {
8168               this.media.currentTime = Popcorn.util.toSeconds( arg );
8169             }
8170
8171             this.media[ name ]();
8172
8173             return this;
8174           }
8175
8176           if ( arg != null ) {
8177             // Capture the current value of the attribute property
8178             previous = this.media[ name ];
8179
8180             // Set the attribute property with the new value
8181             this.media[ name ] = arg;
8182
8183             // If the new value is not the same as the old value
8184             // emit an "attrchanged event"
8185             if ( previous !== arg ) {
8186               this.emit( "attrchange", {
8187                 attribute: name,
8188                 previousValue: previous,
8189                 currentValue: arg
8190               });
8191             }
8192             return this;
8193           }
8194
8195           return this.media[ name ];
8196         };
8197       });
8198
8199       return ret;
8200
8201     })()
8202   );
8203
8204   Popcorn.forEach( "enable disable".split(" "), function( method ) {
8205     Popcorn.p[ method ] = function( plugin ) {
8206       return Popcorn[ method ]( this, plugin );
8207     };
8208   });
8209
8210   Popcorn.extend(Popcorn.p, {
8211
8212     //  Rounded currentTime
8213     roundTime: function() {
8214       return Math.round( this.media.currentTime );
8215     },
8216
8217     //  Attach an event to a single point in time
8218     exec: function( id, time, fn ) {
8219       var length = arguments.length,
8220           eventType = "trackadded",
8221           trackEvent, sec, options;
8222
8223       // Check if first could possibly be a SMPTE string
8224       // p.cue( "smpte string", fn );
8225       // try/catch avoid awful throw in Popcorn.util.toSeconds
8226       // TODO: Get rid of that, replace with NaN return?
8227       try {
8228         sec = Popcorn.util.toSeconds( id );
8229       } catch ( e ) {}
8230
8231       // If it can be converted into a number then
8232       // it's safe to assume that the string was SMPTE
8233       if ( typeof sec === "number" ) {
8234         id = sec;
8235       }
8236
8237       // Shift arguments based on use case
8238       //
8239       // Back compat for:
8240       // p.cue( time, fn );
8241       if ( typeof id === "number" && length === 2 ) {
8242         fn = time;
8243         time = id;
8244         id = Popcorn.guid( "cue" );
8245       } else {
8246         // Support for new forms
8247
8248         // p.cue( "empty-cue" );
8249         if ( length === 1 ) {
8250           // Set a time for an empty cue. It's not important what
8251           // the time actually is, because the cue is a no-op
8252           time = -1;
8253
8254         } else {
8255
8256           // Get the TrackEvent that matches the given id.
8257           trackEvent = this.getTrackEvent( id );
8258
8259           if ( trackEvent ) {
8260
8261             // remove existing cue so a new one can be added via trackEvents.add
8262             this.data.trackEvents.remove( id );
8263             TrackEvent.end( this, trackEvent );
8264             // Update track event references
8265             Popcorn.removeTrackEvent.ref( this, id );
8266
8267             eventType = "cuechange";
8268
8269             // p.cue( "my-id", 12 );
8270             // p.cue( "my-id", function() { ... });
8271             if ( typeof id === "string" && length === 2 ) {
8272
8273               // p.cue( "my-id", 12 );
8274               // The path will update the cue time.
8275               if ( typeof time === "number" ) {
8276                 // Re-use existing TrackEvent start callback
8277                 fn = trackEvent._natives.start;
8278               }
8279
8280               // p.cue( "my-id", function() { ... });
8281               // The path will update the cue function
8282               if ( typeof time === "function" ) {
8283                 fn = time;
8284                 // Re-use existing TrackEvent start time
8285                 time = trackEvent.start;
8286               }
8287             }
8288           } else {
8289
8290             if ( length >= 2 ) {
8291
8292               // p.cue( "a", "00:00:00");
8293               if ( typeof time === "string" ) {
8294                 try {
8295                   sec = Popcorn.util.toSeconds( time );
8296                 } catch ( e ) {}
8297
8298                 time = sec;
8299               }
8300
8301               // p.cue( "b", 11 );
8302               // p.cue( "b", 11, function() {} );
8303               if ( typeof time === "number" ) {
8304                 fn = fn || Popcorn.nop();
8305               }
8306
8307               // p.cue( "c", function() {});
8308               if ( typeof time === "function" ) {
8309                 fn = time;
8310                 time = -1;
8311               }
8312             }
8313           }
8314         }
8315       }
8316
8317       options = {
8318         id: id,
8319         start: time,
8320         end: time + 1,
8321         _running: false,
8322         _natives: {
8323           start: fn || Popcorn.nop,
8324           end: Popcorn.nop,
8325           type: "cue"
8326         }
8327       };
8328
8329       if ( trackEvent ) {
8330         options = Popcorn.extend( trackEvent, options );
8331       }
8332
8333       if ( eventType === "cuechange" ) {
8334
8335         //  Supports user defined track event id
8336         options._id = options.id || options._id || Popcorn.guid( options._natives.type );
8337
8338         this.data.trackEvents.add( options );
8339         TrackEvent.start( this, options );
8340
8341         this.timeUpdate( this, null, true );
8342
8343         // Store references to user added trackevents in ref table
8344         Popcorn.addTrackEvent.ref( this, options );
8345
8346         this.emit( eventType, Popcorn.extend({}, options, {
8347           id: id,
8348           type: eventType,
8349           previousValue: {
8350             time: trackEvent.start,
8351             fn: trackEvent._natives.start
8352           },
8353           currentValue: {
8354             time: time,
8355             fn: fn || Popcorn.nop
8356           },
8357           track: trackEvent
8358         }));
8359       } else {
8360         //  Creating a one second track event with an empty end
8361         Popcorn.addTrackEvent( this, options );
8362       }
8363
8364       return this;
8365     },
8366
8367     // Mute the calling media, optionally toggle
8368     mute: function( toggle ) {
8369
8370       var event = toggle == null || toggle === true ? "muted" : "unmuted";
8371
8372       // If `toggle` is explicitly `false`,
8373       // unmute the media and restore the volume level
8374       if ( event === "unmuted" ) {
8375         this.media.muted = false;
8376         this.media.volume = this.data.state.volume;
8377       }
8378
8379       // If `toggle` is either null or undefined,
8380       // save the current volume and mute the media element
8381       if ( event === "muted" ) {
8382         this.data.state.volume = this.media.volume;
8383         this.media.muted = true;
8384       }
8385
8386       // Trigger either muted|unmuted event
8387       this.emit( event );
8388
8389       return this;
8390     },
8391
8392     // Convenience method, unmute the calling media
8393     unmute: function( toggle ) {
8394
8395       return this.mute( toggle == null ? false : !toggle );
8396     },
8397
8398     // Get the client bounding box of an instance element
8399     position: function() {
8400       return Popcorn.position( this.media );
8401     },
8402
8403     // Toggle a plugin's playback behaviour (on or off) per instance
8404     toggle: function( plugin ) {
8405       return Popcorn[ this.data.disabled[ plugin ] ? "enable" : "disable" ]( this, plugin );
8406     },
8407
8408     // Set default values for plugin options objects per instance
8409     defaults: function( plugin, defaults ) {
8410
8411       // If an array of default configurations is provided,
8412       // iterate and apply each to this instance
8413       if ( Popcorn.isArray( plugin ) ) {
8414
8415         Popcorn.forEach( plugin, function( obj ) {
8416           for ( var name in obj ) {
8417             this.defaults( name, obj[ name ] );
8418           }
8419         }, this );
8420
8421         return this;
8422       }
8423
8424       if ( !this.options.defaults ) {
8425         this.options.defaults = {};
8426       }
8427
8428       if ( !this.options.defaults[ plugin ] ) {
8429         this.options.defaults[ plugin ] = {};
8430       }
8431
8432       Popcorn.extend( this.options.defaults[ plugin ], defaults );
8433
8434       return this;
8435     }
8436   });
8437
8438   Popcorn.Events  = {
8439     UIEvents: "blur focus focusin focusout load resize scroll unload",
8440     MouseEvents: "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave click dblclick",
8441     Events: "loadstart progress suspend emptied stalled play pause error " +
8442             "loadedmetadata loadeddata waiting playing canplay canplaythrough " +
8443             "seeking seeked timeupdate ended ratechange durationchange volumechange"
8444   };
8445
8446   Popcorn.Events.Natives = Popcorn.Events.UIEvents + " " +
8447                            Popcorn.Events.MouseEvents + " " +
8448                            Popcorn.Events.Events;
8449
8450   internal.events.apiTypes = [ "UIEvents", "MouseEvents", "Events" ];
8451
8452   // Privately compile events table at load time
8453   (function( events, data ) {
8454
8455     var apis = internal.events.apiTypes,
8456     eventsList = events.Natives.split( /\s+/g ),
8457     idx = 0, len = eventsList.length, prop;
8458
8459     for( ; idx < len; idx++ ) {
8460       data.hash[ eventsList[idx] ] = true;
8461     }
8462
8463     apis.forEach(function( val, idx ) {
8464
8465       data.apis[ val ] = {};
8466
8467       var apiEvents = events[ val ].split( /\s+/g ),
8468       len = apiEvents.length,
8469       k = 0;
8470
8471       for ( ; k < len; k++ ) {
8472         data.apis[ val ][ apiEvents[ k ] ] = true;
8473       }
8474     });
8475   })( Popcorn.Events, internal.events );
8476
8477   Popcorn.events = {
8478
8479     isNative: function( type ) {
8480       return !!internal.events.hash[ type ];
8481     },
8482     getInterface: function( type ) {
8483
8484       if ( !Popcorn.events.isNative( type ) ) {
8485         return false;
8486       }
8487
8488       var eventApi = internal.events,
8489         apis = eventApi.apiTypes,
8490         apihash = eventApi.apis,
8491         idx = 0, len = apis.length, api, tmp;
8492
8493       for ( ; idx < len; idx++ ) {
8494         tmp = apis[ idx ];
8495
8496         if ( apihash[ tmp ][ type ] ) {
8497           api = tmp;
8498           break;
8499         }
8500       }
8501       return api;
8502     },
8503     //  Compile all native events to single array
8504     all: Popcorn.Events.Natives.split( /\s+/g ),
8505     //  Defines all Event handling static functions
8506     fn: {
8507       trigger: function( type, data ) {
8508         var eventInterface, evt, clonedEvents,
8509             events = this.data.events[ type ];
8510
8511         //  setup checks for custom event system
8512         if ( events ) {
8513           eventInterface  = Popcorn.events.getInterface( type );
8514
8515           if ( eventInterface ) {
8516             evt = document.createEvent( eventInterface );
8517             evt.initEvent( type, true, true, global, 1 );
8518
8519             this.media.dispatchEvent( evt );
8520
8521             return this;
8522           }
8523
8524           // clone events in case callbacks remove callbacks themselves
8525           clonedEvents = events.slice();
8526
8527           // iterate through all callbacks
8528           while ( clonedEvents.length ) {
8529             clonedEvents.shift().call( this, data );
8530           }
8531         }
8532
8533         return this;
8534       },
8535       listen: function( type, fn ) {
8536         var self = this,
8537             hasEvents = true,
8538             eventHook = Popcorn.events.hooks[ type ],
8539             origType = type,
8540             clonedEvents,
8541             tmp;
8542
8543         if ( typeof fn !== "function" ) {
8544           throw new Error( "Popcorn.js Error: Listener is not a function" );
8545         }
8546
8547         // Setup event registry entry
8548         if ( !this.data.events[ type ] ) {
8549           this.data.events[ type ] = [];
8550           // Toggle if the previous assumption was untrue
8551           hasEvents = false;
8552         }
8553
8554         // Check and setup event hooks
8555         if ( eventHook ) {
8556           // Execute hook add method if defined
8557           if ( eventHook.add ) {
8558             eventHook.add.call( this, {}, fn );
8559           }
8560
8561           // Reassign event type to our piggyback event type if defined
8562           if ( eventHook.bind ) {
8563             type = eventHook.bind;
8564           }
8565
8566           // Reassign handler if defined
8567           if ( eventHook.handler ) {
8568             tmp = fn;
8569
8570             fn = function wrapper( event ) {
8571               eventHook.handler.call( self, event, tmp );
8572             };
8573           }
8574
8575           // assume the piggy back event is registered
8576           hasEvents = true;
8577
8578           // Setup event registry entry
8579           if ( !this.data.events[ type ] ) {
8580             this.data.events[ type ] = [];
8581             // Toggle if the previous assumption was untrue
8582             hasEvents = false;
8583           }
8584         }
8585
8586         //  Register event and handler
8587         this.data.events[ type ].push( fn );
8588
8589         // only attach one event of any type
8590         if ( !hasEvents && Popcorn.events.all.indexOf( type ) > -1 ) {
8591           this.media.addEventListener( type, function( event ) {
8592             if ( self.data.events[ type ] ) {
8593               // clone events in case callbacks remove callbacks themselves
8594               clonedEvents = self.data.events[ type ].slice();
8595
8596               // iterate through all callbacks
8597               while ( clonedEvents.length ) {
8598                 clonedEvents.shift().call( self, event );
8599               }
8600             }
8601           }, false );
8602         }
8603         return this;
8604       },
8605       unlisten: function( type, fn ) {
8606         var ind,
8607             events = this.data.events[ type ];
8608
8609         if ( !events ) {
8610           return; // no listeners = nothing to do
8611         }
8612
8613         if ( typeof fn === "string" ) {
8614           // legacy support for string-based removal -- not recommended
8615           for ( var i = 0; i < events.length; i++ ) {
8616             if ( events[ i ].name === fn ) {
8617               // decrement i because array length just got smaller
8618               events.splice( i--, 1 );
8619             }
8620           }
8621
8622           return this;
8623         } else if ( typeof fn === "function" ) {
8624           while( ind !== -1 ) {
8625             ind = events.indexOf( fn );
8626             if ( ind !== -1 ) {
8627               events.splice( ind, 1 );
8628             }
8629           }
8630
8631           return this;
8632         }
8633
8634         // if we got to this point, we are deleting all functions of this type
8635         this.data.events[ type ] = null;
8636
8637         return this;
8638       }
8639     },
8640     hooks: {
8641       canplayall: {
8642         bind: "canplaythrough",
8643         add: function( event, callback ) {
8644
8645           var state = false;
8646
8647           if ( this.media.readyState ) {
8648
8649             // always call canplayall asynchronously
8650             setTimeout(function() {
8651               callback.call( this, event );
8652             }.bind(this), 0 );
8653
8654             state = true;
8655           }
8656
8657           this.data.hooks.canplayall = {
8658             fired: state
8659           };
8660         },
8661         // declare special handling instructions
8662         handler: function canplayall( event, callback ) {
8663
8664           if ( !this.data.hooks.canplayall.fired ) {
8665             // trigger original user callback once
8666             callback.call( this, event );
8667
8668             this.data.hooks.canplayall.fired = true;
8669           }
8670         }
8671       }
8672     }
8673   };
8674
8675   //  Extend Popcorn.events.fns (listen, unlisten, trigger) to all Popcorn instances
8676   //  Extend aliases (on, off, emit)
8677   Popcorn.forEach( [ [ "trigger", "emit" ], [ "listen", "on" ], [ "unlisten", "off" ] ], function( key ) {
8678     Popcorn.p[ key[ 0 ] ] = Popcorn.p[ key[ 1 ] ] = Popcorn.events.fn[ key[ 0 ] ];
8679   });
8680
8681   // Internal Only - construct simple "TrackEvent"
8682   // data type objects
8683   function TrackEvent( track ) {
8684     Abstract.put.call( this, track );
8685   }
8686
8687   // Determine if a TrackEvent's "start" and "trackstart" must be called.
8688   TrackEvent.start = function( instance, track ) {
8689
8690     if ( track.end > instance.media.currentTime &&
8691         track.start <= instance.media.currentTime && !track._running ) {
8692
8693       track._running = true;
8694       instance.data.running[ track._natives.type ].push( track );
8695
8696       if ( !instance.data.disabled[ track._natives.type ] ) {
8697
8698         track._natives.start.call( instance, null, track );
8699
8700         instance.emit( "trackstart",
8701           Popcorn.extend( {}, track, {
8702             plugin: track._natives.type,
8703             type: "trackstart",
8704             track: track
8705           })
8706         );
8707       }
8708     }
8709   };
8710
8711   // Determine if a TrackEvent's "end" and "trackend" must be called.
8712   TrackEvent.end = function( instance, track ) {
8713
8714     var runningPlugins;
8715
8716     if ( ( track.end <= instance.media.currentTime ||
8717         track.start > instance.media.currentTime ) && track._running ) {
8718
8719       runningPlugins = instance.data.running[ track._natives.type ];
8720
8721       track._running = false;
8722       runningPlugins.splice( runningPlugins.indexOf( track ), 1 );
8723
8724       if ( !instance.data.disabled[ track._natives.type ] ) {
8725
8726         track._natives.end.call( instance, null, track );
8727
8728         instance.emit( "trackend",
8729           Popcorn.extend( {}, track, {
8730             plugin: track._natives.type,
8731             type: "trackend",
8732             track: track
8733           })
8734         );
8735       }
8736     }
8737   };
8738
8739   // Internal Only - construct "TrackEvents"
8740   // data type objects that are used by the Popcorn
8741   // instance, stored at p.data.trackEvents
8742   function TrackEvents( parent ) {
8743     this.parent = parent;
8744
8745     this.byStart = [{
8746       start: -1,
8747       end: -1
8748     }];
8749
8750     this.byEnd = [{
8751       start: -1,
8752       end: -1
8753     }];
8754     this.animating = [];
8755     this.startIndex = 0;
8756     this.endIndex = 0;
8757     this.previousUpdateTime = -1;
8758
8759     Object.defineProperty( this, "count", {
8760       get: function() {
8761         return this.byStart.length;
8762       }
8763     });
8764   }
8765
8766   function isMatch( obj, key, value ) {
8767     return obj[ key ] && obj[ key ] === value;
8768   }
8769
8770   TrackEvents.prototype.where = function( params ) {
8771     return ( this.parent.getTrackEvents() || [] ).filter(function( event ) {
8772       var key, value;
8773
8774       // If no explicit params, match all TrackEvents
8775       if ( !params ) {
8776         return true;
8777       }
8778
8779       // Filter keys in params against both the top level properties
8780       // and the _natives properties
8781       for ( key in params ) {
8782         value = params[ key ];
8783         if ( isMatch( event, key, value ) || isMatch( event._natives, key, value ) ) {
8784           return true;
8785         }
8786       }
8787       return false;
8788     });
8789   };
8790
8791   TrackEvents.prototype.add = function( track ) {
8792
8793     //  Store this definition in an array sorted by times
8794     var byStart = this.byStart,
8795         byEnd = this.byEnd,
8796         startIndex, endIndex;
8797
8798     //  Push track event ids into the history
8799     if ( track && track._id ) {
8800       this.parent.data.history.push( track._id );
8801     }
8802
8803     track.start = Popcorn.util.toSeconds( track.start, this.parent.options.framerate );
8804     track.end   = Popcorn.util.toSeconds( track.end, this.parent.options.framerate );
8805
8806     for ( startIndex = byStart.length - 1; startIndex >= 0; startIndex-- ) {
8807
8808       if ( track.start >= byStart[ startIndex ].start ) {
8809         byStart.splice( startIndex + 1, 0, track );
8810         break;
8811       }
8812     }
8813
8814     for ( endIndex = byEnd.length - 1; endIndex >= 0; endIndex-- ) {
8815
8816       if ( track.end > byEnd[ endIndex ].end ) {
8817         byEnd.splice( endIndex + 1, 0, track );
8818         break;
8819       }
8820     }
8821
8822     // update startIndex and endIndex
8823     if ( startIndex <= this.parent.data.trackEvents.startIndex &&
8824       track.start <= this.parent.data.trackEvents.previousUpdateTime ) {
8825
8826       this.parent.data.trackEvents.startIndex++;
8827     }
8828
8829     if ( endIndex <= this.parent.data.trackEvents.endIndex &&
8830       track.end < this.parent.data.trackEvents.previousUpdateTime ) {
8831
8832       this.parent.data.trackEvents.endIndex++;
8833     }
8834
8835   };
8836
8837   TrackEvents.prototype.remove = function( removeId, state ) {
8838
8839     if ( removeId instanceof TrackEvent ) {
8840       removeId = removeId.id;
8841     }
8842
8843     if ( typeof removeId === "object" ) {
8844       // Filter by key=val and remove all matching TrackEvents
8845       this.where( removeId ).forEach(function( event ) {
8846         // |this| refers to the calling Popcorn "parent" instance
8847         this.removeTrackEvent( event._id );
8848       }, this.parent );
8849
8850       return this;
8851     }
8852
8853     var start, end, animate, historyLen, track,
8854         length = this.byStart.length,
8855         index = 0,
8856         indexWasAt = 0,
8857         byStart = [],
8858         byEnd = [],
8859         animating = [],
8860         history = [],
8861         comparable = {};
8862
8863     state = state || {};
8864
8865     while ( --length > -1 ) {
8866       start = this.byStart[ index ];
8867       end = this.byEnd[ index ];
8868
8869       // Padding events will not have _id properties.
8870       // These should be safely pushed onto the front and back of the
8871       // track event array
8872       if ( !start._id ) {
8873         byStart.push( start );
8874         byEnd.push( end );
8875       }
8876
8877       // Filter for user track events (vs system track events)
8878       if ( start._id ) {
8879
8880         // If not a matching start event for removal
8881         if ( start._id !== removeId ) {
8882           byStart.push( start );
8883         }
8884
8885         // If not a matching end event for removal
8886         if ( end._id !== removeId ) {
8887           byEnd.push( end );
8888         }
8889
8890         // If the _id is matched, capture the current index
8891         if ( start._id === removeId ) {
8892           indexWasAt = index;
8893
8894           // cache the track event being removed
8895           track = start;
8896         }
8897       }
8898       // Increment the track index
8899       index++;
8900     }
8901
8902     // Reset length to be used by the condition below to determine
8903     // if animating track events should also be filtered for removal.
8904     // Reset index below to be used by the reverse while as an
8905     // incrementing counter
8906     length = this.animating.length;
8907     index = 0;
8908
8909     if ( length ) {
8910       while ( --length > -1 ) {
8911         animate = this.animating[ index ];
8912
8913         // Padding events will not have _id properties.
8914         // These should be safely pushed onto the front and back of the
8915         // track event array
8916         if ( !animate._id ) {
8917           animating.push( animate );
8918         }
8919
8920         // If not a matching animate event for removal
8921         if ( animate._id && animate._id !== removeId ) {
8922           animating.push( animate );
8923         }
8924         // Increment the track index
8925         index++;
8926       }
8927     }
8928
8929     //  Update
8930     if ( indexWasAt <= this.startIndex ) {
8931       this.startIndex--;
8932     }
8933
8934     if ( indexWasAt <= this.endIndex ) {
8935       this.endIndex--;
8936     }
8937
8938     this.byStart = byStart;
8939     this.byEnd = byEnd;
8940     this.animating = animating;
8941
8942     historyLen = this.parent.data.history.length;
8943
8944     for ( var i = 0; i < historyLen; i++ ) {
8945       if ( this.parent.data.history[ i ] !== removeId ) {
8946         history.push( this.parent.data.history[ i ] );
8947       }
8948     }
8949
8950     // Update ordered history array
8951     this.parent.data.history = history;
8952
8953   };
8954
8955   // Helper function used to retrieve old values of properties that
8956   // are provided for update.
8957   function getPreviousProperties( oldOptions, newOptions ) {
8958     var matchProps = {};
8959
8960     for ( var prop in oldOptions ) {
8961       if ( hasOwn.call( newOptions, prop ) && hasOwn.call( oldOptions, prop ) ) {
8962         matchProps[ prop ] = oldOptions[ prop ];
8963       }
8964     }
8965
8966     return matchProps;
8967   }
8968
8969   // Internal Only - Adds track events to the instance object
8970   Popcorn.addTrackEvent = function( obj, track ) {
8971     var temp;
8972
8973     if ( track instanceof TrackEvent ) {
8974       return;
8975     }
8976
8977     track = new TrackEvent( track );
8978
8979     // Determine if this track has default options set for it
8980     // If so, apply them to the track object
8981     if ( track && track._natives && track._natives.type &&
8982         ( obj.options.defaults && obj.options.defaults[ track._natives.type ] ) ) {
8983
8984       // To ensure that the TrackEvent Invariant Policy is enforced,
8985       // First, copy the properties of the newly created track event event
8986       // to a temporary holder
8987       temp = Popcorn.extend( {}, track );
8988
8989       // Next, copy the default onto the newly created trackevent, followed by the
8990       // temporary holder.
8991       Popcorn.extend( track, obj.options.defaults[ track._natives.type ], temp );
8992     }
8993
8994     if ( track._natives ) {
8995       //  Supports user defined track event id
8996       track._id = track.id || track._id || Popcorn.guid( track._natives.type );
8997
8998       // Trigger _setup method if exists
8999       if ( track._natives._setup ) {
9000
9001         track._natives._setup.call( obj, track );
9002
9003         obj.emit( "tracksetup", Popcorn.extend( {}, track, {
9004           plugin: track._natives.type,
9005           type: "tracksetup",
9006           track: track
9007         }));
9008       }
9009     }
9010
9011     obj.data.trackEvents.add( track );
9012     TrackEvent.start( obj, track );
9013
9014     this.timeUpdate( obj, null, true );
9015
9016     // Store references to user added trackevents in ref table
9017     if ( track._id ) {
9018       Popcorn.addTrackEvent.ref( obj, track );
9019     }
9020
9021     obj.emit( "trackadded", Popcorn.extend({}, track,
9022       track._natives ? { plugin: track._natives.type } : {}, {
9023         type: "trackadded",
9024         track: track
9025     }));
9026   };
9027
9028   // Internal Only - Adds track event references to the instance object's trackRefs hash table
9029   Popcorn.addTrackEvent.ref = function( obj, track ) {
9030     obj.data.trackRefs[ track._id ] = track;
9031
9032     return obj;
9033   };
9034
9035   Popcorn.removeTrackEvent = function( obj, removeId ) {
9036     var track = obj.getTrackEvent( removeId );
9037
9038     if ( !track ) {
9039       return;
9040     }
9041
9042     // If a _teardown function was defined,
9043     // enforce for track event removals
9044     if ( track._natives._teardown ) {
9045       track._natives._teardown.call( obj, track );
9046     }
9047
9048     obj.data.trackEvents.remove( removeId );
9049
9050     // Update track event references
9051     Popcorn.removeTrackEvent.ref( obj, removeId );
9052
9053     if ( track._natives ) {
9054
9055       // Fire a trackremoved event
9056       obj.emit( "trackremoved", Popcorn.extend({}, track, {
9057         plugin: track._natives.type,
9058         type: "trackremoved",
9059         track: track
9060       }));
9061     }
9062   };
9063
9064   // Internal Only - Removes track event references from instance object's trackRefs hash table
9065   Popcorn.removeTrackEvent.ref = function( obj, removeId ) {
9066     delete obj.data.trackRefs[ removeId ];
9067
9068     return obj;
9069   };
9070
9071   // Return an array of track events bound to this instance object
9072   Popcorn.getTrackEvents = function( obj ) {
9073
9074     var trackevents = [],
9075       refs = obj.data.trackEvents.byStart,
9076       length = refs.length,
9077       idx = 0,
9078       ref;
9079
9080     for ( ; idx < length; idx++ ) {
9081       ref = refs[ idx ];
9082       // Return only user attributed track event references
9083       if ( ref._id ) {
9084         trackevents.push( ref );
9085       }
9086     }
9087
9088     return trackevents;
9089   };
9090
9091   // Internal Only - Returns an instance object's trackRefs hash table
9092   Popcorn.getTrackEvents.ref = function( obj ) {
9093     return obj.data.trackRefs;
9094   };
9095
9096   // Return a single track event bound to this instance object
9097   Popcorn.getTrackEvent = function( obj, trackId ) {
9098     return obj.data.trackRefs[ trackId ];
9099   };
9100
9101   // Internal Only - Returns an instance object's track reference by track id
9102   Popcorn.getTrackEvent.ref = function( obj, trackId ) {
9103     return obj.data.trackRefs[ trackId ];
9104   };
9105
9106   Popcorn.getLastTrackEventId = function( obj ) {
9107     return obj.data.history[ obj.data.history.length - 1 ];
9108   };
9109
9110   Popcorn.timeUpdate = function( obj, event ) {
9111     var currentTime = obj.media.currentTime,
9112         previousTime = obj.data.trackEvents.previousUpdateTime,
9113         tracks = obj.data.trackEvents,
9114         end = tracks.endIndex,
9115         start = tracks.startIndex,
9116         byStartLen = tracks.byStart.length,
9117         byEndLen = tracks.byEnd.length,
9118         registryByName = Popcorn.registryByName,
9119         trackstart = "trackstart",
9120         trackend = "trackend",
9121
9122         byEnd, byStart, byAnimate, natives, type, runningPlugins;
9123
9124     //  Playbar advancing
9125     if ( previousTime <= currentTime ) {
9126
9127       while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end <= currentTime ) {
9128
9129         byEnd = tracks.byEnd[ end ];
9130         natives = byEnd._natives;
9131         type = natives && natives.type;
9132
9133         //  If plugin does not exist on this instance, remove it
9134         if ( !natives ||
9135             ( !!registryByName[ type ] ||
9136               !!obj[ type ] ) ) {
9137
9138           if ( byEnd._running === true ) {
9139
9140             byEnd._running = false;
9141             runningPlugins = obj.data.running[ type ];
9142             runningPlugins.splice( runningPlugins.indexOf( byEnd ), 1 );
9143
9144             if ( !obj.data.disabled[ type ] ) {
9145
9146               natives.end.call( obj, event, byEnd );
9147
9148               obj.emit( trackend,
9149                 Popcorn.extend({}, byEnd, {
9150                   plugin: type,
9151                   type: trackend,
9152                   track: byEnd
9153                 })
9154               );
9155             }
9156           }
9157
9158           end++;
9159         } else {
9160           // remove track event
9161           Popcorn.removeTrackEvent( obj, byEnd._id );
9162           return;
9163         }
9164       }
9165
9166       while ( tracks.byStart[ start ] && tracks.byStart[ start ].start <= currentTime ) {
9167
9168         byStart = tracks.byStart[ start ];
9169         natives = byStart._natives;
9170         type = natives && natives.type;
9171         //  If plugin does not exist on this instance, remove it
9172         if ( !natives ||
9173             ( !!registryByName[ type ] ||
9174               !!obj[ type ] ) ) {
9175           if ( byStart.end > currentTime &&
9176                 byStart._running === false ) {
9177
9178             byStart._running = true;
9179             obj.data.running[ type ].push( byStart );
9180
9181             if ( !obj.data.disabled[ type ] ) {
9182
9183               natives.start.call( obj, event, byStart );
9184
9185               obj.emit( trackstart,
9186                 Popcorn.extend({}, byStart, {
9187                   plugin: type,
9188                   type: trackstart,
9189                   track: byStart
9190                 })
9191               );
9192             }
9193           }
9194           start++;
9195         } else {
9196           // remove track event
9197           Popcorn.removeTrackEvent( obj, byStart._id );
9198           return;
9199         }
9200       }
9201
9202     // Playbar receding
9203     } else if ( previousTime > currentTime ) {
9204
9205       while ( tracks.byStart[ start ] && tracks.byStart[ start ].start > currentTime ) {
9206
9207         byStart = tracks.byStart[ start ];
9208         natives = byStart._natives;
9209         type = natives && natives.type;
9210
9211         // if plugin does not exist on this instance, remove it
9212         if ( !natives ||
9213             ( !!registryByName[ type ] ||
9214               !!obj[ type ] ) ) {
9215
9216           if ( byStart._running === true ) {
9217
9218             byStart._running = false;
9219             runningPlugins = obj.data.running[ type ];
9220             runningPlugins.splice( runningPlugins.indexOf( byStart ), 1 );
9221
9222             if ( !obj.data.disabled[ type ] ) {
9223
9224               natives.end.call( obj, event, byStart );
9225
9226               obj.emit( trackend,
9227                 Popcorn.extend({}, byStart, {
9228                   plugin: type,
9229                   type: trackend,
9230                   track: byStart
9231                 })
9232               );
9233             }
9234           }
9235           start--;
9236         } else {
9237           // remove track event
9238           Popcorn.removeTrackEvent( obj, byStart._id );
9239           return;
9240         }
9241       }
9242
9243       while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end > currentTime ) {
9244
9245         byEnd = tracks.byEnd[ end ];
9246         natives = byEnd._natives;
9247         type = natives && natives.type;
9248
9249         // if plugin does not exist on this instance, remove it
9250         if ( !natives ||
9251             ( !!registryByName[ type ] ||
9252               !!obj[ type ] ) ) {
9253
9254           if ( byEnd.start <= currentTime &&
9255                 byEnd._running === false ) {
9256
9257             byEnd._running = true;
9258             obj.data.running[ type ].push( byEnd );
9259
9260             if ( !obj.data.disabled[ type ] ) {
9261
9262               natives.start.call( obj, event, byEnd );
9263
9264               obj.emit( trackstart,
9265                 Popcorn.extend({}, byEnd, {
9266                   plugin: type,
9267                   type: trackstart,
9268                   track: byEnd
9269                 })
9270               );
9271             }
9272           }
9273           end--;
9274         } else {
9275           // remove track event
9276           Popcorn.removeTrackEvent( obj, byEnd._id );
9277           return;
9278         }
9279       }
9280     }
9281
9282     tracks.endIndex = end;
9283     tracks.startIndex = start;
9284     tracks.previousUpdateTime = currentTime;
9285
9286     //enforce index integrity if trackRemoved
9287     tracks.byStart.length < byStartLen && tracks.startIndex--;
9288     tracks.byEnd.length < byEndLen && tracks.endIndex--;
9289
9290   };
9291
9292   //  Map and Extend TrackEvent functions to all Popcorn instances
9293   Popcorn.extend( Popcorn.p, {
9294
9295     getTrackEvents: function() {
9296       return Popcorn.getTrackEvents.call( null, this );
9297     },
9298
9299     getTrackEvent: function( id ) {
9300       return Popcorn.getTrackEvent.call( null, this, id );
9301     },
9302
9303     getLastTrackEventId: function() {
9304       return Popcorn.getLastTrackEventId.call( null, this );
9305     },
9306
9307     removeTrackEvent: function( id ) {
9308
9309       Popcorn.removeTrackEvent.call( null, this, id );
9310       return this;
9311     },
9312
9313     removePlugin: function( name ) {
9314       Popcorn.removePlugin.call( null, this, name );
9315       return this;
9316     },
9317
9318     timeUpdate: function( event ) {
9319       Popcorn.timeUpdate.call( null, this, event );
9320       return this;
9321     },
9322
9323     destroy: function() {
9324       Popcorn.destroy.call( null, this );
9325       return this;
9326     }
9327   });
9328
9329   //  Plugin manifests
9330   Popcorn.manifest = {};
9331   //  Plugins are registered
9332   Popcorn.registry = [];
9333   Popcorn.registryByName = {};
9334   //  An interface for extending Popcorn
9335   //  with plugin functionality
9336   Popcorn.plugin = function( name, definition, manifest ) {
9337
9338     if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
9339       Popcorn.error( "'" + name + "' is a protected function name" );
9340       return;
9341     }
9342
9343     //  Provides some sugar, but ultimately extends
9344     //  the definition into Popcorn.p
9345     var isfn = typeof definition === "function",
9346         blacklist = [ "start", "end", "type", "manifest" ],
9347         methods = [ "_setup", "_teardown", "start", "end", "frame" ],
9348         plugin = {},
9349         setup;
9350
9351     // combines calls of two function calls into one
9352     var combineFn = function( first, second ) {
9353
9354       first = first || Popcorn.nop;
9355       second = second || Popcorn.nop;
9356
9357       return function() {
9358         first.apply( this, arguments );
9359         second.apply( this, arguments );
9360       };
9361     };
9362
9363     //  If `manifest` arg is undefined, check for manifest within the `definition` object
9364     //  If no `definition.manifest`, an empty object is a sufficient fallback
9365     Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {};
9366
9367     // apply safe, and empty default functions
9368     methods.forEach(function( method ) {
9369       definition[ method ] = safeTry( definition[ method ] || Popcorn.nop, name );
9370     });
9371
9372     var pluginFn = function( setup, options ) {
9373
9374       if ( !options ) {
9375         return this;
9376       }
9377
9378       // When the "ranges" property is set and its value is an array, short-circuit
9379       // the pluginFn definition to recall itself with an options object generated from
9380       // each range object in the ranges array. (eg. { start: 15, end: 16 } )
9381       if ( options.ranges && Popcorn.isArray(options.ranges) ) {
9382         Popcorn.forEach( options.ranges, function( range ) {
9383           // Create a fresh object, extend with current options
9384           // and start/end range object's properties
9385           // Works with in/out as well.
9386           var opts = Popcorn.extend( {}, options, range );
9387
9388           // Remove the ranges property to prevent infinitely
9389           // entering this condition
9390           delete opts.ranges;
9391
9392           // Call the plugin with the newly created opts object
9393           this[ name ]( opts );
9394         }, this);
9395
9396         // Return the Popcorn instance to avoid creating an empty track event
9397         return this;
9398       }
9399
9400       //  Storing the plugin natives
9401       var natives = options._natives = {},
9402           compose = "",
9403           originalOpts, manifestOpts;
9404
9405       Popcorn.extend( natives, setup );
9406
9407       options._natives.type = options._natives.plugin = name;
9408       options._running = false;
9409
9410       natives.start = natives.start || natives[ "in" ];
9411       natives.end = natives.end || natives[ "out" ];
9412
9413       if ( options.once ) {
9414         natives.end = combineFn( natives.end, function() {
9415           this.removeTrackEvent( options._id );
9416         });
9417       }
9418
9419       // extend teardown to always call end if running
9420       natives._teardown = combineFn(function() {
9421
9422         var args = slice.call( arguments ),
9423             runningPlugins = this.data.running[ natives.type ];
9424
9425         // end function signature is not the same as teardown,
9426         // put null on the front of arguments for the event parameter
9427         args.unshift( null );
9428
9429         // only call end if event is running
9430         args[ 1 ]._running &&
9431           runningPlugins.splice( runningPlugins.indexOf( options ), 1 ) &&
9432           natives.end.apply( this, args );
9433
9434         args[ 1 ]._running = false;
9435         this.emit( "trackend",
9436           Popcorn.extend( {}, options, {
9437             plugin: natives.type,
9438             type: "trackend",
9439             track: Popcorn.getTrackEvent( this, options.id || options._id )
9440           })
9441         );
9442       }, natives._teardown );
9443
9444       // extend teardown to always trigger trackteardown after teardown
9445       natives._teardown = combineFn( natives._teardown, function() {
9446
9447         this.emit( "trackteardown", Popcorn.extend( {}, options, {
9448           plugin: name,
9449           type: "trackteardown",
9450           track: Popcorn.getTrackEvent( this, options.id || options._id )
9451         }));
9452       });
9453
9454       // default to an empty string if no effect exists
9455       // split string into an array of effects
9456       options.compose = options.compose || [];
9457       if ( typeof options.compose === "string" ) {
9458         options.compose = options.compose.split( " " );
9459       }
9460       options.effect = options.effect || [];
9461       if ( typeof options.effect === "string" ) {
9462         options.effect = options.effect.split( " " );
9463       }
9464
9465       // join the two arrays together
9466       options.compose = options.compose.concat( options.effect );
9467
9468       options.compose.forEach(function( composeOption ) {
9469
9470         // if the requested compose is garbage, throw it away
9471         compose = Popcorn.compositions[ composeOption ] || {};
9472
9473         // extends previous functions with compose function
9474         methods.forEach(function( method ) {
9475           natives[ method ] = combineFn( natives[ method ], compose[ method ] );
9476         });
9477       });
9478
9479       //  Ensure a manifest object, an empty object is a sufficient fallback
9480       options._natives.manifest = manifest;
9481
9482       //  Checks for expected properties
9483       if ( !( "start" in options ) ) {
9484         options.start = options[ "in" ] || 0;
9485       }
9486
9487       if ( !options.end && options.end !== 0 ) {
9488         options.end = options[ "out" ] || Number.MAX_VALUE;
9489       }
9490
9491       // Use hasOwn to detect non-inherited toString, since all
9492       // objects will receive a toString - its otherwise undetectable
9493       if ( !hasOwn.call( options, "toString" ) ) {
9494         options.toString = function() {
9495           var props = [
9496             "start: " + options.start,
9497             "end: " + options.end,
9498             "id: " + (options.id || options._id)
9499           ];
9500
9501           // Matches null and undefined, allows: false, 0, "" and truthy
9502           if ( options.target != null ) {
9503             props.push( "target: " + options.target );
9504           }
9505
9506           return name + " ( " + props.join(", ") + " )";
9507         };
9508       }
9509
9510       // Resolves 239, 241, 242
9511       if ( !options.target ) {
9512
9513         //  Sometimes the manifest may be missing entirely
9514         //  or it has an options object that doesn't have a `target` property
9515         manifestOpts = "options" in manifest && manifest.options;
9516
9517         options.target = manifestOpts && "target" in manifestOpts && manifestOpts.target;
9518       }
9519
9520       if ( !options._id && options._natives ) {
9521         // ensure an initial id is there before setup is called
9522         options._id = Popcorn.guid( options._natives.type );
9523       }
9524
9525       if ( options instanceof TrackEvent ) {
9526
9527         if ( options._natives ) {
9528           //  Supports user defined track event id
9529           options._id = options.id || options._id || Popcorn.guid( options._natives.type );
9530
9531           // Trigger _setup method if exists
9532           if ( options._natives._setup ) {
9533
9534             options._natives._setup.call( this, options );
9535
9536             this.emit( "tracksetup", Popcorn.extend( {}, options, {
9537               plugin: options._natives.type,
9538               type: "tracksetup",
9539               track: options
9540             }));
9541           }
9542         }
9543
9544         this.data.trackEvents.add( options );
9545         TrackEvent.start( this, options );
9546
9547         this.timeUpdate( this, null, true );
9548
9549         // Store references to user added trackevents in ref table
9550         if ( options._id ) {
9551           Popcorn.addTrackEvent.ref( this, options );
9552         }
9553       } else {
9554         // Create new track event for this instance
9555         Popcorn.addTrackEvent( this, options );
9556       }
9557
9558       //  Future support for plugin event definitions
9559       //  for all of the native events
9560       Popcorn.forEach( setup, function( callback, type ) {
9561         // Don't attempt to create events for certain properties:
9562         // "start", "end", "type", "manifest". Fixes #1365
9563         if ( blacklist.indexOf( type ) === -1 ) {
9564           this.on( type, callback );
9565         }
9566       }, this );
9567
9568       return this;
9569     };
9570
9571     //  Extend Popcorn.p with new named definition
9572     //  Assign new named definition
9573     Popcorn.p[ name ] = plugin[ name ] = function( id, options ) {
9574       var length = arguments.length,
9575           trackEvent, defaults, mergedSetupOpts, previousOpts, newOpts;
9576
9577       // Shift arguments based on use case
9578       //
9579       // Back compat for:
9580       // p.plugin( options );
9581       if ( id && !options ) {
9582         options = id;
9583         id = null;
9584       } else {
9585
9586         // Get the trackEvent that matches the given id.
9587         trackEvent = this.getTrackEvent( id );
9588
9589         // If the track event does not exist, ensure that the options
9590         // object has a proper id
9591         if ( !trackEvent ) {
9592           options.id = id;
9593
9594         // If the track event does exist, merge the updated properties
9595         } else {
9596
9597           newOpts = options;
9598           previousOpts = getPreviousProperties( trackEvent, newOpts );
9599
9600           // Call the plugins defined update method if provided. Allows for
9601           // custom defined updating for a track event to be defined by the plugin author
9602           if ( trackEvent._natives._update ) {
9603
9604             this.data.trackEvents.remove( trackEvent );
9605
9606             // It's safe to say that the intent of Start/End will never change
9607             // Update them first before calling update
9608             if ( hasOwn.call( options, "start" ) ) {
9609               trackEvent.start = options.start;
9610             }
9611
9612             if ( hasOwn.call( options, "end" ) ) {
9613               trackEvent.end = options.end;
9614             }
9615
9616             TrackEvent.end( this, trackEvent );
9617
9618             if ( isfn ) {
9619               definition.call( this, trackEvent );
9620             }
9621
9622             trackEvent._natives._update.call( this, trackEvent, options );
9623
9624             this.data.trackEvents.add( trackEvent );
9625             TrackEvent.start( this, trackEvent );
9626           } else {
9627             // This branch is taken when there is no explicitly defined
9628             // _update method for a plugin. Which will occur either explicitly or
9629             // as a result of the plugin definition being a function that _returns_
9630             // a definition object.
9631             //
9632             // In either case, this path can ONLY be reached for TrackEvents that
9633             // already exist.
9634
9635             // Directly update the TrackEvent instance.
9636             // This supports TrackEvent invariant enforcement.
9637             Popcorn.extend( trackEvent, options );
9638
9639             this.data.trackEvents.remove( id );
9640
9641             // If a _teardown function was defined,
9642             // enforce for track event removals
9643             if ( trackEvent._natives._teardown ) {
9644               trackEvent._natives._teardown.call( this, trackEvent );
9645             }
9646
9647             // Update track event references
9648             Popcorn.removeTrackEvent.ref( this, id );
9649
9650             if ( isfn ) {
9651               pluginFn.call( this, definition.call( this, trackEvent ), trackEvent );
9652             } else {
9653
9654               //  Supports user defined track event id
9655               trackEvent._id = trackEvent.id || trackEvent._id || Popcorn.guid( trackEvent._natives.type );
9656
9657               if ( trackEvent._natives && trackEvent._natives._setup ) {
9658
9659                 trackEvent._natives._setup.call( this, trackEvent );
9660
9661                 this.emit( "tracksetup", Popcorn.extend( {}, trackEvent, {
9662                   plugin: trackEvent._natives.type,
9663                   type: "tracksetup",
9664                   track: trackEvent
9665                 }));
9666               }
9667
9668               this.data.trackEvents.add( trackEvent );
9669               TrackEvent.start( this, trackEvent );
9670
9671               this.timeUpdate( this, null, true );
9672
9673               // Store references to user added trackevents in ref table
9674               Popcorn.addTrackEvent.ref( this, trackEvent );
9675             }
9676
9677             // Fire an event with change information
9678             this.emit( "trackchange", {
9679               id: trackEvent.id,
9680               type: "trackchange",
9681               previousValue: previousOpts,
9682               currentValue: trackEvent,
9683               track: trackEvent
9684             });
9685
9686             return this;
9687           }
9688
9689           if ( trackEvent._natives.type !== "cue" ) {
9690             // Fire an event with change information
9691             this.emit( "trackchange", {
9692               id: trackEvent.id,
9693               type: "trackchange",
9694               previousValue: previousOpts,
9695               currentValue: newOpts,
9696               track: trackEvent
9697             });
9698           }
9699
9700           return this;
9701         }
9702       }
9703
9704       this.data.running[ name ] = this.data.running[ name ] || [];
9705
9706       // Merge with defaults if they exist, make sure per call is prioritized
9707       defaults = ( this.options.defaults && this.options.defaults[ name ] ) || {};
9708       mergedSetupOpts = Popcorn.extend( {}, defaults, options );
9709
9710       pluginFn.call( this, isfn ? definition.call( this, mergedSetupOpts ) : definition,
9711                                   mergedSetupOpts );
9712
9713       return this;
9714     };
9715
9716     // if the manifest parameter exists we should extend it onto the definition object
9717     // so that it shows up when calling Popcorn.registry and Popcorn.registryByName
9718     if ( manifest ) {
9719       Popcorn.extend( definition, {
9720         manifest: manifest
9721       });
9722     }
9723
9724     //  Push into the registry
9725     var entry = {
9726       fn: plugin[ name ],
9727       definition: definition,
9728       base: definition,
9729       parents: [],
9730       name: name
9731     };
9732     Popcorn.registry.push(
9733        Popcorn.extend( plugin, entry, {
9734         type: name
9735       })
9736     );
9737     Popcorn.registryByName[ name ] = entry;
9738
9739     return plugin;
9740   };
9741
9742   // Storage for plugin function errors
9743   Popcorn.plugin.errors = [];
9744
9745   // Returns wrapped plugin function
9746   function safeTry( fn, pluginName ) {
9747     return function() {
9748
9749       //  When Popcorn.plugin.debug is true, do not suppress errors
9750       if ( Popcorn.plugin.debug ) {
9751         return fn.apply( this, arguments );
9752       }
9753
9754       try {
9755         return fn.apply( this, arguments );
9756       } catch ( ex ) {
9757
9758         // Push plugin function errors into logging queue
9759         Popcorn.plugin.errors.push({
9760           plugin: pluginName,
9761           thrown: ex,
9762           source: fn.toString()
9763         });
9764
9765         // Trigger an error that the instance can listen for
9766         // and react to
9767         this.emit( "pluginerror", Popcorn.plugin.errors );
9768       }
9769     };
9770   }
9771
9772   // Debug-mode flag for plugin development
9773   // True for Popcorn development versions, false for stable/tagged versions
9774   Popcorn.plugin.debug = ( Popcorn.version === "@" + "VERSION" );
9775
9776   //  removePlugin( type ) removes all tracks of that from all instances of popcorn
9777   //  removePlugin( obj, type ) removes all tracks of type from obj, where obj is a single instance of popcorn
9778   Popcorn.removePlugin = function( obj, name ) {
9779
9780     //  Check if we are removing plugin from an instance or from all of Popcorn
9781     if ( !name ) {
9782
9783       //  Fix the order
9784       name = obj;
9785       obj = Popcorn.p;
9786
9787       if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
9788         Popcorn.error( "'" + name + "' is a protected function name" );
9789         return;
9790       }
9791
9792       var registryLen = Popcorn.registry.length,
9793           registryIdx;
9794
9795       // remove plugin reference from registry
9796       for ( registryIdx = 0; registryIdx < registryLen; registryIdx++ ) {
9797         if ( Popcorn.registry[ registryIdx ].name === name ) {
9798           Popcorn.registry.splice( registryIdx, 1 );
9799           delete Popcorn.registryByName[ name ];
9800           delete Popcorn.manifest[ name ];
9801
9802           // delete the plugin
9803           delete obj[ name ];
9804
9805           // plugin found and removed, stop checking, we are done
9806           return;
9807         }
9808       }
9809
9810     }
9811
9812     var byStart = obj.data.trackEvents.byStart,
9813         byEnd = obj.data.trackEvents.byEnd,
9814         animating = obj.data.trackEvents.animating,
9815         idx, sl;
9816
9817     // remove all trackEvents
9818     for ( idx = 0, sl = byStart.length; idx < sl; idx++ ) {
9819
9820       if ( byStart[ idx ] && byStart[ idx ]._natives && byStart[ idx ]._natives.type === name ) {
9821
9822         byStart[ idx ]._natives._teardown && byStart[ idx ]._natives._teardown.call( obj, byStart[ idx ] );
9823
9824         byStart.splice( idx, 1 );
9825
9826         // update for loop if something removed, but keep checking
9827         idx--; sl--;
9828         if ( obj.data.trackEvents.startIndex <= idx ) {
9829           obj.data.trackEvents.startIndex--;
9830           obj.data.trackEvents.endIndex--;
9831         }
9832       }
9833
9834       // clean any remaining references in the end index
9835       // we do this seperate from the above check because they might not be in the same order
9836       if ( byEnd[ idx ] && byEnd[ idx ]._natives && byEnd[ idx ]._natives.type === name ) {
9837
9838         byEnd.splice( idx, 1 );
9839       }
9840     }
9841
9842     //remove all animating events
9843     for ( idx = 0, sl = animating.length; idx < sl; idx++ ) {
9844
9845       if ( animating[ idx ] && animating[ idx ]._natives && animating[ idx ]._natives.type === name ) {
9846
9847         animating.splice( idx, 1 );
9848
9849         // update for loop if something removed, but keep checking
9850         idx--; sl--;
9851       }
9852     }
9853
9854   };
9855
9856   Popcorn.compositions = {};
9857
9858   //  Plugin inheritance
9859   Popcorn.compose = function( name, definition, manifest ) {
9860
9861     //  If `manifest` arg is undefined, check for manifest within the `definition` object
9862     //  If no `definition.manifest`, an empty object is a sufficient fallback
9863     Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {};
9864
9865     // register the effect by name
9866     Popcorn.compositions[ name ] = definition;
9867   };
9868
9869   Popcorn.plugin.effect = Popcorn.effect = Popcorn.compose;
9870
9871   var rnaiveExpr = /^(?:\.|#|\[)/;
9872
9873   //  Basic DOM utilities and helpers API. See #1037
9874   Popcorn.dom = {
9875     debug: false,
9876     //  Popcorn.dom.find( selector, context )
9877     //
9878     //  Returns the first element that matches the specified selector
9879     //  Optionally provide a context element, defaults to `document`
9880     //
9881     //  eg.
9882     //  Popcorn.dom.find("video") returns the first video element
9883     //  Popcorn.dom.find("#foo") returns the first element with `id="foo"`
9884     //  Popcorn.dom.find("foo") returns the first element with `id="foo"`
9885     //     Note: Popcorn.dom.find("foo") is the only allowed deviation
9886     //           from valid querySelector selector syntax
9887     //
9888     //  Popcorn.dom.find(".baz") returns the first element with `class="baz"`
9889     //  Popcorn.dom.find("[preload]") returns the first element with `preload="..."`
9890     //  ...
9891     //  See https://developer.mozilla.org/En/DOM/Document.querySelector
9892     //
9893     //
9894     find: function( selector, context ) {
9895       var node = null;
9896
9897       //  Default context is the `document`
9898       context = context || document;
9899
9900       if ( selector ) {
9901
9902         //  If the selector does not begin with "#", "." or "[",
9903         //  it could be either a nodeName or ID w/o "#"
9904         if ( !rnaiveExpr.test( selector ) ) {
9905
9906           //  Try finding an element that matches by ID first
9907           node = document.getElementById( selector );
9908
9909           //  If a match was found by ID, return the element
9910           if ( node !== null ) {
9911             return node;
9912           }
9913         }
9914         //  Assume no elements have been found yet
9915         //  Catch any invalid selector syntax errors and bury them.
9916         try {
9917           node = context.querySelector( selector );
9918         } catch ( e ) {
9919           if ( Popcorn.dom.debug ) {
9920             throw new Error(e);
9921           }
9922         }
9923       }
9924       return node;
9925     }
9926   };
9927
9928   //  Cache references to reused RegExps
9929   var rparams = /\?/,
9930   //  XHR Setup object
9931   setup = {
9932     ajax: null,
9933     url: "",
9934     data: "",
9935     dataType: "",
9936     success: Popcorn.nop,
9937     type: "GET",
9938     async: true,
9939     contentType: "application/x-www-form-urlencoded; charset=UTF-8"
9940   };
9941
9942   Popcorn.xhr = function( options ) {
9943     var settings;
9944
9945     options.dataType = options.dataType && options.dataType.toLowerCase() || null;
9946
9947     if ( options.dataType &&
9948          ( options.dataType === "jsonp" || options.dataType === "script" ) ) {
9949
9950       Popcorn.xhr.getJSONP(
9951         options.url,
9952         options.success,
9953         options.dataType === "script"
9954       );
9955       return;
9956     }
9957
9958     //  Merge the "setup" defaults and custom "options"
9959     //  into a new plain object.
9960     settings = Popcorn.extend( {}, setup, options );
9961
9962     //  Create new XMLHttpRequest object
9963     settings.ajax = new XMLHttpRequest();
9964
9965     if ( settings.ajax ) {
9966
9967       if ( settings.type === "GET" && settings.data ) {
9968
9969         //  append query string
9970         settings.url += ( rparams.test( settings.url ) ? "&" : "?" ) + settings.data;
9971
9972         //  Garbage collect and reset settings.data
9973         settings.data = null;
9974       }
9975
9976       //  Open the request
9977       settings.ajax.open( settings.type, settings.url, settings.async );
9978
9979       //  For POST, set the content-type request header
9980       if ( settings.type === "POST" ) {
9981         settings.ajax.setRequestHeader(
9982           "Content-Type", settings.contentType
9983         );
9984       }
9985
9986       settings.ajax.send( settings.data || null );
9987
9988       return Popcorn.xhr.httpData( settings );
9989     }
9990   };
9991
9992
9993   Popcorn.xhr.httpData = function( settings ) {
9994
9995     var data, json = null,
9996         parser, xml = null;
9997
9998     settings.ajax.onreadystatechange = function() {
9999
10000       if ( settings.ajax.readyState === 4 ) {
10001
10002         try {
10003           json = JSON.parse( settings.ajax.responseText );
10004         } catch( e ) {
10005           //suppress
10006         }
10007
10008         data = {
10009           xml: settings.ajax.responseXML,
10010           text: settings.ajax.responseText,
10011           json: json
10012         };
10013
10014         // Normalize: data.xml is non-null in IE9 regardless of if response is valid xml
10015         if ( !data.xml || !data.xml.documentElement ) {
10016           data.xml = null;
10017
10018           try {
10019             parser = new DOMParser();
10020             xml = parser.parseFromString( settings.ajax.responseText, "text/xml" );
10021
10022             if ( !xml.getElementsByTagName( "parsererror" ).length ) {
10023               data.xml = xml;
10024             }
10025           } catch ( e ) {
10026             // data.xml remains null
10027           }
10028         }
10029
10030         //  If a dataType was specified, return that type of data
10031         if ( settings.dataType ) {
10032           data = data[ settings.dataType ];
10033         }
10034
10035
10036         settings.success.call( settings.ajax, data );
10037
10038       }
10039     };
10040     return data;
10041   };
10042
10043   Popcorn.xhr.getJSONP = function( url, success, isScript ) {
10044
10045     var head = document.head || document.getElementsByTagName( "head" )[ 0 ] || document.documentElement,
10046       script = document.createElement( "script" ),
10047       isFired = false,
10048       params = [],
10049       rjsonp = /(=)\?(?=&|$)|\?\?/,
10050       replaceInUrl, prefix, paramStr, callback, callparam;
10051
10052     if ( !isScript ) {
10053
10054       // is there a calback already in the url
10055       callparam = url.match( /(callback=[^&]*)/ );
10056
10057       if ( callparam !== null && callparam.length ) {
10058
10059         prefix = callparam[ 1 ].split( "=" )[ 1 ];
10060
10061         // Since we need to support developer specified callbacks
10062         // and placeholders in harmony, make sure matches to "callback="
10063         // aren't just placeholders.
10064         // We coded ourselves into a corner here.
10065         // JSONP callbacks should never have been
10066         // allowed to have developer specified callbacks
10067         if ( prefix === "?" ) {
10068           prefix = "jsonp";
10069         }
10070
10071         // get the callback name
10072         callback = Popcorn.guid( prefix );
10073
10074         // replace existing callback name with unique callback name
10075         url = url.replace( /(callback=[^&]*)/, "callback=" + callback );
10076       } else {
10077
10078         callback = Popcorn.guid( "jsonp" );
10079
10080         if ( rjsonp.test( url ) ) {
10081           url = url.replace( rjsonp, "$1" + callback );
10082         }
10083
10084         // split on first question mark,
10085         // this is to capture the query string
10086         params = url.split( /\?(.+)?/ );
10087
10088         // rebuild url with callback
10089         url = params[ 0 ] + "?";
10090         if ( params[ 1 ] ) {
10091           url += params[ 1 ] + "&";
10092         }
10093         url += "callback=" + callback;
10094       }
10095
10096       //  Define the JSONP success callback globally
10097       window[ callback ] = function( data ) {
10098         // Fire success callbacks
10099         success && success( data );
10100         isFired = true;
10101       };
10102     }
10103
10104     script.addEventListener( "load",  function() {
10105
10106       //  Handling remote script loading callbacks
10107       if ( isScript ) {
10108         //  getScript
10109         success && success();
10110       }
10111
10112       //  Executing for JSONP requests
10113       if ( isFired ) {
10114         //  Garbage collect the callback
10115         delete window[ callback ];
10116       }
10117       //  Garbage collect the script resource
10118       head.removeChild( script );
10119     }, false );
10120
10121     script.addEventListener( "error",  function( e ) {
10122       //  Handling remote script loading callbacks
10123       success && success( { error: e } );
10124
10125       //  Executing for JSONP requests
10126       if ( !isScript ) {
10127         //  Garbage collect the callback
10128         delete window[ callback ];
10129       }
10130       //  Garbage collect the script resource
10131       head.removeChild( script );
10132     }, false );
10133
10134     script.src = url;
10135     head.insertBefore( script, head.firstChild );
10136
10137     return;
10138   };
10139
10140   Popcorn.getJSONP = Popcorn.xhr.getJSONP;
10141
10142   Popcorn.getScript = Popcorn.xhr.getScript = function( url, success ) {
10143
10144     return Popcorn.xhr.getJSONP( url, success, true );
10145   };
10146
10147   Popcorn.util = {
10148     // Simple function to parse a timestamp into seconds
10149     // Acceptable formats are:
10150     // HH:MM:SS.MMM
10151     // HH:MM:SS;FF
10152     // Hours and minutes are optional. They default to 0
10153     toSeconds: function( timeStr, framerate ) {
10154       // Hours and minutes are optional
10155       // Seconds must be specified
10156       // Seconds can be followed by milliseconds OR by the frame information
10157       var validTimeFormat = /^([0-9]+:){0,2}[0-9]+([.;][0-9]+)?$/,
10158           errorMessage = "Invalid time format",
10159           digitPairs, lastIndex, lastPair, firstPair,
10160           frameInfo, frameTime;
10161
10162       if ( typeof timeStr === "number" ) {
10163         return timeStr;
10164       }
10165
10166       if ( typeof timeStr === "string" &&
10167             !validTimeFormat.test( timeStr ) ) {
10168         Popcorn.error( errorMessage );
10169       }
10170
10171       digitPairs = timeStr.split( ":" );
10172       lastIndex = digitPairs.length - 1;
10173       lastPair = digitPairs[ lastIndex ];
10174
10175       // Fix last element:
10176       if ( lastPair.indexOf( ";" ) > -1 ) {
10177
10178         frameInfo = lastPair.split( ";" );
10179         frameTime = 0;
10180
10181         if ( framerate && ( typeof framerate === "number" ) ) {
10182           frameTime = parseFloat( frameInfo[ 1 ], 10 ) / framerate;
10183         }
10184
10185         digitPairs[ lastIndex ] = parseInt( frameInfo[ 0 ], 10 ) + frameTime;
10186       }
10187
10188       firstPair = digitPairs[ 0 ];
10189
10190       return {
10191
10192         1: parseFloat( firstPair, 10 ),
10193
10194         2: ( parseInt( firstPair, 10 ) * 60 ) +
10195               parseFloat( digitPairs[ 1 ], 10 ),
10196
10197         3: ( parseInt( firstPair, 10 ) * 3600 ) +
10198             ( parseInt( digitPairs[ 1 ], 10 ) * 60 ) +
10199               parseFloat( digitPairs[ 2 ], 10 )
10200
10201       }[ digitPairs.length || 1 ];
10202     }
10203   };
10204
10205   // alias for exec function
10206   Popcorn.p.cue = Popcorn.p.exec;
10207
10208   //  Protected API methods
10209   Popcorn.protect = {
10210     natives: getKeys( Popcorn.p ).map(function( val ) {
10211       return val.toLowerCase();
10212     })
10213   };
10214
10215   // Setup logging for deprecated methods
10216   Popcorn.forEach({
10217     // Deprecated: Recommended
10218     "listen": "on",
10219     "unlisten": "off",
10220     "trigger": "emit",
10221     "exec": "cue"
10222
10223   }, function( recommend, api ) {
10224     var original = Popcorn.p[ api ];
10225     // Override the deprecated api method with a method of the same name
10226     // that logs a warning and defers to the new recommended method
10227     Popcorn.p[ api ] = function() {
10228       if ( typeof console !== "undefined" && console.warn ) {
10229         console.warn(
10230           "Deprecated method '" + api + "', " +
10231           (recommend == null ? "do not use." : "use '" + recommend + "' instead." )
10232         );
10233
10234         // Restore api after first warning
10235         Popcorn.p[ api ] = original;
10236       }
10237       return Popcorn.p[ recommend ].apply( this, [].slice.call( arguments ) );
10238     };
10239   });
10240
10241
10242   //  Exposes Popcorn to global context
10243   global.Popcorn = Popcorn;
10244
10245 })(window, window.document);
10246
10247 (function (global, document, $, deck, window, undefined) {
10248
10249
10250     function maybeAddSnippet(audioDataFile, options, andThen) {
10251         if (options.snippets.browsercast) {
10252             if ($(options.selectors.browsercast).size() > 0 && options.alert.goto) {
10253                 alert("'options.snippets.browsercast' is true but a "+options.selectors.browsercast+" has been found."
10254                       +"\nThis might cause interaction glitches."
10255                       +"\n"
10256                       +"\nSuggestion: remove your html snippet or pass the {snippets: {browsercast: false}} option."
10257                      );
10258             }
10259             var ext = audioDataFile.replace(/.*[.]([^.]*)/, '$1');
10260             $('<div/>').addClass('browsercast')
10261                 .append($('<audio/>').addClass("browsercast-audio")
10262                         .append($('<source/>').attr('src', audioDataFile).attr('type', 'audio/'+ext)))
10263                 .append($('<menu/>').append($('<button/>').addClass('playpause')))
10264                 .append($('<div/>').addClass('browsercast-markers')
10265                         .append($('<div/>').addClass('browsercast-time-label').text('1:00'))
10266                         .append($('<div/>').addClass('browsercast-total-time-label').text('9:99')))
10267                 .appendTo($.deck('getContainer'));
10268         }
10269     }
10270
10271     var $document = $(document);
10272
10273     function togglePlay(popcorn) {
10274         if (popcorn.paused() === true) {
10275             popcorn.play()
10276         } else {
10277             popcorn.pause()
10278         }
10279     }
10280
10281     function timeString(nSeconds) {
10282         return new Date(null, null, null, null, null, nSeconds)
10283             .toTimeString()
10284             .replace(/ .*$/, '')
10285             .replace(/^00:/, '');
10286     }
10287
10288     function updatePlayPauseClass(paused, that, ifPlay, ifPause) {
10289         if (paused == true) {
10290             $(that).removeClass(ifPlay);
10291             $(that).addClass(ifPause);
10292         } else {
10293             $(that).removeClass(ifPause);
10294             $(that).addClass(ifPlay);
10295         }
10296     }
10297
10298     // Use the audio timeupdates to drive existing slides.
10299     function playBrowserCast(timings, options) {
10300         var audio, popcorn, markers, bc;
10301         var divs = {};
10302         var nTimings = Object.keys(timings).length;
10303         var defaultWidth = (100./nTimings)+'%';
10304
10305         var forEachTiming = function(f) {
10306             Object.keys(timings)
10307                 .sort(function(a, b) {return a - b;})
10308                 .forEach(f);
10309         };
10310
10311         var inited = false; // to avoid the audio setting the current slide to 0 at the beginning (and allow bookmarking)
10312
10313         bc = $(options.selectors.browsercast).get(0);
10314         audio = $(options.selectors.browsercastAudio).get(0);
10315         markers = $(options.selectors.browsercastMarkers).get(0);
10316         popcorn = Popcorn(audio);
10317
10318         $('.playpause', bc).click(function() {
10319             togglePlay(popcorn);
10320         });
10321
10322         forEachTiming(function(k, i) {
10323             var div = document.createElement('div');
10324             div.className = 'browsercast-cue';
10325             div.onclick = function(event) {
10326                 popcorn.currentTime(timings[k]);
10327             };
10328             $(div)
10329                 .css('width', defaultWidth)
10330                 .css('box-sizing', 'border-box');
10331             markers.appendChild(div);
10332             divs[k] = div;
10333             popcorn.cue(k, timings[k], function () {
10334                 if (!inited) return;
10335                 transitionLock = true;
10336                 $.deck('go', parseInt(k));
10337                 $('.active', markers).removeClass('active');
10338                 $(div).addClass('active');
10339                 transitionLock = false;
10340             });
10341         });
10342         var trySetCueLengthAndPlay = function(retries, delay) {
10343             if (retries <= 0) { return; }
10344             var totalDuration = popcorn.duration();
10345             if (totalDuration > 0) { // it tests also for NaN
10346                 var kPrev;
10347                 forEachTiming(function(k, i) {
10348                     if (i != 0) {
10349                         var pc = 100 * (timings[k] - timings[kPrev]) / totalDuration;
10350                         $(divs[kPrev]).css('width', pc+'%');
10351                     }
10352                     kPrev = k;
10353                 });
10354                 var pc = 100 * (totalDuration - timings[kPrev]) / totalDuration;
10355                 $(divs[kPrev]).css('width', pc+'%');
10356                 // Start the 'cast!
10357                 inited = true;
10358                 var currentSlideIndex = $.deck('getSlides').indexOf($.deck('getSlide'));
10359                 setTimeout(function() { // delay initialization for popcorn to be properly inited
10360                     $.deck('go', currentSlideIndex);
10361                 }, 1);
10362             } else {
10363                 setTimeout(function() {
10364                     trySetCueLengthAndPlay(retries - 1, delay*1.5);
10365                 }, delay);
10366             }
10367         }
10368
10369         // lock for preventing slidechanged event handler during timeupdate handler.
10370         // TODO using a mutex seems clunky.
10371         var transitionLock = false;
10372
10373         // Decorator for creating an event handler that doesn't run
10374         // when the lock is active.
10375         var ifNotLocked = function (f) {
10376             return function (event) {
10377                 if (!transitionLock) {
10378                     f.apply(this, arguments);
10379                 }
10380             };
10381         };
10382
10383         $document.bind('deck.change', ifNotLocked(function (event, from, to) {
10384             popcorn.currentTime(timings[to.toString()]);
10385             popcorn.play();
10386         }));
10387
10388
10389         var updatePlayPause = function() {
10390             $('.playpause').each(function() {
10391                 updatePlayPauseClass(popcorn.paused(), this, 'pause', 'play');
10392             });
10393         };
10394         audio.addEventListener('pause', updatePlayPause);
10395         audio.addEventListener('playing', updatePlayPause);
10396         audio.addEventListener('timeupdate', function () {
10397             var estimatedTotal = popcorn.duration();
10398             var pc = 100 * audio.currentTime / estimatedTotal;
10399             var timeTxt = timeString(audio.currentTime);
10400             var totalTimeTxt = timeString(estimatedTotal);
10401             $(options.selectors.browsercastTimeLabel).css('left', pc+'%').text(timeTxt);
10402             $(options.selectors.browsercastTotalTimeLabel).text(totalTimeTxt);
10403         });
10404         
10405         $document.unbind('keydown.deckbcast').bind('keydown.deckbcast', function(e) {
10406             //opts.keys.scale || $.inArray(e.which, opts.keys.scale) > -1) {
10407             if (e.which === 32) {
10408                 togglePlay(popcorn);
10409                 e.preventDefault();
10410             }
10411         });
10412
10413         trySetCueLengthAndPlay(20, 10);
10414
10415     }
10416
10417     function leftPad(number, targetLength, padding) {
10418         padding = padding || ' ';
10419         var output = number + '';
10420         while (output.length < targetLength) {
10421             output = padding + output;
10422         }
10423         return output;
10424     }
10425
10426     // Start recording a 'cast
10427     // In the end you can get the slide HTML with the cue attributes set
10428     // by running:
10429     //        browsercastRecorder.getHTMLSlides()
10430     // in the Javascript console.
10431     //
10432     // Press 'Left' on the first slide to start recording.
10433     function recordBrowserCast(options) {
10434
10435         var bc = $(options.selectors.browsercast);
10436         $(options.selectors.browsercastAudio).attr('controls', 'true');
10437         $(options.selectors.browsercastMarkers).hide();
10438         setTimeout(function(){ $.deck('go', 0); logs = [{time:0, slide:0}];}, 200);
10439
10440         var $document = $(document);
10441         var audio = $(options.selectors.browsercastAudio).get(0);
10442         var logs = []; // as a list of pairs, so we can have multiple values and clean afterwards
10443         var exportLogs = function() {
10444             var res = '{\n';
10445             for (i in logs) {
10446                 if (i != 0) {
10447                     res += ',\n';
10448                 }
10449                 res += leftPad('"'+logs[i].slide+'"', 8) + ':' + leftPad(logs[i].time.toFixed(2), 6);
10450             }
10451             res += '\n}\n';
10452             alert(res);
10453         };
10454
10455         $document.bind('deck.change', function(event, from, to) {
10456             logs.push({time: audio.currentTime, slide: to});
10457         });
10458         $document.unbind('keydown.deckbcastrecord').bind('keydown.deckbcastrecord', function(e) {
10459             if (e.which === 84) { // 't'
10460                 exportLogs();
10461             }
10462         });
10463     }
10464
10465     function unsetKey(which, fromWhat) {
10466         if ($.isArray(fromWhat)) {
10467             var match = -1;
10468             while( (match = fromWhat.indexOf(which)) > -1 ) {
10469                 fromWhat.splice(match, 1);
10470             }
10471         } else if ($.isPlainObject(fromWhat)) {
10472             for (var p in fromWhat) {
10473                 if (fromWhat.hasOwnProperty(p)) {
10474                     unsetKey(which, fromWhat[p]);
10475                 }
10476             }
10477         }
10478     }
10479
10480
10481     $.extend(true, $.deck.defaults, {
10482         selectors: {
10483             browsercast: '.browsercast',
10484             browsercastAudio: '.browsercast-audio',
10485             browsercastMarkers: '.browsercast-markers',
10486             browsercastTimeLabel: '.browsercast-time-label',
10487             browsercastTotalTimeLabel: '.browsercast-total-time-label'
10488         },
10489         
10490         snippets: {
10491             browsercast: true,
10492             browsercastAlways: false
10493         },
10494         
10495         alert: {
10496             browsercast: true
10497         }
10498     });
10499
10500
10501     $document.bind('deck.init', function() {
10502         var options = $.deck('getOptions');
10503         var audioDataFile = $('html>head>meta[name="audio"]').attr('content');
10504         if (audioDataFile === undefined) {
10505             return;
10506         }
10507         unsetKey(32, options.keys); // unbind space from 'next slide'
10508         maybeAddSnippet(audioDataFile, options);
10509         var timingDataFile = $('html>head>meta[name="timings"]').attr('content');
10510         if (timingDataFile === undefined) {
10511             recordBrowserCast(options);
10512         } else {
10513             $.getJSON(timingDataFile, function(timings) {
10514                 playBrowserCast(timings, options);
10515             }).fail(function( jqxhr, textStatus, error ) {
10516                 var err = textStatus + ', ' + error;
10517                 console.log('[Browsercast] Request Failed: ' + err);
10518                 if (options.alert.browsercast) {
10519                     alert('Timing file "' + timingDataFile + '" referenced but it was not found or wrong.\n' +
10520                           'See console logs for more details.\n' +
10521                           "Browsercast replay won't work, falling back to timing recording.");
10522                 }
10523                 recordBrowserCast();
10524             });
10525         }
10526     });
10527
10528 })(window, window.document, jQuery, 'deck', this);
10529 function ACTUALLY_FILL_CSS(el) { $(el).text("\n.deck-container {\n  position: relative;\n  overflow: hidden;\n  margin: 0;\n}\n\n.deck-container:not(.show-all-slides):not(.deck-menu):not(.deck-loading) > .slide:not(.deck-current), .deck-container:not(.show-all-slides):not(.deck-menu):not(.deck-loading) > .slide:not(.deck-child-current) {\n  display: none;\n}\n.deck-container:not(.show-all-slides):not(.deck-menu):not(.deck-loading) > .slide.deck-current, .deck-container:not(.show-all-slides):not(.deck-menu):not(.deck-loading) > .slide.deck-child-current {\n  display: block;\n}\n\n.deck-container.deck-loading > *:not(.deck-loading-splash) {\n  visibility: hidden;\n}\n.touch .deck-container {\n  -webkit-text-size-adjust: none;\n  -moz-text-size-adjust: none;\n}\n.deck-container > .slide {\n  position: absolute;\n}\n.deck-container > .slide.deck-current, .deck-container > .slide.deck-child-current {\n  position: absolute;\n  /* relative to parent */\n}\n.deck-container > .slide.deck-current .slide, .deck-container > .slide.deck-child-current .slide {\n  visibility: hidden;\n}\n.deck-container > .slide.deck-current .deck-previous, .deck-container > .slide.deck-current .deck-before, .deck-container > .slide.deck-current .deck-current, .deck-container > .slide.deck-child-current .deck-previous, .deck-container > .slide.deck-child-current .deck-before, .deck-container > .slide.deck-child-current .deck-current {\n  visibility: visible;\n}\n.deck-container.deck-anim-ready .deck-loading-splash {\n  visibility: hidden;\n  opacity: 0;\n  /*\n      right: 100%;\n      left: -100%;\n  */\n  -webkit-transition: visibility 0s linear 0.5s, all 0.5s linear;\n  transition: visibility 0s linear .5s, all 0.5s linear;\n}\n.deck-container .deck-loading-splash {\n  visibility: visible;\n  opacity: 1;\n  position: absolute;\n  text-align: center;\n  padding-top: 200px;\n  display: flex;\n  margin: 0 auto;\n  left: 0;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  background: black;\n  color: white;\n  z-index: 100;\n}\n\n\n.deck-container {\n    width: 100%; height: 100%; /* to get a proper filling of the parent */\n    margin: 0; padding: 0; /* any margin is handled by the parent or the fit extension */\n    position: absolute;\n    left:0; top:0; width:100%; height:100%;\n    border: 0;\n}\n.deck-container>.slide {\n    width: 100%; height: 100%; /* to get a proper filling of the parent */\n    min-width:0; min-height:0; /* undoing some hurting style in the defaults of deck.js */\n    overflow: hidden; /* don't show slides outside of their box */\n    /* margin:0; padding:0; /* remove possible margins */\n}\n\nbody.is-clone .clonepointer {\n  /* default convenient positioning for clone pointers */\n  position: absolute;\n  z-index: 10; }\n  body.is-clone .clonepointer.scale-on-click {\n    transition: transform 80ms linear;\n    -webkit-transition: -webkit-transform 80ms linear; }\n    body.is-clone .clonepointer.scale-on-click.pointer-click {\n      transition: transform 150ms linear;\n      -webkit-transition: -webkit-transform 150ms linear;\n      transform: translate(-50%, -50%) scale(1.5, 1.5) translate(50%, 50%);\n      -webkit-transform: translate(-50%, -50%) scale(1.5, 1.5) translate(50%, 50%); }\n\n.notes, .notes-target {\n  display: none; }\n\nbody.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-current, body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-child-current {\n  outline: 5px solid grey;\n  /* use outline to avoid layout issues with old themes and allow for precise pointer position estimation */\n  overflow: hidden;\n  left: 0;\n  top: 0;\n  transform: translate(20px, 20px);\n  -webkit-transform: translate(20px, 20px); }\n  body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-current + .slide, body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-child-current + .slide {\n    outline: 5px solid grey;\n    overflow: hidden;\n    display: block !important;\n    visibility: visible;\n    top: 0;\n    left: 0;\n    transform: translate(-50%, -50%) scale(0.5) translate(50%, 50%) translate(200%, 0) translate(80px, 40px);\n    -webkit-transform: translate(-50%, -50%) scale(0.5) translate(50%, 50%) translate(200%, 0) translate(80px, 40px); }\n    body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-current + .slide.deck-next, body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-child-current + .slide.deck-next {\n      outline-color: red; }\nbody.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) .notes-target {\n  display: block;\n  background: black;\n  color: #FFB;\n  padding: 5px;\n  position: absolute;\n  left: 840px;\n  right: 0;\n  top: 340px;\n  bottom: 0; }\n\n.goto-form {\n  position: absolute;\n  z-index: 3;\n  bottom: 10px;\n  left: 50%;\n  height: 1.75em;\n  margin: 0 0 0 -9.125em;\n  line-height: 1.75em;\n  padding: 0.625em;\n  display: none;\n  background: #ccc;\n  overflow: hidden;\n  border-radius: 10px;\n}\n.goto-form label {\n  font-weight: bold;\n}\n.goto-form label, .goto-form input {\n  display: inline-block;\n  font-family: inherit;\n}\n.deck-goto .goto-form {\n  display: block;\n}\n\n#goto-slide {\n  width: 8.375em;\n  margin: 0 0.625em;\n  height: 1.4375em;\n}\n\n@media print {\n  .goto-form, #goto-slide {\n    display: none;\n  }\n}\n\n.deck-container.no-status .deck-status {\n  display: none;\n}\n\n.deck-status {\n  position: absolute;\n  z-index: 3;\n  left: 0;\n  bottom: 10px;\n  margin: 0;\n  padding: 0;\n  font-size: 10px;\n  /*outline: 1px solid red;*/\n  width: 100%;\n  text-align: center;\n  color: #888;\n}\n\n.deck-prev-link, .deck-next-link {\n  display: none;\n  position: absolute;\n  z-index: 3;\n  top: 50%;\n  width: 32px;\n  height: 32px;\n  margin-top: -16px;\n  font-size: 20px;\n  font-weight: bold;\n  line-height: 32px;\n  vertical-align: middle;\n  text-align: center;\n  text-decoration: none;\n  color: #fff;\n  background: #888;\n  border-radius: 16px;\n}\n.deck-prev-link:hover, .deck-prev-link:focus, .deck-prev-link:active, .deck-prev-link:visited, .deck-next-link:hover, .deck-next-link:focus, .deck-next-link:active, .deck-next-link:visited {\n  color: #fff;\n}\n\n.deck-prev-link {\n  left: 8px;\n}\n\n.deck-next-link {\n  right: 8px;\n}\n\n.deck-container:hover .deck-prev-link, .deck-container:hover .deck-next-link {\n  display: block;\n}\n.deck-container:hover .deck-prev-link.deck-nav-disabled, .touch .deck-container:hover .deck-prev-link, .deck-container:hover .deck-next-link.deck-nav-disabled, .touch .deck-container:hover .deck-next-link {\n  display: none;\n}\n\n@media print {\n  .deck-prev-link, .deck-next-link {\n    display: none !important;\n  }\n}\n\n.deck-menu {\n  overflow: auto;\n}\n.deck-menu .slide {\n  background: #eee;\n  position: relative;\n  left: 0;\n  top: 0;\n  visibility: visible;\n  cursor: pointer;\n}\n.no-csstransforms .deck-menu > .slide {\n  float: left;\n  width: 22%;\n  height: 22%;\n  min-height: 0;\n  margin: 1%;\n  font-size: 0.22em;\n  overflow: hidden;\n  padding: 0 0.5%;\n}\n.csstransforms .deck-menu > .slide {\n  -webkit-transform: scale(0.22) !important;\n  -ms-transform: scale(0.22) !important;\n  transform: scale(0.22) !important;\n  -webkit-transform-origin: 0 0;\n  -ms-transform-origin: 0 0;\n  transform-origin: 0 0;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  width: 100%;\n  height: 100%;\n  overflow: hidden;\n  padding: 0 48px;\n  margin: 12px;\n}\n.deck-menu iframe, .deck-menu img, .deck-menu video {\n  max-width: 100%;\n}\n.deck-menu .deck-current, .no-touch .deck-menu .slide:hover {\n  background: #ddf;\n}\n.deck-menu.deck-container:hover .deck-prev-link, .deck-menu.deck-container:hover .deck-next-link {\n  display: none;\n}\n\n.deck-container .attribution-wrap {\n  /* cover the complete offset parent */\n  position: absolute;\n  left: 0;\n  width: 100%;\n  top: 0;\n  height: 100%;\n}\n.deck-container .attribution-link {\n  font-size: 10px;\n  color: white;\n  background: black;\n  border: 1px solid darkgrey;\n  opacity: 0.6;\n  right: 0;\n  bottom: 5px;\n  position: absolute;\n  padding: 0 5px;\n}\n\n/* the time etc */\n.timekeeper {\n  font-size: 28px;\n  border-radius: 3px;\n  background: black;\n  color: white;\n  display: inline-block;\n  position: absolute;\n  left: 840px;\n  top: 340px;\n  width: 400px;\n  padding: 4px;\n  margin: -4px; }\n  body:not(.has-clones) .timekeeper {\n    visibility: hidden; }\n  .timekeeper .timekeeper-time, .timekeeper .timekeeper-local-relative-time {\n    margin: 0;\n    padding: 0;\n    display: inline-block;\n    width: 50%;\n    text-align: center;\n    vertical-align: middle; }\n    .timekeeper .timekeeper-time.timekeeper-local-relative-time, .timekeeper .timekeeper-local-relative-time.timekeeper-local-relative-time {\n      color: grey; }\n    .timekeeper .timekeeper-time.timekeeper-time, .timekeeper .timekeeper-local-relative-time.timekeeper-time {\n      border-left: 2px solid grey;\n      /*margin-left: -10px; not needed with the injected template (no space in it)*/\n      margin-right: -15px; }\n  .timekeeper .timekeeper-relative-time {\n    margin-top: 5px;\n    border-top: 2px solid grey;\n    text-align: center;\n    font-size: 300%; }\n  .timekeeper .timekeeper-bang, .timekeeper .timekeeper-clear {\n    display: inline-block;\n    position: absolute;\n    width: 10px;\n    height: 10px;\n    left: 45%;\n    border: 2px solid grey;\n    border-radius: 15px;\n    background: black; }\n    .timekeeper .timekeeper-bang.timekeeper-bang, .timekeeper .timekeeper-clear.timekeeper-bang {\n      top: 10px; }\n    .timekeeper .timekeeper-bang.timekeeper-clear, .timekeeper .timekeeper-clear.timekeeper-clear {\n      top: 23px; }\n    .timekeeper .timekeeper-bang:not(.timekeeper-notification), .timekeeper .timekeeper-clear:not(.timekeeper-notification) {\n      transition: background 300ms linear;\n      -webkit-transition: background 300ms linear; }\n    .timekeeper .timekeeper-bang.timekeeper-notification, .timekeeper .timekeeper-clear.timekeeper-notification {\n      border-color: white;\n      background: green; }\n      .timekeeper .timekeeper-bang.timekeeper-notification.timekeeper-clear, .timekeeper .timekeeper-clear.timekeeper-notification.timekeeper-clear {\n        background: red; }\n\n/* the logs */\n.timekeeper-logs {\n  visibility: hidden;\n  border: 2px solid black;\n  border-radius: 2px;\n  background: #181818;\n  color: yellow;\n  padding: 5px;\n  position: absolute;\n  width: 500px;\n  right: 0;\n  top: 0;\n  bottom: 0;\n  opacity: .8; }\n  .timekeeper-logs.timekeeper-logs-visible {\n    visibility: visible; }\n  .timekeeper-logs pre {\n    font-size: 10px;\n    overflow-y: scroll;\n    position: absolute;\n    top: 50px;\n    bottom: 0;\n    left: 0;\n    right: 0; }\n  .timekeeper-logs .button {\n    color: white;\n    background: black;\n    display: inline-block;\n    padding: 0 5px;\n    margin-right: 10px;\n    border: 1px solid white;\n    border-radius: 3px; }\n\nbody.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) div.notes-target {\n  top: 490px; }\n\n.deck-container .slide.image-full > .attribution-wrap, .deck-container .slide.image-full > img, .deck-container .slide.image-full > div.img, .deck-container .slide.image-fit > .attribution-wrap, .deck-container .slide.image-fit > img, .deck-container .slide.image-fit > div.img {\n  z-index: -1;\n}\n.deck-container .slide.image-full > img, .deck-container .slide.image-full > div.img, .deck-container .slide.image-fit > img, .deck-container .slide.image-fit > div.img {\n  margin: 0;\n  padding: 0;\n  position: relative;\n  left: 0;\n  top: 0;\n  width: 100%;\n  min-height: 100%;\n}\n.deck-container .slide.image-full div.img, .deck-container .slide.image-fit div.img {\n  width: 100%;\n  height: 100%;\n  outline: 2px solid red;\n  background-position: center center;\n  background-repeat: no-repeat;\n}\n.deck-container .slide.image-full.image-full div.img, .deck-container .slide.image-fit.image-full div.img {\n  -webkit-background-size: cover;\n  -moz-background-size: cover;\n  -o-background-size: cover;\n  background-size: cover;\n}\n.deck-container .slide.image-full.image-fit div.img, .deck-container .slide.image-fit.image-fit div.img {\n  -webkit-background-size: contain;\n  -moz-background-size: contain;\n  -o-background-size: contain;\n  background-size: contain;\n}\n.deck-container .slide.top-left h2 {\n  position: absolute;\n  border: 0px;\n  top: 50px;\n  left: 50px;\n}\n.deck-container .slide.top-right h2 {\n  position: absolute;\n  border: 0px;\n  top: 50px;\n  right: 50px;\n}\n.deck-container .slide.bottom-left h2 {\n  position: absolute;\n  border: 0px;\n  bottom: 50px;\n  left: 50px;\n}\n.deck-container .slide.bottom-right h2 {\n  position: absolute;\n  border: 0px;\n  bottom: 50px;\n  right: 50px;\n}\n.deck-container .slide.no-title h1, .deck-container .slide.no-title h2 {\n  display: none;\n}\n.deck-container .slide.darkened h2 {\n  background: rgba(0, 0, 0, 0.75);\n  padding: 15px;\n  margin: -15px;\n}\n.deck-container .in3d-table {\n  transform: scale(0.7) perspective(600px) rotateX(40deg) rotateZ(-15deg) translate(-30px, -120px);\n}\n\n.deck-container:not(.deck-globalscale) div.comment, .deck-container:not(.deck-globalscale) .comment {\n  z-index: 1000 !important;\n  /* might need theme specific thing here */\n  background-color: yellow;\n  /* force opaque... */\n  color: darkred;\n}\n\n.deck-container:not(.deck-globalscale) .hasSVG .comment {\n  /*transform: none;*/\n  -webkit-transform: none;\n}\n\nbody:not(.has-clones):not(.show-comments) .deck-container > .slide .comment, body:not(.has-clones):not(.show-comments) .deck-container > .slide .showwhencomment {\n  display: none;\n}\n\n.deck-container > .slide div.comment {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  /*outline: 1px solid red;*/\n  border-radius: 3px;\n  color: darkred;\n  background: rgba(255, 255, 128, 0.7);\n  /*        opacity: .8;*/\n  font-size: 14px;\n  line-height: initial;\n  padding: 1px 15px;\n  width: auto;\n  height: 20px;\n  margin: 0;\n  margin-left: 100px;\n  margin-top: -6.6px;\n  margin-bottom: -13.2px;\n}\n\n.deck-container > .slide div.comment.small {\n  width: 120px;\n  margin-left: -100px;\n}\n\n.deck-container > .slide div.comment.twolines {\n  height: 40px;\n  margin-top: -13.333px;\n  margin-bottom: -26.667px;\n}\n\n.browsercast {\n    position: absolute;\n    top: 5px; left: 5px;\n    right: 5px;\n}\n\n.browsercast-audio {\n    width: 100%;\n    margin: auto auto;\n}\n\n.browsercast-cue {\n    position: relative;\n    float: left;\n    height: 10px;\n    border-right: solid 2px #000;\n    cursor: pointer;\n}\n\n.browsercast-cue:last-child {\n    border-right: 0;\n}\n\n.browsercast-cue.active {\n    background-color: #abc;\n}\n\n\nmenu {\n  /* @size sets the relative size of the buttons, define before calling the buttons mixin */\n  /* Play */\n  /* Stop */\n  /* Fast-Forward */\n  /* Rewind */\n  /* Pause */\n  margin: 2em auto;\n  text-align: center;\n  position: relative;\n}\nmenu button {\n  position: relative;\n  display: inline-block;\n  padding: .6em;\n  background: linear-gradient(#ffffff, #cccccc), #c9c5c9;\n  border-radius: 10em;\n  border: 0 solid #d0d0d0;\n  width: 3em;\n  height: 3em;\n  margin-right: 20px;\n  box-shadow: 0 0.18em 0.21em rgba(0, 0, 0, 0.4);\n}\nmenu button:hover {\n  background: linear-gradient(#f5f5f5, #b9b9b9), #c9c5c9;\n}\nmenu button:before,\nmenu button:after {\n  position: absolute;\n  content: \" \";\n}\nmenu button:active {\n  top: 0.15em;\n  box-shadow: 0 0.06em 0.09em rgba(0, 0, 0, 0.4);\n}\nmenu .play:before {\n  z-index: 2;\n  top: 0.66em;\n  left: 1.08em;\n  width: 0;\n  height: 0;\n  border: 0.9em solid transparent;\n  border-left-color: rgba(100, 100, 100, 0.8);\n  border-left-width: 1.35em;\n}\nmenu .play:hover:before {\n  border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu .stop:before {\n  top: 0.84em;\n  left: 0.84em;\n  width: 1.41em;\n  height: 1.41em;\n  background: rgba(100, 100, 100, 0.8);\n}\nmenu .stop:hover:before {\n  background: rgba(36, 36, 36, 0.8);\n}\nmenu .ff:before,\nmenu .ff:after {\n  width: 0;\n  height: 0;\n  top: 0.78em;\n  border: 0.75em solid transparent;\n  border-left-color: rgba(100, 100, 100, 0.8);\n  border-left-width: 0.81em;\n}\nmenu .ff:before {\n  left: 0.9em;\n}\nmenu .ff:after {\n  left: 1.698em;\n  content: \" \";\n}\nmenu .ff:hover:before,\nmenu .ff:hover:after {\n  border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu .rw:before,\nmenu .rw:after {\n  width: 0;\n  height: 0;\n  top: 0.78em;\n  border: 0.75em solid transparent;\n  border-right-color: rgba(100, 100, 100, 0.8);\n  border-right-width: 0.81em;\n}\nmenu .rw:before {\n  left: 0.66em;\n}\nmenu .rw:after {\n  left: -0.15em;\n  content: \" \";\n}\nmenu .rw:hover:after,\nmenu .rw:hover:before {\n  border-right-color: rgba(36, 36, 36, 0.8);\n}\nmenu .pause:before,\nmenu .pause:after {\n  height: 1.41em;\n  width: 0.57em;\n  left: 0.87em;\n  top: 0.84em;\n  display: block;\n  background-color: rgba(100, 100, 100, 0.8);\n}\nmenu .pause:after {\n  left: 1.62em;\n}\nmenu .pause:hover:before,\nmenu .pause:hover:after {\n  background-color: rgba(36, 36, 36, 0.8);\n}\nmenu.medium {\n  /* Play */\n  /* Stop */\n  /* Fast-Forward */\n  /* Rewind */\n  /* Pause */\n}\nmenu.medium button {\n  position: relative;\n  display: inline-block;\n  padding: .6em;\n  background: linear-gradient(#ffffff, #cccccc), #c9c5c9;\n  border-radius: 10em;\n  border: 0 solid #d0d0d0;\n  width: 5em;\n  height: 5em;\n  margin-right: 20px;\n  box-shadow: 0 0.3em 0.35em rgba(0, 0, 0, 0.4);\n}\nmenu.medium button:hover {\n  background: linear-gradient(#f5f5f5, #b9b9b9), #c9c5c9;\n}\nmenu.medium button:before,\nmenu.medium button:after {\n  position: absolute;\n  content: \" \";\n}\nmenu.medium button:active {\n  top: 0.25em;\n  box-shadow: 0 0.1em 0.15em rgba(0, 0, 0, 0.4);\n}\nmenu.medium .play:before {\n  z-index: 2;\n  top: 1.1em;\n  left: 1.8em;\n  width: 0;\n  height: 0;\n  border: 1.5em solid transparent;\n  border-left-color: rgba(100, 100, 100, 0.8);\n  border-left-width: 2.25em;\n}\nmenu.medium .play:hover:before {\n  border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu.medium .stop:before {\n  top: 1.4em;\n  left: 1.4em;\n  width: 2.35em;\n  height: 2.35em;\n  background: rgba(100, 100, 100, 0.8);\n}\nmenu.medium .stop:hover:before {\n  background: rgba(36, 36, 36, 0.8);\n}\nmenu.medium .ff:before,\nmenu.medium .ff:after {\n  width: 0;\n  height: 0;\n  top: 1.3em;\n  border: 1.25em solid transparent;\n  border-left-color: rgba(100, 100, 100, 0.8);\n  border-left-width: 1.35em;\n}\nmenu.medium .ff:before {\n  left: 1.5em;\n}\nmenu.medium .ff:after {\n  left: 2.83em;\n  content: \" \";\n}\nmenu.medium .ff:hover:before,\nmenu.medium .ff:hover:after {\n  border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu.medium .rw:before,\nmenu.medium .rw:after {\n  width: 0;\n  height: 0;\n  top: 1.3em;\n  border: 1.25em solid transparent;\n  border-right-color: rgba(100, 100, 100, 0.8);\n  border-right-width: 1.35em;\n}\nmenu.medium .rw:before {\n  left: 1.1em;\n}\nmenu.medium .rw:after {\n  left: -0.25em;\n  content: \" \";\n}\nmenu.medium .rw:hover:after,\nmenu.medium .rw:hover:before {\n  border-right-color: rgba(36, 36, 36, 0.8);\n}\nmenu.medium .pause:before,\nmenu.medium .pause:after {\n  height: 2.35em;\n  width: 0.95em;\n  left: 1.45em;\n  top: 1.4em;\n  display: block;\n  background-color: rgba(100, 100, 100, 0.8);\n}\nmenu.medium .pause:after {\n  left: 2.7em;\n}\nmenu.medium .pause:hover:before,\nmenu.medium .pause:hover:after {\n  background-color: rgba(36, 36, 36, 0.8);\n}\nmenu.small {\n  /* Play */\n  /* Stop */\n  /* Fast-Forward */\n  /* Rewind */\n  /* Pause */\n}\nmenu.small button {\n  position: relative;\n  display: inline-block;\n  padding: .6em;\n  background: linear-gradient(#ffffff, #cccccc), #c9c5c9;\n  border-radius: 10em;\n  border: 0 solid #d0d0d0;\n  width: 3em;\n  height: 3em;\n  margin-right: 20px;\n  box-shadow: 0 0.18em 0.21em rgba(0, 0, 0, 0.4);\n}\nmenu.small button:hover {\n  background: linear-gradient(#f5f5f5, #b9b9b9), #c9c5c9;\n}\nmenu.small button:before,\nmenu.small button:after {\n  position: absolute;\n  content: \" \";\n}\nmenu.small button:active {\n  top: 0.15em;\n  box-shadow: 0 0.06em 0.09em rgba(0, 0, 0, 0.4);\n}\nmenu.small .play:before {\n  z-index: 2;\n  top: 0.66em;\n  left: 1.08em;\n  width: 0;\n  height: 0;\n  border: 0.9em solid transparent;\n  border-left-color: rgba(100, 100, 100, 0.8);\n  border-left-width: 1.35em;\n}\nmenu.small .play:hover:before {\n  border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu.small .stop:before {\n  top: 0.84em;\n  left: 0.84em;\n  width: 1.41em;\n  height: 1.41em;\n  background: rgba(100, 100, 100, 0.8);\n}\nmenu.small .stop:hover:before {\n  background: rgba(36, 36, 36, 0.8);\n}\nmenu.small .ff:before,\nmenu.small .ff:after {\n  width: 0;\n  height: 0;\n  top: 0.78em;\n  border: 0.75em solid transparent;\n  border-left-color: rgba(100, 100, 100, 0.8);\n  border-left-width: 0.81em;\n}\nmenu.small .ff:before {\n  left: 0.9em;\n}\nmenu.small .ff:after {\n  left: 1.698em;\n  content: \" \";\n}\nmenu.small .ff:hover:before,\nmenu.small .ff:hover:after {\n  border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu.small .rw:before,\nmenu.small .rw:after {\n  width: 0;\n  height: 0;\n  top: 0.78em;\n  border: 0.75em solid transparent;\n  border-right-color: rgba(100, 100, 100, 0.8);\n  border-right-width: 0.81em;\n}\nmenu.small .rw:before {\n  left: 0.66em;\n}\nmenu.small .rw:after {\n  left: -0.15em;\n  content: \" \";\n}\nmenu.small .rw:hover:after,\nmenu.small .rw:hover:before {\n  border-right-color: rgba(36, 36, 36, 0.8);\n}\nmenu.small .pause:before,\nmenu.small .pause:after {\n  height: 1.41em;\n  width: 0.57em;\n  left: 0.87em;\n  top: 0.84em;\n  display: block;\n  background-color: rgba(100, 100, 100, 0.8);\n}\nmenu.small .pause:after {\n  left: 1.62em;\n}\nmenu.small .pause:hover:before,\nmenu.small .pause:hover:after {\n  background-color: rgba(36, 36, 36, 0.8);\n}\n/*\nThe buttons mixin that defines the buttons styles, the @size must be defined to set the relative size\n*/\n/*\nOther Styles\n*/\nbody {\n  background: #c1c1c1;\n}\n\n\n\n\n/* ///////////////////////////////// */\n\n\n.browsercast-time-label, .browsercast-total-time-label {\n    z-index: 1;\n    background-color: grey;\n    font-family: lato;\n    color: #DDD;\n    text-shadow: #555 1px 1px 1px;\n    padding: 0 5px;\n    border-radius: 2px;\n    font-size: 10px;\n    display: inline-block;\n    position: absolute;\n}\n.browsercast-total-time-label {\n    right: 0%;\n    bottom: -17px;\n    background-color: #333;\n    transform: translate(50%, 0) translate(-3px, 0);\n}\n.browsercast-time-label {\n    z-index: 2;\n    left: 0%;\n    transition: left 200ms linear;\n    bottom: -17px;\n    transform: translate(-50%, 0) translate(-3px, 0);\n}\n.browsercast-time-label:after {\n    content: ' ';\n    height: 0; \n    position: absolute;\n    width: 0;\n    \n    border: 8px solid transparent;\n    border-bottom-color: grey;\n    \n    bottom: 100%;\n    left: 50%;\n    margin-left: -7px;\n}\n\n\n/* ///////////////////////// */\nmenu {\n    padding: 0;\n    margin: 0;\n}\n\nmenu .playpause {\n    position: absolute;\n    left: 0;\n    top: 0;\n    font-size: 12px;\n    margin: 0; padding: 0;\n}\n\n.browsercast-markers {\n    position: absolute;\n    top: 0; height: 10px;\n    left: 3em; right: 1em;\n    background-color: #e3e3e3;\n}\n") }