2 This is a packed deck.js with some extensions and styles.
3 It has been generated from version d8c74bcc860ba175ab020fd69656abee3fc057f3 .
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
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
54 * The goal of this extension is to simplify include of deck.js,
55 * its profiles/themes and the extensions.
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
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
78 // this is the actual includedeck
79 function includedeck(m, c) {
80 var maybe = function(f) { return f || (function(){}); }
81 var modules = m || [];
83 var initDelay = conf.INITDELAY;
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, ...)
93 var prefix = conf.PREFIX || "deck.js";
95 if (typeof(modules) == "string") {
96 modules = modules.split(/ +/);
99 // todo: make this externally extensible
100 // todo: maybe have a mechanism to load a list of dependency (e.g., mymodule-files.js)
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"
111 "@_deck-core-dependencies",
112 prefix + "/core/deck.core.css",
113 prefix + "/core/deck.core.js"
116 "@_deck-core-dependencies",
117 prefix + "/extensions/style-chunks/core.css",
118 prefix + "/core/deck.core.js"
122 "fit": [ prefix + "/extensions/fit/deck.fit.js" ],
124 prefix + "/extensions/fit/deck.fit-fs.css",
128 prefix + "/libs/display-latex2.user.js",
129 prefix + "/extensions/simplemath/deck.simplemath.js"
131 "smartsyntax": [ prefix + "/extensions/smartsyntax/deck.smartsyntax.js" ],
133 prefix + "/extensions/smarkdown/markdown.js",
134 prefix + "/extensions/smarkdown/deck.smarkdown.js"
137 prefix + "/extensions/clone/deck.clone.css",
138 prefix + "/extensions/clone/deck.clone.js"
141 prefix + "/extensions/timekeeper/deck.timekeeper.css",
142 prefix + "/extensions/timekeeper/deck.timekeeper.js"
145 prefix + "/extensions/goto/deck.goto.css",
146 prefix + "/extensions/goto/deck.goto.js"
149 prefix + "/extensions/status/deck.status.css",
150 prefix + "/extensions/status/deck.status.js"
153 prefix + "/extensions/progress/deck.progress.css",
154 prefix + "/extensions/progress/deck.progress.js"
157 prefix + "/extensions/navigation/deck.navigation.css",
158 prefix + "/extensions/navigation/deck.navigation.js"
161 prefix + "/extensions/menu/deck.menu.css",
162 prefix + "/extensions/menu/deck.menu.js"
164 "step": [ prefix + "/extensions/step/deck.step.js" ],
165 "events": [ prefix + "/extensions/events/deck.events.js" ],
166 "anim": [ prefix + "/extensions/anim/deck.anim.js" ],
168 prefix + "/libs/jquerysvg/jquery.svg.min.js" ,
169 prefix + "/libs/jquerysvg/jquery.svganim.min.js",
170 prefix + "/extensions/svg/deck.svg.js"
172 "metadata": [ prefix + "/extensions/metadata/deck.metadata.js" ],
174 prefix + "/extensions/attribution/deck.attribution.css",
175 prefix + "/extensions/attribution/deck.attribution.js"
177 "container-styling": [ prefix + "/extensions/container-styling/deck.container-styling.js" ],
180 prefix + "/extensions/style-chunks/simple.css",
181 prefix + "/extensions/style-chunks/comments.css"
185 // // by convention, "theme:blabla" will load the default blabla theme
187 // Some default profiles
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"],
207 var endsInJsOrCss = /\.(css|js)$/;
209 // Defensive check that there are no *.js/*.css in the info (as they won't be useable anyways)
211 if (endsInJsOrCss.test(k)) {
212 alert("Internal problem detected in includedeck: '" + k + "' won't be useable.");
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...))
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, '')
225 window.location.hash = base;
229 var addInfo = function(k) {
230 if (k.substring(0, 6) == "theme:") {
232 if (forceTheme) { // replace by the url forced theme (works only with default themes...
235 if (k.substring(0, 2) == "x:") {
237 toLoad = toLoad.concat(prefix + "/deck.js-theme-builder/" + k + ".css");
239 toLoad = toLoad.concat(prefix + "/themes/style/" + k + ".css");
243 if (k.substring(0, 10) == "extension:") {
244 toLoad = toLoad.concat(prefix + "/extensions/" + k.substring(10));
247 if (endsInJsOrCss.test(k)) {
248 toLoad = toLoad.concat(k);
251 var closure = function(wh, e) { return function () { cb.generic(wh, e); } };
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));
257 if (cb.hasGeneric) toLoad = toLoad.concat(closure("AFTER", e));
259 toLoad = toLoad.concat(info[k][i]);
268 if (typeof ACTUALLY_EXPORT_A_LIST_OF_FILES !== 'undefined') {
272 { // First insert a CSS, just to fit modernizr
273 var c = document.createElement("style");
275 if (typeof ACTUALLY_FILL_CSS !== 'undefined') {
276 ACTUALLY_FILL_CSS(c);
278 document.getElementsByTagName("head")[0].appendChild(c);
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) {
285 if (l.length == 0) return;
286 if ("string" !== typeof l[0]) {
288 loadsAndCalls(l.slice(1));
290 head.js(l[0], function() {
291 loadsAndCalls(l.slice(1));
296 loadsAndCalls(toLoad.concat(function() {
298 var doIt = function() {
304 // delay and callback logic
307 setTimeout(doIt, initDelay);
316 /*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
317 //@ sourceMappingURL=jquery-1.10.2.min.map
319 (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
320 }({});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);
321 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);
322 /* Modernizr 2.0.6 (Custom Build) | MIT & BSD
323 * 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 ;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=["­","<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))};
328 Copyright (c) 2011-2014 Caleb Troughton
329 Dual licensed under the MIT license.
330 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
334 The deck.core module provides all the basic functionality for creating and
335 moving through a deck. It does so by applying classes to indicate the state of
336 the deck and its slides, allowing CSS to take care of the visual representation
337 of each state. It also provides methods for navigating the deck and inspecting
338 its state, as well as basic key bindings for going to the next and previous
339 slides. More functionality is provided by wholly separate extension modules
340 that use the API provided by core.
342 (function($, undefined) {
343 var slides, currentIndex, $container, $fragmentLinks;
347 This event fires at the beginning of a slide change, before the actual
348 change occurs. Its purpose is to give extension authors a way to prevent
349 the slide change from occuring. This is done by calling preventDefault
350 on the event object within this event. If that is done, the deck.change
351 event will never be fired and the slide will not change.
353 beforeChange: 'deck.beforeChange',
356 This event fires whenever the current slide changes, whether by way of
357 next, prev, or go. The callback function is passed two parameters, from
358 and to, equal to the indices of the old slide and the new slide
359 respectively. If preventDefault is called on the event within this handler
360 the slide change does not occur.
362 $(document).bind('deck.change', function(event, from, to) {
363 alert('Moving from slide ' + from + ' to ' + to);
366 change: 'deck.change',
369 This event fires at the beginning of deck initialization. This event makes
370 a good hook for preprocessing extensions looking to modify the DOM before
371 the deck is fully initialized. It is also possible to halt the deck.init
372 event from firing while you do things in beforeInit. This can be done by
373 calling lockInit on the event object passed to this event. The init can be
374 released by calling releaseInit.
376 $(document).bind('deck.beforeInit', function(event) {
377 event.lockInit(); // halts deck.init event
378 window.setTimeout(function() {
379 event.releaseInit(); // deck.init will now fire 2 seconds later
383 The init event will be fired regardless of locks after
384 options.initLockTimeout milliseconds.
386 beforeInitialize: 'deck.beforeInit',
389 This event fires at the end of deck initialization. Extensions should
390 implement any code that relies on user extensible options (key bindings,
391 element selectors, classes) within a handler for this event. Native
392 events associated with Deck JS should be scoped under a .deck event
393 namespace, as with the example below:
395 var $d = $(document);
396 $.deck.defaults.keys.myExtensionKeycode = 70; // 'h'
397 $d.bind('deck.init', function() {
398 $d.bind('keydown.deck', function(event) {
399 if (event.which === $.deck.getOptions().keys.myExtensionKeycode) {
405 initialize: 'deck.init'
409 var $document = $(document);
410 var $window = $(window);
411 var stopPropagation = function(event) {
412 event.stopPropagation();
415 var updateContainerState = function() {
416 var oldIndex = $container.data('onSlide');
417 $container.removeClass(options.classes.onPrefix + oldIndex);
418 $container.addClass(options.classes.onPrefix + currentIndex);
419 $container.data('onSlide', currentIndex);
422 var updateChildCurrent = function() {
423 var $oldCurrent = $('.' + options.classes.current);
424 var $oldParents = $oldCurrent.parentsUntil(options.selectors.container);
425 var $newCurrent = slides[currentIndex];
426 var $newParents = $newCurrent.parentsUntil(options.selectors.container);
427 $oldParents.removeClass(options.classes.childCurrent);
428 $newParents.addClass(options.classes.childCurrent);
431 var removeOldSlideStates = function() {
433 $.each(slides, function(i, el) {
437 options.classes.before,
438 options.classes.previous,
439 options.classes.current,
440 options.classes.next,
441 options.classes.after
445 var addNewSlideStates = function() {
446 slides[currentIndex].addClass(options.classes.current);
447 if (currentIndex > 0) {
448 slides[currentIndex-1].addClass(options.classes.previous);
450 if (currentIndex + 1 < slides.length) {
451 slides[currentIndex+1].addClass(options.classes.next);
453 if (currentIndex > 1) {
454 $.each(slides.slice(0, currentIndex - 1), function(i, $slide) {
455 $slide.addClass(options.classes.before);
458 if (currentIndex + 2 < slides.length) {
459 $.each(slides.slice(currentIndex+2), function(i, $slide) {
460 $slide.addClass(options.classes.after);
465 var setAriaHiddens = function() {
466 $(options.selectors.slides).each(function() {
467 var $slide = $(this);
468 var isSub = $slide.closest('.' + options.classes.childCurrent).length;
469 var isBefore = $slide.hasClass(options.classes.before) && !isSub;
470 var isPrevious = $slide.hasClass(options.classes.previous) && !isSub;
471 var isNext = $slide.hasClass(options.classes.next);
472 var isAfter = $slide.hasClass(options.classes.after);
473 var ariaHiddenValue = isBefore || isPrevious || isNext || isAfter;
474 $slide.attr('aria-hidden', ariaHiddenValue);
478 var updateStates = function() {
479 updateContainerState();
480 updateChildCurrent();
481 removeOldSlideStates();
483 if (options.setAriaHiddens) {
488 var initSlidesArray = function(elements) {
489 if ($.isArray(elements)) {
490 $.each(elements, function(i, element) {
491 slides.push($(element));
495 $(elements).each(function(i, element) {
496 slides.push($(element));
501 var bindKeyEvents = function() {
512 $document.unbind('keydown.deck').bind('keydown.deck', function(event) {
513 var isNext = event.which === options.keys.next;
514 var isPrev = event.which === options.keys.previous;
515 isNext = isNext || $.inArray(event.which, options.keys.next) > -1;
516 isPrev = isPrev || $.inArray(event.which, options.keys.previous) > -1;
520 event.preventDefault();
524 event.preventDefault();
528 $document.undelegate(editables, 'keydown.deck', stopPropagation);
529 $document.delegate(editables, 'keydown.deck', stopPropagation);
532 var bindTouchEvents = function() {
534 var direction = options.touch.swipeDirection;
535 var tolerance = options.touch.swipeTolerance;
536 var listenToHorizontal = ({ both: true, horizontal: true })[direction];
537 var listenToVertical = ({ both: true, vertical: true })[direction];
539 $container.unbind('touchstart.deck');
540 $container.bind('touchstart.deck', function(event) {
542 startTouch = $.extend({}, event.originalEvent.targetTouches[0]);
546 $container.unbind('touchmove.deck');
547 $container.bind('touchmove.deck', function(event) {
548 $.each(event.originalEvent.changedTouches, function(i, touch) {
549 if (!startTouch || touch.identifier !== startTouch.identifier) {
552 var xDistance = touch.screenX - startTouch.screenX;
553 var yDistance = touch.screenY - startTouch.screenY;
554 var leftToRight = xDistance > tolerance && listenToHorizontal;
555 var rightToLeft = xDistance < -tolerance && listenToHorizontal;
556 var topToBottom = yDistance > tolerance && listenToVertical;
557 var bottomToTop = yDistance < -tolerance && listenToVertical;
559 if (leftToRight || topToBottom) {
561 startTouch = undefined;
563 else if (rightToLeft || bottomToTop) {
565 startTouch = undefined;
570 if (listenToVertical) {
571 event.preventDefault();
575 $container.unbind('touchend.deck');
576 $container.bind('touchend.deck', function(event) {
577 $.each(event.originalEvent.changedTouches, function(i, touch) {
578 if (startTouch && touch.identifier === startTouch.identifier) {
579 startTouch = undefined;
585 var indexInBounds = function(index) {
586 return typeof index === 'number' && index >=0 && index < slides.length;
589 var createBeforeInitEvent = function() {
590 var event = $.Event(events.beforeInitialize);
593 event.lockInit = function() {
596 event.releaseInit = function() {
605 var goByHash = function(str) {
606 var id = str.substr(str.indexOf("#") + 1);
608 $.each(slides, function(i, $slide) {
609 if ($slide.attr('id') === id) {
615 // If we don't set these to 0 the container scrolls due to hashchange
616 if (options.preventFragmentScroll) {
617 $.deck('getContainer').scrollLeft(0).scrollTop(0);
621 var assignSlideId = function(i, $slide) {
622 var currentId = $slide.attr('id');
623 var previouslyAssigned = $slide.data('deckAssignedId') === currentId;
624 if (!currentId || previouslyAssigned) {
625 $slide.attr('id', options.hashPrefix + i);
626 $slide.data('deckAssignedId', options.hashPrefix + i);
630 var removeContainerHashClass = function(id) {
631 $container.removeClass(options.classes.onPrefix + id);
634 var addContainerHashClass = function(id) {
635 $container.addClass(options.classes.onPrefix + id);
638 var setupHashBehaviors = function() {
639 $fragmentLinks = $();
640 $.each(slides, function(i, $slide) {
643 assignSlideId(i, $slide);
644 hash = '#' + $slide.attr('id');
645 if (hash === window.location.hash) {
646 setTimeout(function() {
650 $fragmentLinks = $fragmentLinks.add('a[href="' + hash + '"]');
654 addContainerHashClass($.deck('getSlide').attr('id'));
658 var changeHash = function(from, to) {
659 var hash = '#' + $.deck('getSlide', to).attr('id');
660 var hashPath = window.location.href.replace(/#.*/, '') + hash;
662 removeContainerHashClass($.deck('getSlide', from).attr('id'));
663 addContainerHashClass($.deck('getSlide', to).attr('id'));
664 if (Modernizr.history) {
665 window.history.replaceState({}, "", hashPath);
669 /* Methods exposed in the jQuery.deck namespace */
673 jQuery.deck(selector, options)
675 selector: string | jQuery | array
676 options: object, optional
678 Initializes the deck, using each element matched by selector as a slide.
679 May also be passed an array of string selectors or jQuery objects, in
680 which case each selector in the array is considered a slide. The second
681 parameter is an optional options object which will extend the default
684 Users may also pass only an options object to init. In this case the slide
685 selector will be options.selectors.slides which defaults to .slide.
697 init: function(opts) {
698 var beforeInitEvent = createBeforeInitEvent();
699 var overrides = opts;
701 if (!$.isPlainObject(opts)) {
702 overrides = arguments[1] || {};
703 $.extend(true, overrides, {
710 options = $.extend(true, {}, $.deck.defaults, overrides);
713 $container = $(options.selectors.container);
715 // Hide the deck while states are being applied to kill transitions
716 $container.addClass(options.classes.loading);
718 // populate the array of slides for pre-init
719 initSlidesArray(options.selectors.slides);
720 // Pre init event for preprocessing hooks
721 beforeInitEvent.done = function() {
722 // reInitSlidesArray is meant only for beforeInit
723 methods['reInitSlidesArray'] = function() {
724 alert('Deck.js method "reInitSlidesArray" is meant to be called in the beforeInit phase only.');
726 // re-populate the array of slides
728 initSlidesArray(options.selectors.slides);
729 setupHashBehaviors();
732 $container.scrollLeft(0).scrollTop(0);
738 // Show deck again now that slides are in place
739 $container.removeClass(options.classes.loading);
740 $document.trigger(events.initialize);
743 beforeInitEvent.lockInit();
744 $document.trigger(beforeInitEvent);
745 beforeInitEvent.releaseInit();
746 window.setTimeout(function() {
747 if (beforeInitEvent.locks) {
748 if (window.console) {
749 window.console.warn('Something locked deck initialization\
750 without releasing it before the timeout. Proceeding with\
751 initialization anyway.');
753 beforeInitEvent.done();
755 }, options.initLockTimeout);
759 jQuery.deck('reInitSlidesArray')
761 Force a recomputation of the "slides" array. This method is meant
762 to be used by extensions that generate new slides in the
766 reInitSlidesArray: function() {
768 initSlidesArray(options.selectors.slides);
772 jQuery.deck('go', index)
774 index: integer | string
776 Moves to the slide at the specified index if index is a number. Index is
777 0-based, so $.deck('go', 0); will move to the first slide. If index is a
778 string this will move to the slide with the specified id. If index is out
779 of bounds or doesn't match a slide id the call is ignored.
781 go: function(indexOrId) {
782 var beforeChangeEvent = $.Event(events.beforeChange);
785 /* Number index, easy. */
786 if (indexInBounds(indexOrId)) {
789 /* Id string index, search for it and set integer index */
790 else if (typeof indexOrId === 'string') {
791 $.each(slides, function(i, $slide) {
792 if ($slide.attr('id') === indexOrId) {
798 if (typeof index === 'undefined') {
802 /* Trigger beforeChange. If nothing prevents the change, trigger
804 $document.trigger(beforeChangeEvent, [currentIndex, index]);
805 if (!beforeChangeEvent.isDefaultPrevented()) {
806 $document.trigger(events.change, [currentIndex, index]);
807 changeHash(currentIndex, index);
808 currentIndex = index;
816 Moves to the next slide. If the last slide is already active, the call
820 methods.go(currentIndex+1);
826 Moves to the previous slide. If the first slide is already active, the
830 methods.go(currentIndex-1);
834 jQuery.deck('getSlide', index)
836 index: integer, optional
838 Returns a jQuery object containing the slide at index. If index is not
839 specified, the current slide is returned.
841 getSlide: function(index) {
842 index = typeof index !== 'undefined' ? index : currentIndex;
843 if (!indexInBounds(index)) {
846 return slides[index];
850 jQuery.deck('getSlides')
852 Returns all slides as an array of jQuery objects.
854 getSlides: function() {
859 jQuery.deck('getTopLevelSlides')
861 Returns all slides that are not subslides.
863 getTopLevelSlides: function() {
864 var topLevelSlides = [];
865 var slideSelector = options.selectors.slides;
866 var subSelector = [slideSelector, slideSelector].join(' ');
867 $.each(slides, function(i, $slide) {
868 if (!$slide.is(subSelector)) {
869 topLevelSlides.push($slide);
872 return topLevelSlides;
876 jQuery.deck('getNestedSlides', index)
878 index: integer, optional
880 Returns all the nested slides of the current slide. If index is
881 specified it returns the nested slides of the slide at that index.
882 If there are no nested slides this will return an empty array.
884 getNestedSlides: function(index) {
885 var targetIndex = index == null ? currentIndex : index;
886 var $targetSlide = $.deck('getSlide', targetIndex);
887 var $nesteds = $targetSlide.find(options.selectors.slides);
888 var nesteds = $nesteds.get();
889 return $.map(nesteds, function(slide, i) {
896 jQuery.deck('getContainer')
898 Returns a jQuery object containing the deck container as defined by the
901 getContainer: function() {
906 jQuery.deck('getOptions')
908 Returns the options object for the deck, including any overrides that
909 were defined at initialization.
911 getOptions: function() {
916 jQuery.deck('extend', name, method)
921 Adds method to the deck namespace with the key of name. This doesn’t
922 give access to any private member data — public methods must still be
923 used within method — but lets extension authors piggyback on the deck
924 namespace rather than pollute jQuery.
926 $.deck('extend', 'alert', function(msg) {
931 $.deck('alert', 'boom');
933 extend: function(name, method) {
934 methods[name] = method;
938 /* jQuery extension */
939 $.deck = function(method, arg) {
940 var args = Array.prototype.slice.call(arguments, 1);
941 if (methods[method]) {
942 return methods[method].apply(this, args);
945 return methods.init(method, arg);
950 The default settings object for a deck. All deck extensions should extend
951 this object to add defaults for any of their options.
953 options.classes.after
954 This class is added to all slides that appear after the 'next' slide.
956 options.classes.before
957 This class is added to all slides that appear before the 'previous'
960 options.classes.childCurrent
961 This class is added to all elements in the DOM tree between the
962 'current' slide and the deck container. For standard slides, this is
963 mostly seen and used for nested slides.
965 options.classes.current
966 This class is added to the current slide.
968 options.classes.loading
969 This class is applied to the deck container during loading phases and is
970 primarily used as a way to short circuit transitions between states
971 where such transitions are distracting or unwanted. For example, this
972 class is applied during deck initialization and then removed to prevent
973 all the slides from appearing stacked and transitioning into place
977 This class is added to the slide immediately following the 'current'
980 options.classes.onPrefix
981 This prefix, concatenated with the current slide index, is added to the
982 deck container as you change slides.
984 options.classes.previous
985 This class is added to the slide immediately preceding the 'current'
988 options.selectors.container
989 Elements matched by this CSS selector will be considered the deck
990 container. The deck container is used to scope certain states of the
991 deck, as with the onPrefix option, or with extensions such as deck.goto
994 options.selectors.slides
995 Elements matched by this selector make up the individual deck slides.
996 If a user chooses to pass the slide selector as the first argument to
997 $.deck() on initialization it does the same thing as passing in this
998 option and this option value will be set to the value of that parameter.
1001 The numeric keycode used to go to the next slide.
1003 options.keys.previous
1004 The numeric keycode used to go to the previous slide.
1006 options.touch.swipeDirection
1007 The direction swipes occur to cause slide changes. Can be 'horizontal',
1008 'vertical', or 'both'. Any other value or a falsy value will disable
1009 swipe gestures for navigation.
1011 options.touch.swipeTolerance
1012 The number of pixels the users finger must travel to produce a swipe
1015 options.initLockTimeout
1016 The number of milliseconds the init event will wait for BeforeInit event
1017 locks to be released before firing the init event regardless.
1020 Every slide that does not have an id is assigned one at initialization.
1021 Assigned ids take the form of hashPrefix + slideIndex, e.g., slide-0,
1024 options.preventFragmentScroll
1025 When deep linking to a hash of a nested slide, this scrolls the deck
1026 container to the top, undoing the natural browser behavior of scrolling
1027 to the document fragment on load.
1029 options.setAriaHiddens
1030 When set to true, deck.js will set aria hidden attributes for slides
1031 that do not appear onscreen according to a typical heirarchical
1032 deck structure. You may want to turn this off if you are using a theme
1033 where slides besides the current slide are visible on screen and should
1034 be accessible to screenreaders.
1038 after: 'deck-after',
1039 before: 'deck-before',
1040 childCurrent: 'deck-child-current',
1041 current: 'deck-current',
1042 loading: 'deck-loading',
1044 onPrefix: 'on-slide-',
1045 previous: 'deck-previous'
1049 container: '.deck-container',
1054 // enter, space, page down, right arrow, down arrow,
1055 next: [13, 32, 34, 39, 40],
1056 // backspace, page up, left arrow, up arrow
1057 previous: [8, 33, 37, 38]
1061 swipeDirection: 'horizontal',
1065 initLockTimeout: 10000,
1066 hashPrefix: 'slide-',
1067 preventFragmentScroll: true,
1068 setAriaHiddens: true
1071 $document.ready(function() {
1072 $('html').addClass('ready');
1075 $window.bind('hashchange.deck', function(event) {
1076 if (event.originalEvent && event.originalEvent.newURL) {
1077 goByHash(event.originalEvent.newURL);
1080 goByHash(window.location.hash);
1084 $window.bind('load.deck', function() {
1085 if (options.preventFragmentScroll) {
1086 $container.scrollLeft(0).scrollTop(0);
1091 // Released under MIT license
1092 // Copyright (c) 2009-2010 Dominic Baggott
1093 // Copyright (c) 2009-2010 Ash Berlin
1094 // Copyright (c) 2011 Christoph Dorn <christoph@christophdorn.com> (http://www.christophdorn.com)
1096 /*jshint browser:true, devel:true */
1098 (function( expose ) {
1103 * Markdown processing in Javascript done right. We have very particular views
1104 * on what constitutes 'right' which include:
1106 * - produces well-formed HTML (this means that em and strong nesting is
1109 * - has an intermediate representation to allow processing of parsed data (We
1110 * in fact have two, both as [JsonML]: a markdown tree and an HTML tree).
1112 * - is easily extensible to add new dialects without having to rewrite the
1113 * entire parsing mechanics
1115 * - has a good test suite
1117 * This implementation fulfills all of these (except that the test suite could
1118 * do with expanding to automatically run all the fixtures from other Markdown
1121 * ##### Intermediate Representation
1123 * *TODO* Talk about this :) Its JsonML, but document the node names we use.
1125 * [JsonML]: http://jsonml.org/ "JSON Markup Language"
1127 var Markdown = expose.Markdown = function(dialect) {
1128 switch (typeof dialect) {
1130 this.dialect = Markdown.dialects.Gruber;
1133 this.dialect = dialect;
1136 if ( dialect in Markdown.dialects ) {
1137 this.dialect = Markdown.dialects[dialect];
1140 throw new Error("Unknown Markdown dialect '" + String(dialect) + "'");
1145 this.strong_state = [];
1146 this.debug_indent = "";
1150 * parse( markdown, [dialect] ) -> JsonML
1151 * - markdown (String): markdown string to parse
1152 * - dialect (String | Dialect): the dialect to use, defaults to gruber
1154 * Parse `markdown` and return a markdown document as a Markdown.JsonML tree.
1156 expose.parse = function( source, dialect ) {
1157 // dialect will default if undefined
1158 var md = new Markdown( dialect );
1159 return md.toTree( source );
1163 * toHTML( markdown, [dialect] ) -> String
1164 * toHTML( md_tree ) -> String
1165 * - markdown (String): markdown string to parse
1166 * - md_tree (Markdown.JsonML): parsed markdown tree
1168 * Take markdown (either as a string or as a JsonML tree) and run it through
1169 * [[toHTMLTree]] then turn it into a well-formated HTML fragment.
1171 expose.toHTML = function toHTML( source , dialect , options ) {
1172 var input = expose.toHTMLTree( source , dialect , options );
1174 return expose.renderJsonML( input );
1178 * toHTMLTree( markdown, [dialect] ) -> JsonML
1179 * toHTMLTree( md_tree ) -> JsonML
1180 * - markdown (String): markdown string to parse
1181 * - dialect (String | Dialect): the dialect to use, defaults to gruber
1182 * - md_tree (Markdown.JsonML): parsed markdown tree
1184 * Turn markdown into HTML, represented as a JsonML tree. If a string is given
1185 * to this function, it is first parsed into a markdown tree by calling
1188 expose.toHTMLTree = function toHTMLTree( input, dialect , options ) {
1189 // convert string input to an MD tree
1190 if ( typeof input ==="string" ) input = this.parse( input, dialect );
1192 // Now convert the MD tree to an HTML tree
1194 // remove references from the tree
1195 var attrs = extract_attr( input ),
1198 if ( attrs && attrs.references ) {
1199 refs = attrs.references;
1202 var html = convert_tree_to_html( input, refs , options );
1203 merge_text_nodes( html );
1207 // For Spidermonkey based engines
1208 function mk_block_toSource() {
1209 return "Markdown.mk_block( " +
1210 uneval(this.toString()) +
1212 uneval(this.trailing) +
1214 uneval(this.lineNumber) +
1219 function mk_block_inspect() {
1220 var util = require("util");
1221 return "Markdown.mk_block( " +
1222 util.inspect(this.toString()) +
1224 util.inspect(this.trailing) +
1226 util.inspect(this.lineNumber) +
1231 var mk_block = Markdown.mk_block = function(block, trail, line) {
1232 // Be helpful for default case in tests.
1233 if ( arguments.length == 1 ) trail = "\n\n";
1235 var s = new String(block);
1237 // To make it clear its not just a string
1238 s.inspect = mk_block_inspect;
1239 s.toSource = mk_block_toSource;
1241 if ( line != undefined )
1242 s.lineNumber = line;
1247 function count_lines( str ) {
1249 while ( ( i = str.indexOf("\n", i + 1) ) !== -1 ) n++;
1253 // Internal - split source into rough blocks
1254 Markdown.prototype.split_blocks = function splitBlocks( input, startLine ) {
1255 input = input.replace(/(\r\n|\n|\r)/g, "\n");
1256 // [\s\S] matches _anything_ (newline or space)
1257 // [^] is equivalent but doesn't work in IEs.
1258 var re = /([\s\S]+?)($|\n#|\n(?:\s*\n|$)+)/g,
1264 if ( ( m = /^(\s*\n)/.exec(input) ) != null ) {
1265 // skip (but count) leading blank lines
1266 line_no += count_lines( m[0] );
1267 re.lastIndex = m[0].length;
1270 while ( ( m = re.exec(input) ) !== null ) {
1271 if (m[2] == "\n#") {
1275 blocks.push( mk_block( m[1], m[2], line_no ) );
1276 line_no += count_lines( m[0] );
1283 * Markdown#processBlock( block, next ) -> undefined | [ JsonML, ... ]
1284 * - block (String): the block to process
1285 * - next (Array): the following blocks
1287 * Process `block` and return an array of JsonML nodes representing `block`.
1289 * It does this by asking each block level function in the dialect to process
1290 * the block until one can. Succesful handling is indicated by returning an
1291 * array (with zero or more JsonML nodes), failure by a false value.
1293 * Blocks handlers are responsible for calling [[Markdown#processInline]]
1294 * themselves as appropriate.
1296 * If the blocks were split incorrectly or adjacent blocks need collapsing you
1297 * can adjust `next` in place using shift/splice etc.
1299 * If any of this default behaviour is not right for the dialect, you can
1300 * define a `__call__` method on the dialect that will get invoked to handle
1301 * the block processing.
1303 Markdown.prototype.processBlock = function processBlock( block, next ) {
1304 var cbs = this.dialect.block,
1305 ord = cbs.__order__;
1307 if ( "__call__" in cbs ) {
1308 return cbs.__call__.call(this, block, next);
1311 for ( var i = 0; i < ord.length; i++ ) {
1312 //D:this.debug( "Testing", ord[i] );
1313 var res = cbs[ ord[i] ].call( this, block, next );
1315 //D:this.debug(" matched");
1316 if ( !isArray(res) || ( res.length > 0 && !( isArray(res[0]) ) ) )
1317 this.debug(ord[i], "didn't return a proper array");
1318 //D:this.debug( "" );
1323 // Uhoh! no match! Should we throw an error?
1327 Markdown.prototype.processInline = function processInline( block ) {
1328 return this.dialect.inline.__call__.call( this, String( block ) );
1332 * Markdown#toTree( source ) -> JsonML
1333 * - source (String): markdown source to parse
1335 * Parse `source` into a JsonML tree representing the markdown document.
1337 // custom_tree means set this.tree to `custom_tree` and restore old value on return
1338 Markdown.prototype.toTree = function toTree( source, custom_root ) {
1339 var blocks = source instanceof Array ? source : this.split_blocks( source );
1341 // Make tree a member variable so its easier to mess with in extensions
1342 var old_tree = this.tree;
1344 this.tree = custom_root || this.tree || [ "markdown" ];
1347 while ( blocks.length ) {
1348 var b = this.processBlock( blocks.shift(), blocks );
1350 // Reference blocks and the like won't return any content
1351 if ( !b.length ) continue blocks;
1353 this.tree.push.apply( this.tree, b );
1358 if ( custom_root ) {
1359 this.tree = old_tree;
1365 Markdown.prototype.debug = function () {
1366 var args = Array.prototype.slice.call( arguments);
1367 args.unshift(this.debug_indent);
1368 if ( typeof print !== "undefined" )
1369 print.apply( print, args );
1370 if ( typeof console !== "undefined" && typeof console.log !== "undefined" )
1371 console.log.apply( null, args );
1374 Markdown.prototype.loop_re_over_block = function( re, block, cb ) {
1375 // Dont use /g regexps with this
1377 b = block.valueOf();
1379 while ( b.length && (m = re.exec(b) ) != null ) {
1380 b = b.substr( m[0].length );
1389 * Namespace of built-in dialects.
1391 Markdown.dialects = {};
1394 * Markdown.dialects.Gruber
1396 * The default dialect that follows the rules set out by John Gruber's
1397 * markdown.pl as closely as possible. Well actually we follow the behaviour of
1398 * that script which in some places is not exactly what the syntax web page
1401 Markdown.dialects.Gruber = {
1403 atxHeader: function atxHeader( block, next ) {
1404 var m = block.match( /^(#{1,6})\s*(.*?)\s*#*\s*(?:\n|$)/ );
1406 if ( !m ) return undefined;
1408 var header = [ "header", { level: m[ 1 ].length } ];
1409 Array.prototype.push.apply(header, this.processInline(m[ 2 ]));
1411 if ( m[0].length < block.length )
1412 next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) );
1417 setextHeader: function setextHeader( block, next ) {
1418 var m = block.match( /^(.*)\n([-=])\2\2+(?:\n|$)/ );
1420 if ( !m ) return undefined;
1422 var level = ( m[ 2 ] === "=" ) ? 1 : 2;
1423 var header = [ "header", { level : level }, m[ 1 ] ];
1425 if ( m[0].length < block.length )
1426 next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) );
1431 code: function code( block, next ) {
1434 // should be a code block followed by a paragraph. Fun
1436 // There might also be adjacent code block to merge.
1439 re = /^(?: {0,3}\t| {4})(.*)\n?/,
1442 // 4 spaces + content
1443 if ( !block.match( re ) ) return undefined;
1447 // Now pull out the rest of the lines
1448 var b = this.loop_re_over_block(
1449 re, block.valueOf(), function( m ) { ret.push( m[1] ); } );
1452 // Case alluded to in first comment. push it back on as a new block
1453 next.unshift( mk_block(b, block.trailing) );
1456 else if ( next.length ) {
1457 // Check the next block - it might be code too
1458 if ( !next[0].match( re ) ) break block_search;
1460 // Pull how how many blanks lines follow - minus two to account for .join
1461 ret.push ( block.trailing.replace(/[^\n]/g, "").substring(2) );
1463 block = next.shift();
1470 return [ [ "code_block", ret.join("\n") ] ];
1473 horizRule: function horizRule( block, next ) {
1474 // this needs to find any hr in the block to handle abutting blocks
1475 var m = block.match( /^(?:([\s\S]*?)\n)?[ \t]*([-_*])(?:[ \t]*\2){2,}[ \t]*(?:\n([\s\S]*))?$/ );
1481 var jsonml = [ [ "hr" ] ];
1483 // if there's a leading abutting block, process it
1485 jsonml.unshift.apply( jsonml, this.processBlock( m[ 1 ], [] ) );
1488 // if there's a trailing abutting block, stick it into next
1490 next.unshift( mk_block( m[ 3 ] ) );
1496 // There are two types of lists. Tight and loose. Tight lists have no whitespace
1497 // between the items (and result in text just in the <li>) and loose lists,
1498 // which have an empty line between list items, resulting in (one or more)
1499 // paragraphs inside the <li>.
1501 // There are all sorts weird edge cases about the original markdown.pl's
1502 // handling of lists:
1504 // * Nested lists are supposed to be indented by four chars per level. But
1505 // if they aren't, you can get a nested list by indenting by less than
1506 // four so long as the indent doesn't match an indent of an existing list
1507 // item in the 'nest stack'.
1509 // * The type of the list (bullet or number) is controlled just by the
1510 // first item at the indent. Subsequent changes are ignored unless they
1511 // are for nested lists
1513 lists: (function( ) {
1514 // Use a closure to hide a few variables.
1515 var any_list = "[*+-]|\\d+\\.",
1516 bullet_list = /[*+-]/,
1517 number_list = /\d+\./,
1518 // Capture leading indent as it matters for determining nested lists.
1519 is_list_re = new RegExp( "^( {0,3})(" + any_list + ")[ \t]+" ),
1520 indent_re = "(?: {0,3}\\t| {4})";
1522 // TODO: Cache this regexp for certain depths.
1523 // Create a regexp suitable for matching an li for a given stack depth
1524 function regex_for_depth( depth ) {
1527 // m[1] = indent, m[2] = list_type
1528 "(?:^(" + indent_re + "{0," + depth + "} {0,3})(" + any_list + ")\\s+)|" +
1530 "(^" + indent_re + "{0," + (depth-1) + "}[ ]{0,4})"
1533 function expand_tab( input ) {
1534 return input.replace( / {0,3}\t/g, " " );
1537 // Add inline content `inline` to `li`. inline comes from processInline
1538 // so is an array of content
1539 function add(li, loose, inline, nl) {
1541 li.push( [ "para" ].concat(inline) );
1544 // Hmmm, should this be any block level element or just paras?
1545 var add_to = li[li.length -1] instanceof Array && li[li.length - 1][0] == "para"
1549 // If there is already some content in this list, add the new line in
1550 if ( nl && li.length > 1 ) inline.unshift(nl);
1552 for ( var i = 0; i < inline.length; i++ ) {
1553 var what = inline[i],
1554 is_str = typeof what == "string";
1555 if ( is_str && add_to.length > 1 && typeof add_to[add_to.length-1] == "string" ) {
1556 add_to[ add_to.length-1 ] += what;
1559 add_to.push( what );
1564 // contained means have an indent greater than the current one. On
1565 // *every* line in the block
1566 function get_contained_blocks( depth, blocks ) {
1568 var re = new RegExp( "^(" + indent_re + "{" + depth + "}.*?\\n?)*$" ),
1569 replace = new RegExp("^" + indent_re + "{" + depth + "}", "gm"),
1572 while ( blocks.length > 0 ) {
1573 if ( re.exec( blocks[0] ) ) {
1574 var b = blocks.shift(),
1575 // Now remove that indent
1576 x = b.replace( replace, "");
1578 ret.push( mk_block( x, b.trailing, b.lineNumber ) );
1587 // passed to stack.forEach to turn list items up the stack into paras
1588 function paragraphify(s, i, stack) {
1590 var last_li = list[list.length-1];
1592 if ( last_li[1] instanceof Array && last_li[1][0] == "para" ) {
1595 if ( i + 1 == stack.length ) {
1597 // Keep the same array, but replace the contents
1598 last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ) );
1601 var sublist = last_li.pop();
1602 last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ), sublist );
1606 // The matcher function
1607 return function( block, next ) {
1608 var m = block.match( is_list_re );
1609 if ( !m ) return undefined;
1611 function make_list( m ) {
1612 var list = bullet_list.exec( m[2] )
1616 stack.push( { list: list, indent: m[1] } );
1621 var stack = [], // Stack of lists for nesting.
1622 list = make_list( m ),
1625 ret = [ stack[0].list ],
1628 // Loop to search over block looking for inner block elements and loose lists
1631 // Split into lines preserving new lines at end of line
1632 var lines = block.split( /(?=\n)/ );
1634 // We have to grab all lines for a li and call processInline on them
1635 // once as there are some inline things that can span lines.
1636 var li_accumulate = "";
1638 // Loop over the lines in this block looking for tight lists.
1640 for ( var line_no = 0; line_no < lines.length; line_no++ ) {
1642 l = lines[line_no].replace(/^\n/, function(n) { nl = n; return ""; });
1644 // TODO: really should cache this
1645 var line_re = regex_for_depth( stack.length );
1647 m = l.match( line_re );
1648 //print( "line:", uneval(l), "\nline match:", uneval(m) );
1650 // We have a list item
1651 if ( m[1] !== undefined ) {
1652 // Process the previous list item, if any
1653 if ( li_accumulate.length ) {
1654 add( last_li, loose, this.processInline( li_accumulate ), nl );
1655 // Loose mode will have been dealt with. Reset it
1660 m[1] = expand_tab( m[1] );
1661 var wanted_depth = Math.floor(m[1].length/4)+1;
1662 //print( "want:", wanted_depth, "stack:", stack.length);
1663 if ( wanted_depth > stack.length ) {
1664 // Deep enough for a nested list outright
1665 //print ( "new nested list" );
1666 list = make_list( m );
1667 last_li.push( list );
1668 last_li = list[1] = [ "listitem" ];
1671 // We aren't deep enough to be strictly a new level. This is
1672 // where Md.pl goes nuts. If the indent matches a level in the
1673 // stack, put it there, else put it one deeper then the
1674 // wanted_depth deserves.
1676 for ( i = 0; i < stack.length; i++ ) {
1677 if ( stack[ i ].indent != m[1] ) continue;
1678 list = stack[ i ].list;
1679 stack.splice( i+1, stack.length - (i+1) );
1685 //print("not found. l:", uneval(l));
1687 if ( wanted_depth <= stack.length ) {
1688 stack.splice(wanted_depth, stack.length - wanted_depth);
1689 //print("Desired depth now", wanted_depth, "stack:", stack.length);
1690 list = stack[wanted_depth-1].list;
1691 //print("list:", uneval(list) );
1694 //print ("made new stack for messy indent");
1695 list = make_list(m);
1700 //print( uneval(list), "last", list === stack[stack.length-1].list );
1701 last_li = [ "listitem" ];
1703 } // end depth of shenegains
1708 if ( l.length > m[0].length ) {
1709 li_accumulate += nl + l.substr( m[0].length );
1713 if ( li_accumulate.length ) {
1714 add( last_li, loose, this.processInline( li_accumulate ), nl );
1715 // Loose mode will have been dealt with. Reset it
1720 // Look at the next block - we might have a loose list. Or an extra
1721 // paragraph for the current li
1722 var contained = get_contained_blocks( stack.length, next );
1724 // Deal with code blocks or properly nested lists
1725 if ( contained.length > 0 ) {
1726 // Make sure all listitems up the stack are paragraphs
1727 forEach( stack, paragraphify, this);
1729 last_li.push.apply( last_li, this.toTree( contained, [] ) );
1732 var next_block = next[0] && next[0].valueOf() || "";
1734 if ( next_block.match(is_list_re) || next_block.match( /^ / ) ) {
1735 block = next.shift();
1737 // Check for an HR following a list: features/lists/hr_abutting
1738 var hr = this.dialect.block.horizRule( block, next );
1741 ret.push.apply(ret, hr);
1745 // Make sure all listitems up the stack are paragraphs
1746 forEach( stack, paragraphify, this);
1749 continue loose_search;
1758 blockquote: function blockquote( block, next ) {
1759 if ( !block.match( /^>/m ) )
1764 // separate out the leading abutting block, if any. I.e. in this case:
1769 if ( block[ 0 ] != ">" ) {
1770 var lines = block.split( /\n/ ),
1772 line_no = block.lineNumber;
1774 // keep shifting lines until you find a crotchet
1775 while ( lines.length && lines[ 0 ][ 0 ] != ">" ) {
1776 prev.push( lines.shift() );
1780 var abutting = mk_block( prev.join( "\n" ), "\n", block.lineNumber );
1781 jsonml.push.apply( jsonml, this.processBlock( abutting, [] ) );
1782 // reassemble new block of just block quotes!
1783 block = mk_block( lines.join( "\n" ), block.trailing, line_no );
1787 // if the next block is also a blockquote merge it in
1788 while ( next.length && next[ 0 ][ 0 ] == ">" ) {
1789 var b = next.shift();
1790 block = mk_block( block + block.trailing + b, b.trailing, block.lineNumber );
1793 // Strip off the leading "> " and re-process as a block.
1794 var input = block.replace( /^> ?/gm, "" ),
1795 old_tree = this.tree,
1796 processedBlock = this.toTree( input, [ "blockquote" ] ),
1797 attr = extract_attr( processedBlock );
1799 // If any link references were found get rid of them
1800 if ( attr && attr.references ) {
1801 delete attr.references;
1802 // And then remove the attribute object if it's empty
1803 if ( isEmpty( attr ) ) {
1804 processedBlock.splice( 1, 1 );
1808 jsonml.push( processedBlock );
1812 referenceDefn: function referenceDefn( block, next) {
1813 var re = /^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/;
1814 // interesting matches are [ , ref_id, url, , title, title ]
1816 if ( !block.match(re) )
1819 // make an attribute node if it doesn't exist
1820 if ( !extract_attr( this.tree ) ) {
1821 this.tree.splice( 1, 0, {} );
1824 var attrs = extract_attr( this.tree );
1826 // make a references hash if it doesn't exist
1827 if ( attrs.references === undefined ) {
1828 attrs.references = {};
1831 var b = this.loop_re_over_block(re, block, function( m ) {
1833 if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" )
1834 m[2] = m[2].substring( 1, m[2].length - 1 );
1836 var ref = attrs.references[ m[1].toLowerCase() ] = {
1840 if ( m[4] !== undefined )
1842 else if ( m[5] !== undefined )
1848 next.unshift( mk_block( b, block.trailing ) );
1853 para: function para( block, next ) {
1854 // everything's a para!
1855 return [ ["para"].concat( this.processInline( block ) ) ];
1860 Markdown.dialects.Gruber.inline = {
1862 __oneElement__: function oneElement( text, patterns_or_re, previous_nodes ) {
1867 patterns_or_re = patterns_or_re || this.dialect.inline.__patterns__;
1868 var re = new RegExp( "([\\s\\S]*?)(" + (patterns_or_re.source || patterns_or_re) + ")" );
1870 m = re.exec( text );
1873 return [ text.length, text ];
1876 // Some un-interesting text matched. Return that first
1877 return [ m[1].length, m[1] ];
1881 if ( m[2] in this.dialect.inline ) {
1882 res = this.dialect.inline[ m[2] ].call(
1884 text.substr( m.index ), m, previous_nodes || [] );
1886 // Default for now to make dev easier. just slurp special and output it.
1887 res = res || [ m[2].length, m[2] ];
1891 __call__: function inline( text, patterns ) {
1897 //D:self.debug(" adding output", uneval(x));
1898 if ( typeof x == "string" && typeof out[out.length-1] == "string" )
1899 out[ out.length-1 ] += x;
1904 while ( text.length > 0 ) {
1905 res = this.dialect.inline.__oneElement__.call(this, text, patterns, out );
1906 text = text.substr( res.shift() );
1913 // These characters are intersting elsewhere, so have rules for them so that
1914 // chunks of plain text blocks don't include them
1915 "]": function () {},
1916 "}": function () {},
1918 __escape__ : /^\\[\\`\*_{}\[\]()#\+.!\-]/,
1920 "\\": function escaped( text ) {
1921 // [ length of input processed, node/children to add... ]
1922 // Only esacape: \ ` * _ { } [ ] ( ) # * + - . !
1923 if ( this.dialect.inline.__escape__.exec( text ) )
1924 return [ 2, text.charAt( 1 ) ];
1930 "![": function image( text ) {
1932 // Unlike images, alt text is plain text only. no other elements are
1935 // ![Alt text](/path/to/img.jpg "Optional title")
1936 // 1 2 3 4 <--- captures
1937 var m = text.match( /^!\[(.*?)\][ \t]*\([ \t]*([^")]*?)(?:[ \t]+(["'])(.*?)\3)?[ \t]*\)/ );
1940 if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" )
1941 m[2] = m[2].substring( 1, m[2].length - 1 );
1943 m[2] = this.dialect.inline.__call__.call( this, m[2], /\\/ )[0];
1945 var attrs = { alt: m[1], href: m[2] || "" };
1946 if ( m[4] !== undefined)
1949 return [ m[0].length, [ "img", attrs ] ];
1953 m = text.match( /^!\[(.*?)\][ \t]*\[(.*?)\]/ );
1956 // We can't check if the reference is known here as it likely wont be
1957 // found till after. Check it in md tree->hmtl tree conversion
1958 return [ m[0].length, [ "img_ref", { alt: m[1], ref: m[2].toLowerCase(), original: m[0] } ] ];
1961 // Just consume the '!['
1965 "[": function link( text ) {
1967 var orig = String(text);
1968 // Inline content is possible inside `link text`
1969 var res = Markdown.DialectHelpers.inline_until_char.call( this, text.substr(1), "]" );
1971 // No closing ']' found. Just consume the [
1972 if ( !res ) return [ 1, "[" ];
1974 var consumed = 1 + res[ 0 ],
1975 children = res[ 1 ],
1979 // At this point the first [...] has been parsed. See what follows to find
1980 // out which kind of link we are (reference or direct url)
1981 text = text.substr( consumed );
1983 // [link text](/path/to/img.jpg "Optional title")
1984 // 1 2 3 <--- captures
1985 // This will capture up to the last paren in the block. We then pull
1986 // back based on if there a matching ones in the url
1987 // ([here](/url/(test))
1988 // The parens have to be balanced
1989 var m = text.match( /^\s*\([ \t]*([^"']*)(?:[ \t]+(["'])(.*?)\2)?[ \t]*\)/ );
1992 consumed += m[0].length;
1994 if ( url && url[0] == "<" && url[url.length-1] == ">" )
1995 url = url.substring( 1, url.length - 1 );
1997 // If there is a title we don't have to worry about parens in the url
1999 var open_parens = 1; // One open that isn't in the capture
2000 for ( var len = 0; len < url.length; len++ ) {
2001 switch ( url[len] ) {
2006 if ( --open_parens == 0) {
2007 consumed -= url.length - len;
2008 url = url.substring(0, len);
2015 // Process escapes only
2016 url = this.dialect.inline.__call__.call( this, url, /\\/ )[0];
2018 attrs = { href: url || "" };
2019 if ( m[3] !== undefined)
2022 link = [ "link", attrs ].concat( children );
2023 return [ consumed, link ];
2028 m = text.match( /^\s*\[(.*?)\]/ );
2032 consumed += m[ 0 ].length;
2034 // [links][] uses links as its reference
2035 attrs = { ref: ( m[ 1 ] || String(children) ).toLowerCase(), original: orig.substr( 0, consumed ) };
2037 link = [ "link_ref", attrs ].concat( children );
2039 // We can't check if the reference is known here as it likely wont be
2040 // found till after. Check it in md tree->hmtl tree conversion.
2041 // Store the original so that conversion can revert if the ref isn't found.
2042 return [ consumed, link ];
2046 // Only if id is plain (no formatting.)
2047 if ( children.length == 1 && typeof children[0] == "string" ) {
2049 attrs = { ref: children[0].toLowerCase(), original: orig.substr( 0, consumed ) };
2050 link = [ "link_ref", attrs, children[0] ];
2051 return [ consumed, link ];
2054 // Just consume the "["
2059 "<": function autoLink( text ) {
2062 if ( ( m = text.match( /^<(?:((https?|ftp|mailto):[^>]+)|(.*?@.*?\.[a-zA-Z]+))>/ ) ) != null ) {
2064 return [ m[0].length, [ "link", { href: "mailto:" + m[3] }, m[3] ] ];
2067 else if ( m[2] == "mailto" ) {
2068 return [ m[0].length, [ "link", { href: m[1] }, m[1].substr("mailto:".length ) ] ];
2071 return [ m[0].length, [ "link", { href: m[1] }, m[1] ] ];
2077 "`": function inlineCode( text ) {
2078 // Inline code block. as many backticks as you like to start it
2079 // Always skip over the opening ticks.
2080 var m = text.match( /(`+)(([\s\S]*?)\1)/ );
2083 return [ m[1].length + m[2].length, [ "inlinecode", m[3] ] ];
2085 // TODO: No matching end code found - warn!
2090 " \n": function lineBreak( text ) {
2091 return [ 3, [ "linebreak" ] ];
2096 // Meta Helper/generator method for em and strong handling
2097 function strong_em( tag, md ) {
2099 var state_slot = tag + "_state",
2100 other_slot = tag == "strong" ? "em_state" : "strong_state";
2102 function CloseTag(len) {
2103 this.len_after = len;
2104 this.name = "close_" + md;
2107 return function ( text, orig_match ) {
2109 if ( this[state_slot][0] == md ) {
2110 // Most recent em is of this type
2111 //D:this.debug("closing", md);
2112 this[state_slot].shift();
2114 // "Consume" everything to go back to the recrusion in the else-block below
2115 return[ text.length, new CloseTag(text.length-md.length) ];
2118 // Store a clone of the em/strong states
2119 var other = this[other_slot].slice(),
2120 state = this[state_slot].slice();
2122 this[state_slot].unshift(md);
2124 //D:this.debug_indent += " ";
2127 var res = this.processInline( text.substr( md.length ) );
2128 //D:this.debug_indent = this.debug_indent.substr(2);
2130 var last = res[res.length - 1];
2132 //D:this.debug("processInline from", tag + ": ", uneval( res ) );
2134 var check = this[state_slot].shift();
2135 if ( last instanceof CloseTag ) {
2137 // We matched! Huzzah.
2138 var consumed = text.length - last.len_after;
2139 return [ consumed, [ tag ].concat(res) ];
2142 // Restore the state of the other kind. We might have mistakenly closed it.
2143 this[other_slot] = other;
2144 this[state_slot] = state;
2146 // We can't reuse the processed result as it could have wrong parsing contexts in it.
2147 return [ md.length, md ];
2150 }; // End returned function
2153 Markdown.dialects.Gruber.inline["**"] = strong_em("strong", "**");
2154 Markdown.dialects.Gruber.inline["__"] = strong_em("strong", "__");
2155 Markdown.dialects.Gruber.inline["*"] = strong_em("em", "*");
2156 Markdown.dialects.Gruber.inline["_"] = strong_em("em", "_");
2159 // Build default order from insertion order.
2160 Markdown.buildBlockOrder = function(d) {
2162 for ( var i in d ) {
2163 if ( i == "__order__" || i == "__call__" ) continue;
2169 // Build patterns for inline matcher
2170 Markdown.buildInlinePatterns = function(d) {
2173 for ( var i in d ) {
2174 // __foo__ is reserved and not a pattern
2175 if ( i.match( /^__.*__$/) ) continue;
2176 var l = i.replace( /([\\.*+?|()\[\]{}])/g, "\\$1" )
2177 .replace( /\n/, "\\n" );
2178 patterns.push( i.length == 1 ? l : "(?:" + l + ")" );
2181 patterns = patterns.join("|");
2182 d.__patterns__ = patterns;
2183 //print("patterns:", uneval( patterns ) );
2185 var fn = d.__call__;
2186 d.__call__ = function(text, pattern) {
2187 if ( pattern != undefined ) {
2188 return fn.call(this, text, pattern);
2192 return fn.call(this, text, patterns);
2197 Markdown.DialectHelpers = {};
2198 Markdown.DialectHelpers.inline_until_char = function( text, want ) {
2203 if ( text.charAt( consumed ) == want ) {
2204 // Found the character we were looking for
2206 return [ consumed, nodes ];
2209 if ( consumed >= text.length ) {
2210 // No closing char found. Abort.
2214 var res = this.dialect.inline.__oneElement__.call(this, text.substr( consumed ) );
2215 consumed += res[ 0 ];
2216 // Add any returned nodes.
2217 nodes.push.apply( nodes, res.slice( 1 ) );
2221 // Helper function to make sub-classing a dialect easier
2222 Markdown.subclassDialect = function( d ) {
2224 Block.prototype = d.block;
2225 function Inline() {}
2226 Inline.prototype = d.inline;
2228 return { block: new Block(), inline: new Inline() };
2231 Markdown.buildBlockOrder ( Markdown.dialects.Gruber.block );
2232 Markdown.buildInlinePatterns( Markdown.dialects.Gruber.inline );
2234 Markdown.dialects.Maruku = Markdown.subclassDialect( Markdown.dialects.Gruber );
2236 Markdown.dialects.Maruku.processMetaHash = function processMetaHash( meta_string ) {
2237 var meta = split_meta_hash( meta_string ),
2240 for ( var i = 0; i < meta.length; ++i ) {
2242 if ( /^#/.test( meta[ i ] ) ) {
2243 attr.id = meta[ i ].substring( 1 );
2246 else if ( /^\./.test( meta[ i ] ) ) {
2247 // if class already exists, append the new one
2248 if ( attr["class"] ) {
2249 attr["class"] = attr["class"] + meta[ i ].replace( /./, " " );
2252 attr["class"] = meta[ i ].substring( 1 );
2255 // attribute: foo=bar
2256 else if ( /\=/.test( meta[ i ] ) ) {
2257 var s = meta[ i ].split( /\=/ );
2258 attr[ s[ 0 ] ] = s[ 1 ];
2265 function split_meta_hash( meta_string ) {
2266 var meta = meta_string.split( "" ),
2270 while ( meta.length ) {
2271 var letter = meta.shift();
2274 // if we're in a quoted section, keep it
2276 parts[ parts.length - 1 ] += letter;
2278 // otherwise make a new part
2285 // reverse the quotes and move straight on
2286 in_quotes = !in_quotes;
2289 // shift off the next letter to be used straight away.
2290 // it was escaped so we'll keep it whatever it is
2291 letter = meta.shift();
2293 parts[ parts.length - 1 ] += letter;
2301 Markdown.dialects.Maruku.block.document_meta = function document_meta( block, next ) {
2302 // we're only interested in the first block
2303 if ( block.lineNumber > 1 ) return undefined;
2305 // document_meta blocks consist of one or more lines of `Key: Value\n`
2306 if ( ! block.match( /^(?:\w+:.*\n)*\w+:.*$/ ) ) return undefined;
2308 // make an attribute node if it doesn't exist
2309 if ( !extract_attr( this.tree ) ) {
2310 this.tree.splice( 1, 0, {} );
2313 var pairs = block.split( /\n/ );
2314 for ( p in pairs ) {
2315 var m = pairs[ p ].match( /(\w+):\s*(.*)$/ ),
2316 key = m[ 1 ].toLowerCase(),
2319 this.tree[ 1 ][ key ] = value;
2322 // document_meta produces no content!
2326 Markdown.dialects.Maruku.block.block_meta = function block_meta( block, next ) {
2327 // check if the last line of the block is an meta hash
2328 var m = block.match( /(^|\n) {0,3}\{:\s*((?:\\\}|[^\}])*)\s*\}$/ );
2329 if ( !m ) return undefined;
2331 // process the meta hash
2332 var attr = this.dialect.processMetaHash( m[ 2 ] );
2336 // if we matched ^ then we need to apply meta to the previous block
2337 if ( m[ 1 ] === "" ) {
2338 var node = this.tree[ this.tree.length - 1 ];
2339 hash = extract_attr( node );
2341 // if the node is a string (rather than JsonML), bail
2342 if ( typeof node === "string" ) return undefined;
2344 // create the attribute hash if it doesn't exist
2347 node.splice( 1, 0, hash );
2350 // add the attributes in
2352 hash[ a ] = attr[ a ];
2355 // return nothing so the meta hash is removed
2359 // pull the meta hash off the block and process what's left
2360 var b = block.replace( /\n.*$/, "" ),
2361 result = this.processBlock( b, [] );
2363 // get or make the attributes hash
2364 hash = extract_attr( result[ 0 ] );
2367 result[ 0 ].splice( 1, 0, hash );
2370 // attach the attributes to the block
2372 hash[ a ] = attr[ a ];
2378 Markdown.dialects.Maruku.block.definition_list = function definition_list( block, next ) {
2379 // one or more terms followed by one or more definitions, in a single block
2380 var tight = /^((?:[^\s:].*\n)+):\s+([\s\S]+)$/,
2384 // see if we're dealing with a tight or loose block
2385 if ( ( m = block.match( tight ) ) ) {
2386 // pull subsequent tight DL blocks out of `next`
2387 var blocks = [ block ];
2388 while ( next.length && tight.exec( next[ 0 ] ) ) {
2389 blocks.push( next.shift() );
2392 for ( var b = 0; b < blocks.length; ++b ) {
2393 var m = blocks[ b ].match( tight ),
2394 terms = m[ 1 ].replace( /\n$/, "" ).split( /\n/ ),
2395 defns = m[ 2 ].split( /\n:\s+/ );
2397 // print( uneval( m ) );
2399 for ( i = 0; i < terms.length; ++i ) {
2400 list.push( [ "dt", terms[ i ] ] );
2403 for ( i = 0; i < defns.length; ++i ) {
2404 // run inline processing over the definition
2405 list.push( [ "dd" ].concat( this.processInline( defns[ i ].replace( /(\n)\s+/, "$1" ) ) ) );
2416 // splits on unescaped instances of @ch. If @ch is not a character the result
2417 // can be unpredictable
2419 Markdown.dialects.Maruku.block.table = function table (block, next) {
2421 var _split_on_unescaped = function(s, ch) {
2423 if (ch.match(/^[\\|\[\]{}?*.+^$]$/)) { ch = '\\' + ch; }
2425 r = new RegExp('^((?:\\\\.|[^\\\\' + ch + '])*)' + ch + '(.*)'),
2427 while(m = s.match(r)) {
2435 var leading_pipe = /^ {0,3}\|(.+)\n {0,3}\|\s*([\-:]+[\-| :]*)\n((?:\s*\|.*(?:\n|$))*)(?=\n|$)/,
2436 // find at least an unescaped pipe in each line
2437 no_leading_pipe = /^ {0,3}(\S(?:\\.|[^\\|])*\|.*)\n {0,3}([\-:]+\s*\|[\-| :]*)\n((?:(?:\\.|[^\\|])*\|.*(?:\n|$))*)(?=\n|$)/,
2439 if (m = block.match(leading_pipe)) {
2440 // remove leading pipes in contents
2441 // (header and horizontal rule already have the leading pipe left out)
2442 m[3] = m[3].replace(/^\s*\|/gm, '');
2443 } else if (! ( m = block.match(no_leading_pipe))) {
2447 var table = [ "table", [ "thead", [ "tr" ] ], [ "tbody" ] ];
2449 // remove trailing pipes, then split on pipes
2450 // (no escaped pipes are allowed in horizontal rule)
2451 m[2] = m[2].replace(/\|\s*$/, '').split('|');
2453 // process alignment
2454 var html_attrs = [ ];
2455 forEach (m[2], function (s) {
2456 if (s.match(/^\s*-+:\s*$/)) html_attrs.push({align: "right"});
2457 else if (s.match(/^\s*:-+\s*$/)) html_attrs.push({align: "left"});
2458 else if (s.match(/^\s*:-+:\s*$/)) html_attrs.push({align: "center"});
2459 else html_attrs.push({});
2462 // now for the header, avoid escaped pipes
2463 m[1] = _split_on_unescaped(m[1].replace(/\|\s*$/, ''), '|');
2464 for (i = 0; i < m[1].length; i++) {
2465 table[1][1].push(['th', html_attrs[i] || {}].concat(
2466 this.processInline(m[1][i].trim())));
2469 // now for body contents
2470 forEach (m[3].replace(/\|\s*$/mg, '').split('\n'), function (row) {
2471 var html_row = ['tr'];
2472 row = _split_on_unescaped(row, '|');
2473 for (i = 0; i < row.length; i++) {
2474 html_row.push(['td', html_attrs[i] || {}].concat(this.processInline(row[i].trim())));
2476 table[2].push(html_row);
2482 Markdown.dialects.Maruku.inline[ "{:" ] = function inline_meta( text, matches, out ) {
2483 if ( !out.length ) {
2487 // get the preceeding element
2488 var before = out[ out.length - 1 ];
2490 if ( typeof before === "string" ) {
2494 // match a meta hash
2495 var m = text.match( /^\{:\s*((?:\\\}|[^\}])*)\s*\}/ );
2497 // no match, false alarm
2502 // attach the attributes to the preceeding element
2503 var meta = this.dialect.processMetaHash( m[ 1 ] ),
2504 attr = extract_attr( before );
2508 before.splice( 1, 0, attr );
2511 for ( var k in meta ) {
2512 attr[ k ] = meta[ k ];
2515 // cut out the string and replace it with nothing
2516 return [ m[ 0 ].length, "" ];
2519 Markdown.dialects.Maruku.inline.__escape__ = /^\\[\\`\*_{}\[\]()#\+.!\-|:]/;
2521 Markdown.buildBlockOrder ( Markdown.dialects.Maruku.block );
2522 Markdown.buildInlinePatterns( Markdown.dialects.Maruku.inline );
2524 var isArray = Array.isArray || function(obj) {
2525 return Object.prototype.toString.call(obj) == "[object Array]";
2529 // Don't mess with Array.prototype. Its not friendly
2530 if ( Array.prototype.forEach ) {
2531 forEach = function( arr, cb, thisp ) {
2532 return arr.forEach( cb, thisp );
2536 forEach = function(arr, cb, thisp) {
2537 for (var i = 0; i < arr.length; i++) {
2538 cb.call(thisp || arr, arr[i], i, arr);
2543 var isEmpty = function( obj ) {
2544 for ( var key in obj ) {
2545 if ( hasOwnProperty.call( obj, key ) ) {
2553 function extract_attr( jsonml ) {
2554 return isArray(jsonml)
2555 && jsonml.length > 1
2556 && typeof jsonml[ 1 ] === "object"
2557 && !( isArray(jsonml[ 1 ]) )
2565 * renderJsonML( jsonml[, options] ) -> String
2566 * - jsonml (Array): JsonML array to render to XML
2567 * - options (Object): options
2569 * Converts the given JsonML into well-formed XML.
2571 * The options currently understood are:
2573 * - root (Boolean): wether or not the root node should be included in the
2574 * output, or just its children. The default `false` is to not include the
2577 expose.renderJsonML = function( jsonml, options ) {
2578 options = options || {};
2579 // include the root element in the rendered output?
2580 options.root = options.root || false;
2584 if ( options.root ) {
2585 content.push( render_tree( jsonml ) );
2588 jsonml.shift(); // get rid of the tag
2589 if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) {
2590 jsonml.shift(); // get rid of the attributes
2593 while ( jsonml.length ) {
2594 content.push( render_tree( jsonml.shift() ) );
2598 return content.join( "\n\n" );
2601 function escapeHTML( text ) {
2602 return text.replace( /&/g, "&" )
2603 .replace( /</g, "<" )
2604 .replace( />/g, ">" )
2605 .replace( /"/g, """ )
2606 .replace( /'/g, "'" );
2609 function render_tree( jsonml ) {
2611 if ( typeof jsonml === "string" ) {
2612 return jsonml; // modified for deck.smarkdown.js
2615 var tag = jsonml.shift(),
2619 if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) {
2620 attributes = jsonml.shift();
2623 while ( jsonml.length ) {
2624 content.push( render_tree( jsonml.shift() ) );
2628 for ( var a in attributes ) {
2629 tag_attrs += " " + a + '="' + escapeHTML( attributes[ a ] ) + '"';
2632 // be careful about adding whitespace here for inline elements
2633 if ( tag == "img" || tag == "br" || tag == "hr" ) {
2634 return "<"+ tag + tag_attrs + "/>";
2637 return "<"+ tag + tag_attrs + ">" + content.join( "" ) + "</" + tag + ">";
2641 function convert_tree_to_html( tree, references, options ) {
2643 options = options || {};
2646 var jsonml = tree.slice( 0 );
2648 if ( typeof options.preprocessTreeNode === "function" ) {
2649 jsonml = options.preprocessTreeNode(jsonml, references);
2652 // Clone attributes if they exist
2653 var attrs = extract_attr( jsonml );
2656 for ( i in attrs ) {
2657 jsonml[ 1 ][ i ] = attrs[ i ];
2659 attrs = jsonml[ 1 ];
2663 if ( typeof jsonml === "string" ) {
2667 // convert this node
2668 switch ( jsonml[ 0 ] ) {
2670 jsonml[ 0 ] = "h" + jsonml[ 1 ].level;
2671 delete jsonml[ 1 ].level;
2686 jsonml[ 0 ] = "html";
2687 if ( attrs ) delete attrs.references;
2690 jsonml[ 0 ] = "pre";
2692 var code = [ "code" ];
2693 code.push.apply( code, jsonml.splice( i, jsonml.length - i ) );
2697 jsonml[ 0 ] = "code";
2700 jsonml[ 1 ].src = jsonml[ 1 ].href;
2701 delete jsonml[ 1 ].href;
2712 // grab this ref and clean up the attribute node
2713 var ref = references[ attrs.ref ];
2715 // if the reference exists, make the link
2719 // add in the href and title, if present
2720 attrs.href = ref.href;
2722 attrs.title = ref.title;
2725 // get rid of the unneeded original text
2726 delete attrs.original;
2728 // the reference doesn't exist, so revert to plain text
2730 return attrs.original;
2734 jsonml[ 0 ] = "img";
2736 // grab this ref and clean up the attribute node
2737 var ref = references[ attrs.ref ];
2739 // if the reference exists, make the link
2743 // add in the href and title, if present
2744 attrs.src = ref.href;
2746 attrs.title = ref.title;
2749 // get rid of the unneeded original text
2750 delete attrs.original;
2752 // the reference doesn't exist, so revert to plain text
2754 return attrs.original;
2759 // convert all the children
2762 // deal with the attribute node, if it exists
2764 // if there are keys, skip over it
2765 for ( var key in jsonml[ 1 ] ) {
2769 // if there aren't, remove it
2771 jsonml.splice( i, 1 );
2775 for ( ; i < jsonml.length; ++i ) {
2776 jsonml[ i ] = convert_tree_to_html( jsonml[ i ], references, options );
2783 // merges adjacent text nodes into a single node
2784 function merge_text_nodes( jsonml ) {
2785 // skip the tag name and attribute hash
2786 var i = extract_attr( jsonml ) ? 2 : 1;
2788 while ( i < jsonml.length ) {
2789 // if it's a string check the next item too
2790 if ( typeof jsonml[ i ] === "string" ) {
2791 if ( i + 1 < jsonml.length && typeof jsonml[ i + 1 ] === "string" ) {
2792 // merge the second string into the first and remove it
2793 jsonml[ i ] += jsonml.splice( i + 1, 1 )[ 0 ];
2799 // if it's not a string recurse
2801 merge_text_nodes( jsonml[ i ] );
2808 if ( typeof exports === "undefined" ) {
2809 window.markdown = {};
2810 return window.markdown;
2818 Deck JS - deck.smarkdown
2819 Copyright (c) 2014-2014 RĂ©mi Emonet
2820 Licensed under the MIT license.
2821 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
2825 This module provides a support for a shorter syntax for slides, with a syntax that is closer to plain markdown.
2827 - configurize the .smark and the default duration also
2828 - have a shortcut for {slide}?
2832 (function($, deck, undefined) {
2833 var $d = $(document);
2834 var may = function(f) {return f ? f : function() {}};
2835 var endsWith = function(longStr, part) {return longStr.indexOf(part, longStr.length - part.length) !== -1;}
2837 var startsWith = function(longStr, part) {
2838 if (part == "%+class:") alert(":::"+longStr+":::");
2839 var res = longStr.substr(0, part.length) == part;
2840 REST = res ? longStr.slice(part.length) : null;
2841 RESTRIM = res ? REST.replace(/^ */, "") : null;
2844 var startsWithIgnoreCase = function(longStr, part) {
2845 var res = longStr.substr(0, part.length).toUpperCase() == part.toUpperCase();
2846 REST = res ? longStr.slice(part.length) : null;
2847 RESTRIM = res ? REST.replace(/^ */, "") : null;
2850 var isArray = Array.isArray || $.isArray; // there is also an alternative in markdownjs
2852 // the animation duration is stateful across the smarkdown sections
2853 var animationDurationDefault = 400;
2854 var animationDuration = animationDurationDefault;
2856 function clone(a) { return JSON.parse(JSON.stringify(a)) }
2857 function findTag(tree, regexp, startAt) {
2858 var i = startAt || 0;
2859 while (i < tree.length) {
2860 if (isArray(tree[i]) && tree[i][0].match(regexp)) {
2867 function addSpaceSeparatedAttr(o, a, c) {
2868 ensureHasAttributes(o);
2874 function addClass(o, c) {
2875 addSpaceSeparatedAttr(o, 'class', c);
2877 function hasClass(o, c) {
2878 if (!isObject(o[1]) || !o[1]['class']) {
2881 return o[1]['class'].match(new RegExp("\\b"+c+"\\b"));
2884 function isObject(o) {
2885 return !isArray(o) && typeof(o) === 'object';
2887 function ensureHasAttributes(tree) {
2888 if (!isObject(tree[1])) {
2889 tree.splice(1, 0, {});
2894 function lazyGetAttributes(tree) {
2895 if (isObject(tree[1])) {
2901 function lazyUnsetAttributes(tree) {
2902 if (isObject(tree[1])) {
2906 function hasIDOrClassDecoration(s) {
2907 return s.match(/^(.*)\{([^{}<>]*)\}$/);
2909 function maybeProcessCopySlide(tree, index) {
2910 var slide = tree[index];
2911 ensureHasAttributes(slide);
2912 if (slide.length != 3) return false;
2913 if (slide[2][0] != "h1") return false;
2914 ensureHasAttributes(slide[2]);
2915 if (startsWithIgnoreCase(slide[2][2], "@COPY:#")) {
2916 var main = RESTRIM.split(/:/);
2917 var idOfBase = main[0];
2918 var animPart = main.slice(1).join(":");
2919 var hasAnim = ! animPart.match(/^\s*$/);
2922 if (i == 0 || (i==1 && isObject(tree[1]))) continue;
2923 ensureHasAttributes(tree[i]);
2924 if (tree[i][1].id == idOfBase) {
2929 if (base == null) { alert("pb"); return false; } // TODO should alert based on options
2930 var content = [["div", {}, "@anim:" + animPart]];
2931 content = content.concat(clone(base.slice(2)));
2932 slide[1] = clone(base[1]);
2934 if (hasAnim) addClass(slide, "anim-continue");
2935 slide.splice.apply(slide, [2, 1].concat(content)); // replace the h1 with content
2940 function processIDOrClassDecoration(tree, index) {
2941 var matched = hasIDOrClassDecoration(tree[index]); // make sure the group is set
2942 if (!matched) { alert("should call processIDOrClassDecoration() only if hasIDOrClassDecoration is true"); return; }
2943 var returnValue = false; // whether we added the attributes
2944 var base = RegExp.$1;
2945 var decorations = RegExp.$2.split(/ +/);
2946 if (ensureHasAttributes(tree)) {
2947 if (index>0) index++;
2951 for (d in decorations) {
2952 // allow .class and class notations
2953 if (startsWith(decorations[d], ".")) decorations[d] = decorations[d].slice(1);
2955 if (startsWith(decorations[d], "#")) {
2956 tree[1].id = decorations[d].slice(1);
2958 if (startsWith(decorations[d], "*") | startsWith(decorations[d], "/")) {
2959 addSpaceSeparatedAttr(tree, "data-container-class", decorations[d].slice(1));
2961 addClass(tree, decorations[d]);
2967 function possiblyHideIfEmpty(tree) { // if it contains only anim stuf etc
2969 var i = isObject(tree[1]) ? 2 : 1;
2970 function onlyDivAnims(tt) {
2972 var start = isObject(tt[1]) ? 2 : 1;
2973 tt.slice(start).forEach(function(e) {
2974 if (!isArray(e) || !isObject(e[1]) || (" "+e[1]["class"]).indexOf(" anim-") == -1) {
2981 if (onlyDivAnims(tree)) hide = true;
2982 else if (tree.length == i+1 && isArray(tree[i]) && tree[i][0] == "p"
2983 && onlyDivAnims(tree[i])) hide = true;
2985 ensureHasAttributes(tree);
2986 tree[1].style = "display: none";
2989 function maybeProcessComment(tree, index) {
2990 var line = tree[index];
2991 var clean = function(s) { return s;}; //return s.replace(/\/\\\//g, '//'); };
2992 if (line.match(/^(.*?)[\n\s]*\/\/ +(.*)/)) {
2995 }, clean(RegExp.$2)];
2996 tree.splice(index, 1, RegExp.$1, obj);
2999 tree[index] = clean(tree[index]);
3002 function maybeProcessAtSomething(tree, index) {
3003 var line = tree[index];
3004 if (startsWithIgnoreCase(line, "@SVG:")) {
3005 var content = RESTRIM
3006 var parts = content.split(/ +/);
3007 if (hasIDOrClassDecoration(content) || parts.length == 3) {
3010 'data-src': parts[0],
3011 'data-width': parts[1],
3012 'data-height': parts[2],
3013 'class': "svg-object"
3014 }, parts.slice(3).join(" ")];
3015 // TODO: alert when wrong number of args
3016 if (hasIDOrClassDecoration(content)) processIDOrClassDecoration(obj, 2);
3019 // TODO allow this only when an option is set option
3020 // old, smartsyntax version
3022 'data-src': parts[1],
3023 'data-width': parts[2],
3024 'data-height': parts[3],
3025 'class': "svg-object"
3027 parts[0].split(/,/).forEach(function (p) { addClass(obj, p); });
3030 } else if (startsWithIgnoreCase(line, "@ANIM:")) {
3031 line = RESTRIM.replace(/%[+]/i, "%%"); // protect the "%+class" from being split
3033 var parts = line.split(/ *\| */); // TODO: configurize + reconsider all separators?
3035 // process each group of simultaneous animations
3036 var subparts = parts[i].split(/ *\+ */);
3037 for (ii in subparts) {
3038 var what = subparts[ii];
3039 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)
3040 var continuating = ii != subparts.length-1;
3041 var toAdd = ["div", {}, ""];
3042 addClass(toAdd, "slide");
3043 // process the individual element (reminder: animationDuration is global)
3044 function dw() { addSpaceSeparatedAttr(toAdd, "data-what", REST); }
3045 function dd() { addSpaceSeparatedAttr(toAdd, "data-dur", ""+animationDuration); }
3046 if (startsWithIgnoreCase(what, "%duration:")) {
3047 animationDuration = RESTRIM == "" ? animationDurationDefault : RESTRIM;
3049 } else if (startsWithIgnoreCase(what, "%dur:")) {
3050 animationDuration = RESTRIM == "" ? animationDurationDefault : RESTRIM;
3052 } else if (startsWithIgnoreCase(what, "%play:")) {
3053 addClass(toAdd, "anim-play");
3055 } else if (startsWithIgnoreCase(what, "%pause:")) {
3056 addClass(toAdd, "anim-pause");
3058 } else if (startsWith(what, "%viewbox:")) {
3059 addClass(toAdd, "anim-viewboxas");
3060 // TODO: if REST contains ':', two params (then the target is specified, else it is just all SVGs root elements)
3061 addSpaceSeparatedAttr(toAdd, "data-as", REST);
3062 addSpaceSeparatedAttr(toAdd, "data-what", "svg");
3064 } else if (startsWith(what, "%attr:")) {
3065 var main = RESTRIM.split(/ *: */);
3066 addClass(toAdd, "anim-attribute");
3067 addSpaceSeparatedAttr(toAdd, "data-what", main[0]);
3068 addSpaceSeparatedAttr(toAdd, "data-attr", main.slice(1).join(":"));
3070 } else if (startsWith(what, "%along:")) {
3071 var main = RESTRIM.split(/ *: */);
3072 addClass(toAdd, "anim-along");
3073 if (startsWith(main[0], "-")) {
3075 addSpaceSeparatedAttr(toAdd, "data-reverse", "true");
3077 addSpaceSeparatedAttr(toAdd, "data-path", main[0]);
3078 addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
3080 } else if (startsWith(what, "%%class:")) {
3081 var main = RESTRIM.split(/ *: */);
3082 addClass(toAdd, "anim-addclass");
3083 addSpaceSeparatedAttr(toAdd, "data-class", main[0]);
3084 addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
3085 } else if (startsWith(what, "%-class:")) {
3086 var main = RESTRIM.split(/ *: */);
3087 addClass(toAdd, "anim-removeclass");
3088 addSpaceSeparatedAttr(toAdd, "data-class", main[0]);
3089 addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
3090 } else if (startsWith(what, "+")) {
3091 addClass(toAdd, "anim-show");
3093 } else if (startsWith(what, "-")) {
3094 addClass(toAdd, "anim-hide");
3097 addClass(toAdd, "anim-show");
3098 addSpaceSeparatedAttr(toAdd, "data-what", what);
3101 if (continuating) addClass(toAdd, "anim-continue");
3102 allToAdd.push(toAdd);
3105 tree.splice.apply(tree, [index, 1].concat(allToAdd)); // just replacing the text with allToAdd elements
3109 // TODO? handle the decorations for comments
3112 function processMath(content) {
3113 return content.replace(/\$([^$][^$]*)\$/g, '<span class="latex">\\displaystyle $1</span>').replace(/\$\$/, '$');
3116 var interpretationOfSmartLanguage = function(smark, doc) {
3117 var jstree = markdown.toHTMLTree(smark);
3119 // split at each h2 or h1
3120 (function makeTopLevelDivs(jsTree) {
3121 var firstIndex = findTag(jsTree, /^(h1|h2)$/);
3122 if (firstIndex == -1) return;
3123 var secondIndex = findTag(jsTree, /^(h1|h2)$/, firstIndex+1);
3124 if (secondIndex == -1) secondIndex = jsTree.length;
3125 var slide = ["section"].concat( // we will add the 'slide' class later below
3126 jsTree.splice(firstIndex, secondIndex - firstIndex));
3127 jsTree.splice(firstIndex, 0, slide);
3128 makeTopLevelDivs(jsTree);
3132 // - the class and id decorations like {#first hightlight slide}
3133 // - the @... custom notations
3134 // - the // for comments
3136 if (s == 0 || (s==1 && isObject(jstree[1]))) continue;
3137 var slide = jstree[s];
3138 ensureHasAttributes(slide);
3139 if (maybeProcessCopySlide(jstree, s)) {
3141 // actually we want to apply anims to it
3143 // 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)
3144 (function patch(tree){ // tree is slide or a subelement
3146 while (i < tree.length) {
3147 if (isArray(tree[i])) {
3148 if (tree[i][0] === "li") {
3150 if (isArray(li[1]) && li[1][0] === "p") {
3151 li.splice.apply(li, [1, 1].concat(li[1].slice(1)));
3160 // process @anim... and {} decoration
3161 (function patch(tree){ // tree is slide or a subelement
3163 while (i < tree.length) {
3164 if (isArray(tree[i])) patch(tree[i]);
3165 else if (typeof(tree[i]) == 'string') {
3166 if (maybeProcessComment(tree, i)) continue;
3167 else if (maybeProcessAtSomething(tree, i)) continue;
3168 else if (hasIDOrClassDecoration(tree[i])) {
3169 if (processIDOrClassDecoration(tree, i)) {
3170 i++; // avoid processing the same element twice
3177 // cleanup: hide empty "li" after @anim processing
3178 (function patch(tree){ // tree is slide or a subelement
3180 while (i < tree.length) {
3181 if (isArray(tree[i])) {
3182 if (tree[i][0] === "li" && possiblyHideIfEmpty(tree[i])) continue;
3183 else patch(tree[i]);
3188 // process the $math$
3189 (function patch(tree){ // tree is slide or a subelement
3190 if (hasClass(tree, "smark-nomath")) return;
3192 while (i < tree.length) {
3193 if (isArray(tree[i])) patch(tree[i]);
3194 else if (typeof(tree[i]) == 'string') {
3195 tree[i] = processMath(tree[i]);
3200 // change things to textarea (to help with codemirror) https://github.com/iros/deck.js-codemirror/issues/19
3201 (function patch(tree){ // tree is slide or a subelement
3202 if (hasClass(tree, "smark-textarea")) {
3203 tree[3][0] = "textarea";
3206 while (i < tree.length) {
3207 if (isArray(tree[i])) patch(tree[i]);
3211 // now propagate to the slide
3212 var hAttributes = lazyGetAttributes(slide[2]);
3213 if (slide[1]['class']) {
3214 var cl = slide[1]['class'];
3215 slide[1] = clone(hAttributes);
3216 addClass(slide, cl);
3218 slide[1] = clone(hAttributes);
3220 lazyUnsetAttributes(slide[2]);
3221 addClass(slide, 'slide');
3224 return markdown.renderJsonML(jstree);
3227 // this have to be executed before the deck init
3228 $d.bind('deck.beforeInit', function() {
3229 $('.smark').each(function() { // TODO make it configurable
3231 var slides = interpretationOfSmartLanguage(it.innerHTML, document);
3232 $(it).after(slides);
3233 // remove the smart node (to avoid having an empty non-slide sibling (e.g., in the presenter view))
3236 var opts = $[deck]('getOptions');
3237 var maybe = function(f) { return f || (function(){}); }
3238 maybe(opts.AFTERSMARKDOWN)();
3239 $[deck]('reInitSlidesArray')
3246 Copyright (c) 2012 RĂ©mi Emonet
3247 Licensed under the MIT license.
3248 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
3252 This extension provides a way of scaling the slides to fit the slide container.
3253 A "design size" is used to do global scaling of all slides in the same way.
3254 The default design size is 800x600.
3256 (function($, deck, window, undefined) {
3257 var $d = $(document),
3259 timer, // Timeout id for debouncing
3263 Internal function to do all the dirty work of scaling the slides.
3265 scaleDeck = function() {
3266 var opts = $[deck]('getOptions');
3267 var addMarginX = opts.fitMarginX * 2;
3268 var addMarginY = opts.fitMarginY * 2;
3269 var fitMode = opts.fitMode;
3270 var sdw = opts.designWidth;
3271 var sdh = opts.designHeight;
3272 var $container = $[deck]('getContainer');
3273 var scaleX = $container.hasClass(opts.classes.globalscale) ? $container.innerWidth() / (sdw+addMarginX) : 1;
3274 var scaleY = $container.hasClass(opts.classes.globalscale) ? $container.innerHeight() / (sdh+addMarginY) : 1;
3275 //var truescaleX = $container.hasClass(opts.classes.globalscale) ? $container.innerWidth() / (sdw) : 1;
3276 //var truescaleY = $container.hasClass(opts.classes.globalscale) ? $container.innerHeight() / (sdh) : 1;
3277 var scale = scaleX < scaleY ? scaleX : scaleY;
3278 var rootSlides = [];
3279 var slideTest = $.map([opts.classes.before, opts.classes.previous, opts.classes.current, opts.classes.next, opts.classes.after],
3280 function(el, i) {return '.' + el;}).join(', ');
3282 $.each($[deck]('getSlides'), function(i, $el) {
3283 if (!$el.parentsUntil(opts.selectors.container).length) {
3284 rootSlides.push($el);
3287 $.each(rootSlides, function(i, $slide) {
3288 $slide.css('width', sdw);
3289 $slide.css('height', sdh);
3290 $.each('Webkit Moz O ms Khtml'.split(' '), function(i, prefix) {
3292 $slide.css(prefix + 'Transform', '');
3294 if (fitMode == "left top" || fitMode == "top left") {
3295 // ok align left/top (ok with the percents)
3296 $slide.css(prefix + 'Transform', 'translate(-50%,-50%) scale(' + scale + ' , ' + scale + ') translate(50%,50%) translate('+(addMarginX/2)+'px,'+(addMarginY/2)+'px)');
3297 } else if (fitMode == "center middle") {
3298 // ok align center/middle
3299 $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)');
3300 } else if (fitMode == "right bottom" || fitMode == "bottom right") {
3301 // ok align right/bottom
3302 $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)');
3303 } else if (fitMode == "stretched") {
3304 // ok stretched (with respect of the margin, i.e., it is center/middle)
3305 $slide.css(prefix + 'Transform', 'scale(' + scaleX + ' , ' + scaleY + ') translate('+(($container.innerWidth()-sdw)/2/scaleX)+'px,'+(($container.innerHeight()-sdh)/2/scaleY)+'px)');
3314 Extends defaults/options.
3317 Defaults to 800. You may instead specify a width as a number
3318 of px and all slides will be scaled in the same way, considering their
3319 size is the provided one.
3321 options.designHeight
3322 Defaults to 600. You may instead specify a height as a number
3323 of px and all slides will be scaled in the same way, considering their
3324 size is the provided one.
3327 How to adapt the slide to the container.
3328 Only the following combinations are available for now:
3329 "center middle", "top left", "bottom right", "stretched"
3333 Defaults to 5. Adds some margin in design space units.
3334 E.g., if the designe width is 800 and the margin is 5, the slide will be
3335 810 pixel wide before rescaling.
3337 options.scaleDebounce
3338 Scaling on the browser resize event is debounced. This number is the
3339 threshold in milliseconds. You can learn more about debouncing here:
3340 http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
3343 $.extend(true, $[deck].defaults, {
3345 globalscale: 'deck-globalscale'
3353 fitMode: "center middle",
3360 jQuery.deck('disableScale')
3362 Disables scaling and removes the scale class from the deck container.
3364 $[deck]('extend', 'disableScale', function() {
3365 $[deck]('getContainer').removeClass($[deck]('getOptions').classes.globalscale);
3370 jQuery.deck('enableScale')
3372 Enables scaling and adds the scale class to the deck container.
3374 $[deck]('extend', 'enableScale', function() {
3375 $[deck]('getContainer').addClass($[deck]('getOptions').classes.globalscale);
3380 jQuery.deck('toggleScale')
3382 Toggles between enabling and disabling scaling.
3384 $[deck]('extend', 'toggleScale', function() {
3385 var $c = $[deck]('getContainer');
3386 $[deck]($c.hasClass($[deck]('getOptions').classes.globalscale) ?
3387 'disableScale' : 'enableScale');
3390 $d.bind('deck.init', function() {
3391 var opts = $[deck]('getOptions');
3393 // Debounce the resize scaling
3394 $w.unbind('resize.deckscale').bind('resize.deckscale', function() {
3395 window.clearTimeout(timer);
3396 timer = window.setTimeout(scaleDeck, opts.scaleDebounce);
3398 // Scale once on load, in case images or something change layout
3399 .unbind('load.deckscale').bind('load.deckscale', scaleDeck);
3402 $d.unbind('keydown.deckscale').bind('keydown.deckscale', function(e) {
3403 if (e.which === opts.keys.scale || $.inArray(e.which, opts.keys.scale) > -1) {
3404 $[deck]('toggleScale');
3409 // Enable scale on init
3410 $[deck]('enableScale');
3412 })(jQuery, 'deck', this);
3415 // This script was automatically generated from a literate source.
3416 // Do not edit this file; look at the literate source instead!
3418 // Greasemonkey user script to
3419 // Display LaTeX in Web pages by transforming to MathML
3420 // --------------------------------------------------------------------
3422 // Original script by
3423 // Copyright (C) 2006 Steve Cheng <stevecheng@users.sourceforge.net>
3424 // Home page: http://gold-saucer.afraid.org/mathml/greasemonkey/
3427 // Copyright (C) 2010 Valery Alexeev <va.email.tex@gmail.com>
3428 // Version 1.15, May 7, 2010
3431 // Added arxiv.org, front.math.ucdavis.edu, *mathscinet*, mail.google.com
3432 // Changed char_map to fix the display for \mathcal, \mathbb, \mathfrak
3433 // Fixed the displayed formulas with $$...$$ and \[...\]
3434 // Added \scr, \germ, \roman, etc used by Mathscinet.
3435 // Added miscellaneous symbols and arrows
3437 // Permission is hereby granted, free of charge, to any person obtaining
3438 // a copy of this software and associated documentation files (the
3439 // "Software"), to deal in the Software without restriction, including
3440 // without limitation the rights to use, copy, modify, merge, publish,
3441 // distribute, sublicense, and/or sell copies of the Software, and to
3442 // permit persons to whom the Software is furnished to do so, subject to
3443 // the following conditions:
3445 // The above copyright notice and this permission notice shall be included
3446 // in all copies or substantial portions of the Software.
3448 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3449 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3450 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
3451 // IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
3452 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
3453 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
3454 // OTHER DEALNGS IN THE SOFTWARE.
3457 function latex2mml() {
3460 function GM_log() {}
3463 // First, find out where we are
3464 var va_loc = window.location.href;
3465 var va_view = 'web';
3467 //alert( 'va_view=' + va_view );
3469 // The script itself begins
3471 var/*const*/ mmlns = 'http://www.w3.org/1998/Math/MathML';
3474 // VA: Fix displayed equations first.
3475 if( va_view == 'web' ){
3476 document.body.innerHTML=
3477 document.body.innerHTML.replace(/\n/g," "); // remove end-of-lines
3478 document.body.innerHTML=
3479 document.body.innerHTML.replace(/(\$\$|\\\[)([^$]+)(\$\$|\\\])/g,
3480 "<p style=\"text-indent: 20px;\"> \$ $2 \$ </p>");
3481 // VA: Experimental: may lead to slow down. \spcheck is used on MathSciNet
3482 // document.body.innerHTML=
3483 // document.body.innerHTML.replace(/\\spcheck/g,"^{\\vee}");
3488 function result_element(tag, num_attrs)
3490 var node = document.createElementNS(mmlns, tag);
3493 while(--num_attrs >= 0) {
3494 if(arguments[k+1] != null) {
3495 node.setAttribute(arguments[k], arguments[k+1]);
3500 for(; k < arguments.length; k++) {
3501 if(arguments[k] != null) {
3502 if(typeof(arguments[k]) == 'string')
3503 node.appendChild(document.createTextNode(arguments[k]));
3505 node.appendChild(arguments[k]);
3513 function result_element_append(parent, child)
3515 if(parent != null && child != null) {
3516 if(typeof(child) == 'string')
3517 parent.appendChild(document.createTextNode(child));
3519 parent.appendChild(child);
3524 function result_element_prepend(parent, child, next)
3527 result_element_append(parent, child);
3528 else if (parent != null && child != null)
3529 parent.insertBefore(child, next);
3533 function result_set_attr(elem, attr, value)
3535 if(elem != null && attr != null) {
3537 elem.setAttribute(attr, value);
3539 elem.removeAttribute(attr);
3544 function result_append_attr(elem, attr, value)
3546 if(elem != null && attr != null) {
3547 var old_value = elem.getAttribute(elem, attr);
3548 if(old_value == null)
3549 elem.setAttribute(attr, value);
3551 elem.setAttribute(attr, old_value + value);
3556 if( va_view == 'web' ){
3557 if(!this.GM_getValue) {
3558 this.GM_getValue = function(key, value) { return value; }
3559 this.GM_log = function() {}
3563 if(this.GM_registerMenuCommand) {
3564 GM_registerMenuCommand("Enable native display of math images",
3566 GM_setValue("patch-images", true);
3567 do_patch_images = true;
3568 patch_element(document.documentElement);
3570 GM_registerMenuCommand("Disable native display of math images",
3572 GM_setValue("patch-images", false);
3578 // VA: changed char_map
3579 var/*const*/ char_map = {
3581 '\uD835\uDC9C', '\u212C', '\uD835\uDC9E', //abc
3582 '\uD835\uDC9F', '\u2130', '\u2131', //def
3583 '\uD835\uDCA2', '\u210B', '\u2110', //ghi
3584 '\uD835\uDCA5', '\uD835\uDCA6', '\u2112', //jkl
3585 '\u2133', '\uD835\uDCA9', '\uD835\uDCAA', //mno
3586 '\uD835\uDCAB', '\uD835\uDCAC', '\u211B', //pqr
3587 '\uD835\uDCAE', '\uD835\uDCAF', '\uD835\uDCB0', //stu
3588 '\uD835\uDCB1', '\uD835\uDCB2', '\uD835\uDCB3', //vwx
3589 '\uD835\uDCB4', '\uD835\uDCB5' ], //yz
3592 '\uD835\uDD04', '\uD835\uDD05', '\u212D', //abc
3593 '\uD835\uDD07', '\uD835\uDD08', '\uD835\uDD09', //def
3594 '\uD835\uDD0A', '\u210C', '\u2111', //ghi
3595 '\uD835\uDD0D', '\uD835\uDD0E', '\uD835\uDD0F', //jkl
3596 '\uD835\uDD10', '\uD835\uDD11', '\uD835\uDD12', //mno
3597 '\uD835\uDD13', '\uD835\uDD14', '\u211C', //pqr
3598 '\uD835\uDD16', '\uD835\uDD17', '\uD835\uDD18', //stu
3599 '\uD835\uDD19', '\uD835\uDD1A', '\uD835\uDD1B', //vwx
3600 '\uD835\uDD1C', '\u2128' ], //yz
3603 '\uD835\uDD38', '\uD835\uDD39', '\u2102', //abc
3604 '\uD835\uDD3B', '\uD835\uDD3C', '\uD835\uDD3D', //def
3605 '\uD835\uDD3E', '\u210D', '\uD835\uDD40', //ghi
3606 '\uD835\uDD41', '\uD835\uDD42', '\uD835\uDD43', //jkl
3607 '\uD835\uDD44', '\u2115', '\uD835\uDD46', //mno
3608 '\u2119', '\u211A', '\u211D', //pqr
3609 '\uD835\uDD4A', '\uD835\uDD4B', '\uD835\uDD4C', //stu
3610 '\uD835\uDD4D', '\uD835\uDD4E', '\uD835\uDD4F', //vwx
3611 '\uD835\uDD50', '\u2124', ], //yz
3614 var/*const*/ uppercase_re = /[A-Z]/;
3616 function fix_mathvariant(node, style)
3618 if(node.nodeType == node.TEXT_NODE) {
3619 if(style != null && style != '' && style in char_map) {
3620 node.data = node.data.replace(uppercase_re,
3621 function(s) {return char_map[style][s.charCodeAt(0)-65]});
3623 } else if(node.nodeType == node.ELEMENT_NODE) {
3624 var new_style = node.getAttribute('mathvariant');
3625 if(new_style != null && new_style != '')
3628 for(var i=0; i < node.childNodes.length; i++)
3629 fix_mathvariant(node.childNodes.item(i), style);
3633 var g_punct_and_space
3634 = {"\\quad" : "\u2003" ,
3635 "\\qquad" : "\u2003\u2003" ,
3636 "\\thickspace" : "\u2002" ,
3638 "\\medspace" : "\u2005" ,
3640 "\\thinspace" : "\u2004" ,
3646 "\\qedsymbol" : "\u25a0" ,
3649 var g_left_delimiters
3656 "\\lVert" : "\u2016" ,
3657 "\\lceil" : "\u2308" ,
3658 "\\lfloor" : "\u230a" ,
3659 "\\lmoustache" : "\u23b0" ,
3660 "\\langle" : "\u2329" ,
3663 var g_right_delimiters
3670 "\\rVert" : "\u2016" ,
3671 "\\rceil" : "\u2309" ,
3672 "\\rfloor" : "\u230b" ,
3673 "\\rmoustache" : "\u23b1" ,
3674 "\\rangle" : "\u232a" ,
3677 var g_operator_symbols
3678 = {"\\amalg" : "\u2a3f" ,
3680 "\\ast" : "\u2217" ,
3681 "\\barwedge" : "\u22bc" ,
3682 "\\barwedge" : "\u2305" ,
3683 "\\bigcirc" : "\u25cb" ,
3684 "\\bigtriangledown" : "\u25bd" ,
3685 "\\bigtriangleup" : "\u25b3" ,
3686 "\\boxdot" : "\u22a1" ,
3687 "\\boxminus" : "\u229f" ,
3688 "\\boxplus" : "\u229e" ,
3689 "\\boxtimes" : "\u22a0" ,
3690 "\\bullet" : "\u2022" ,
3691 "\\bullet" : "\u2219" ,
3692 "\\cap" : "\u2229" ,
3693 "\\Cap" : "\u22d2" ,
3694 "\\cdot" : "\u22c5" ,
3695 "\\centerdot" : "\u00b7" ,
3696 "\\circ" : "\u2218" ,
3697 "\\circledast" : "\u229b" ,
3698 "\\circledcirc" : "\u229a" ,
3699 "\\circleddash" : "\u229d" ,
3700 "\\cup" : "\u222a" ,
3701 "\\Cup" : "\u22d3" ,
3702 "\\curlyvee" : "\u22ce" ,
3703 "\\curlywedge" : "\u22cf" ,
3704 "\\dagger" : "\u2020" ,
3705 "\\ddagger" : "\u2021" ,
3706 "\\diamond" : "\u22c4" ,
3707 "\\div" : "\u00f7" ,
3708 "\\divideontimes" : "\u22c7" ,
3709 "\\dotplus" : "\u2214" ,
3710 "\\doublebarwedge" : "\u2306" ,
3711 "\\doublecap" : "\u22d2" ,
3712 "\\doublecup" : "\u22d3" ,
3713 "\\gtrdot" : "\u22d7" ,
3714 "\\intercal" : "\u22ba" ,
3715 "\\land" : "\u2227" ,
3716 "\\leftthreetimes" : "\u22cb" ,
3717 "\\lessdot" : "\u22d6" ,
3718 "\\lor" : "\u2228" ,
3719 "\\ltimes" : "\u22c9" ,
3721 "\\odot" : "\u2299" ,
3722 "\\ominus" : "\u2296" ,
3723 "\\oplus" : "\u2295" ,
3724 "\\oslash" : "\u2298" ,
3725 "\\otimes" : "\u2297" ,
3727 "\\rightthreetimes" : "\u22cc" ,
3728 "\\rtimes" : "\u22ca" ,
3729 "\\setminus" : "\u2216" ,
3730 "\\smallsetminus" : "\u2216" ,
3731 "\\sqcap" : "\u2293" ,
3732 "\\sqcup" : "\u2294" ,
3733 "\\star" : "\u22c6" ,
3734 "\\times" : "\u00d7" ,
3735 "\\triangleleft" : "\u25c1" ,
3736 "\\triangleright" : "\u25b7" ,
3737 "\\uplus" : "\u228e" ,
3738 "\\vee" : "\u2228" ,
3739 "\\spcheck" : "\u207a" , // has to be ^{\vee} instead but that's hard
3741 //"\\spcheck" : "\u002a" ,
3742 "\\veebar" : "\u22bb" ,
3743 "\\veebar" : "\u2a61" ,
3744 "\\wedge" : "\u2227" ,
3755 "\\Vert" : "\u2016" ,
3757 "\\backslash" : "\\" ,
3762 "\\downarrow" : "\u2193" ,
3763 "\\Downarrow" : "\u21d3" ,
3764 "\\uparrow" : "\u2191" ,
3765 "\\Uparrow" : "\u21d1" ,
3766 "\\updownarrow" : "\u2195" ,
3767 "\\Updownarrow" : "\u21d5" ,
3768 "\\bigcap" : "\u22c2" ,
3769 "\\bigcup" : "\u22c3" ,
3770 "\\bigodot" : "\u2a00" ,
3771 "\\bigoplus" : "\u2a01" ,
3772 "\\bigotimes" : "\u2a02" ,
3773 "\\bigsqcup" : "\u2a06" ,
3774 "\\biguplus" : "\u2a04" ,
3775 "\\bigvee" : "\u22c1" ,
3776 "\\bigwedge" : "\u22c0" ,
3777 "\\coprod" : "\u2210" ,
3778 "\\prod" : "\u220f" ,
3779 "\\sum" : "\u2211" ,
3780 "\\int" : "\u222b" ,
3781 "\\smallint" : "\u222b" ,
3782 "\\oint" : "\u222e" ,
3783 "\\angle" : "\u2220" ,
3784 "\\backprime" : "\u2035" ,
3785 "\\bigstar" : "\u2605" ,
3786 "\\blacklozenge" : "\u29eb" ,
3787 "\\blacksquare" : "\u25a0" ,
3788 "\\blacktriangle" : "\u25b4" ,
3789 "\\blacktriangledown" : "\u25be" ,
3790 "\\bot" : "\u22a5" ,
3791 "\\clubsuit" : "\u2663" ,
3792 "\\diagdown" : "\u2572" ,
3793 "\\diagup" : "\u2571" ,
3794 "\\diamondsuit" : "\u2662" ,
3795 "\\emptyset" : "\u2205" ,
3796 "\\exists" : "\u2203" ,
3797 "\\flat" : "\u266d" ,
3798 "\\forall" : "\u2200" ,
3799 "\\heartsuit" : "\u2661" ,
3800 "\\infty" : "\u221e" ,
3801 "\\lnot" : "\u00ac" ,
3802 "\\lozenge" : "\u25ca" ,
3803 "\\measuredangle" : "\u2221" ,
3804 "\\nabla" : "\u2207" ,
3805 "\\natural" : "\u266e" ,
3806 "\\neg" : "\u00ac" ,
3807 "\\nexists" : "\u2204" ,
3808 "\\prime" : "\u2032" ,
3809 "\\sharp" : "\u266f" ,
3810 "\\spadesuit" : "\u2660" ,
3811 "\\sphericalangle" : "\u2222" ,
3812 "\\square" : "\u25a1" ,
3813 "\\surd" : "\u221a" ,
3814 "\\top" : "\u22a4" ,
3815 "\\triangle" : "\u25b5" ,
3816 "\\triangledown" : "\u25bf" ,
3817 "\\varnothing" : "\u2205" ,
3818 "\\aleph" : "\u2135" ,
3819 "\\Bbbk" : "\u1d55C" ,
3820 "\\beth" : "\u2136" ,
3821 "\\circledS" : "\u24c8" ,
3822 "\\complement" : "\u2201" ,
3823 "\\daleth" : "\u2138" ,
3824 "\\ell" : "\u2113" ,
3825 "\\eth" : "\u00f0" ,
3826 "\\Finv" : "\u2132" ,
3827 "\\Game" : "\u2141" ,
3828 "\\gimel" : "\u2137" ,
3829 "\\hbar" : "\u210f" ,
3830 "\\hslash" : "\u210f" ,
3832 "\\mho" : "\u2127" ,
3833 "\\partial" : "\u2202" ,
3838 var g_relation_symbols
3842 "\\approx" : "\u2248" ,
3843 "\\approxeq" : "\u224a" ,
3844 "\\asymp" : "\u2248" ,
3845 "\\backsim" : "\u223d" ,
3846 "\\backsimeq" : "\u22cd" ,
3847 "\\bumpeq" : "\u224f" ,
3848 "\\Bumpeq" : "\u224e" ,
3849 "\\circeq" : "\u2257" ,
3850 "\\cong" : "\u2245" ,
3851 "\\curlyeqprec" : "\u22de" ,
3852 "\\curlyeqsucc" : "\u22df" ,
3853 "\\doteq" : "\u2250" ,
3854 "\\doteqdot" : "\u2251" ,
3855 "\\eqcirc" : "\u2256" ,
3856 "\\eqsim" : "\u2242" ,
3857 "\\eqslantgtr" : "\u2a96" ,
3858 "\\eqslantless" : "\u2a95" ,
3859 "\\equiv" : "\u2261" ,
3860 "\\fallingdotseq" : "\u2252" ,
3862 "\\geq" : "\u2265" ,
3863 "\\geqq" : "\u2267" ,
3864 "\\geqslant" : "\u2a7e" ,
3867 "\\ggg" : "\u22d9" ,
3868 "\\gggtr" : "\u22d9" ,
3869 "\\gnapprox" : "\u2a8a" ,
3870 "\\gneq" : "\u2a88" ,
3871 "\\gneqq" : "\u2269" ,
3872 "\\gnsim" : "\u22e7" ,
3873 "\\gtrapprox" : "\u2a86" ,
3874 "\\gtreqless" : "\u22db" ,
3875 "\\gtreqqless" : "\u2a8c" ,
3876 "\\gtrless" : "\u2277" ,
3877 "\\gtrsim" : "\u2273" ,
3878 "\\gvertneqq" : "\u2269" ,
3880 "\\leq" : "\u2264" ,
3881 "\\leqq" : "\u2266" ,
3882 "\\leqslant" : "\u2a7d" ,
3883 "\\lessapprox" : "\u2a85" ,
3884 "\\lesseqgtr" : "\u22da" ,
3885 "\\lesseqqgtr" : "\u2a8b" ,
3886 "\\lessgtr" : "\u2276" ,
3887 "\\lesssim" : "\u2272" ,
3889 "\\llless" : "\u22d8" ,
3890 "\\lnapprox" : "\u2a89" ,
3891 "\\lneq" : "\u2a87" ,
3892 "\\lneqq" : "\u2268" ,
3893 "\\lnsim" : "\u22e6" ,
3894 "\\lvertneqq" : "\u2268" ,
3895 "\\ncong" : "\u2247" ,
3897 "\\neq" : "\u2260" ,
3898 "\\ngeq" : "\u2271" ,
3899 "\\ngeqq" : "\u2267" ,
3900 "\\ngeqslant" : "\u2a7e" ,
3901 "\\ngtr" : "\u226f" ,
3902 "\\nleq" : "\u2270" ,
3903 "\\nleqq" : "\u2266" ,
3904 "\\nleqslant" : "\u2a7d" ,
3905 "\\nless" : "\u226e" ,
3906 "\\nprec" : "\u2280" ,
3907 "\\npreceq" : "\u2aaf" ,
3908 "\\nsim" : "\u2241" ,
3909 "\\nsucc" : "\u2281" ,
3910 "\\nsucceq" : "\u2ab0" ,
3911 "\\prec" : "\u227a" ,
3912 "\\precapprox" : "\u2ab7" ,
3913 "\\preccurlyeq" : "\u227c" ,
3914 "\\preceq" : "\u2aaf" ,
3915 "\\precnapprox" : "\u2ab9" ,
3916 "\\precneqq" : "\u2ab5" ,
3917 "\\precnsim" : "\u22e8" ,
3918 "\\precsim" : "\u227e" ,
3919 "\\risingdotseq" : "\u2253" ,
3920 "\\sim" : "\u223c" ,
3921 "\\simeq" : "\u2243" ,
3922 "\\succ" : "\u227b" ,
3923 "\\succapprox" : "\u2ab8" ,
3924 "\\succcurlyeq" : "\u227d" ,
3925 "\\succeq" : "\u2ab0" ,
3926 "\\succnapprox" : "\u2aba" ,
3927 "\\succneqq" : "\u2ab6" ,
3928 "\\succnsim" : "\u22e9" ,
3929 "\\succsim" : "\u227f" ,
3930 "\\thickapprox" : "\u2248" ,
3931 "\\thicksim" : "\u223c" ,
3932 "\\triangleq" : "\u225c" ,
3933 "\\longrightarrow" : "\u27F6" ,
3934 "\\curvearrowleft" : "\u21b6" ,
3935 "\\curvearrowright" : "\u21b7" ,
3936 "\\downdownarrows" : "\u21ca" ,
3937 "\\downharpoonleft" : "\u21c3" ,
3938 "\\downharpoonright" : "\u21c2" ,
3939 "\\gets" : "\u2190" ,
3940 "\\hookleftarrow" : "\u21a9" ,
3941 "\\hookrightarrow" : "\u21aa" ,
3942 "\\leftarrow" : "\u2190" ,
3943 "\\Leftarrow" : "\u21d0" ,
3944 "\\leftarrowtail" : "\u21a2" ,
3945 "\\leftharpoondown" : "\u21bd" ,
3946 "\\leftharpoonup" : "\u21bc" ,
3947 "\\leftleftarrows" : "\u21c7" ,
3948 "\\leftrightarrow" : "\u2194" ,
3949 "\\leftrightarrows" : "\u21c6" ,
3950 "\\leftrightharpoons" : "\u21cb" ,
3951 "\\leftrightsquigarrow" : "\u21ad" ,
3952 "\\Lleftarrow" : "\u21da" ,
3953 "\\longleftarrow" : "\u27f5" ,
3954 "\\Longleftarrow" : "\u27f8" ,
3955 "\\longleftrightarrow" : "\u27f7" ,
3956 "\\Longleftrightarrow" : "\u27fa" ,
3957 "\\looparrowleft" : "\u21ab" ,
3958 "\\looparrowright" : "\u21ac" ,
3959 "\\Lsh" : "\u21b0" ,
3960 "\\mapsto" : "\u21a6" ,
3961 "\\multimap" : "\u22b8" ,
3962 "\\nearrow" : "\u2197" ,
3963 "\\nleftarrow" : "\u219a" ,
3964 "\\nLeftarrow" : "\u21cd" ,
3965 "\\nleftrightarrow" : "\u21ae" ,
3966 "\\nLeftrightarrow" : "\u21ce" ,
3967 "\\nrightarrow" : "\u219b" ,
3968 "\\nRightarrow" : "\u21cf" ,
3969 "\\nwarrow" : "\u2196" ,
3970 "\\restriction" : "\u21be" ,
3971 "\\rightarrow" : "\u2192" ,
3972 "\\Rightarrow" : "\u21d2" ,
3973 "\\rightarrowtail" : "\u21a3" ,
3974 "\\rightharpoondown" : "\u21c1" ,
3975 "\\rightharpoonup" : "\u21c0" ,
3976 "\\rightleftarrows" : "\u21c4" ,
3977 "\\rightleftharpoons" : "\u21cc" ,
3978 "\\rightrightarrows" : "\u21c9" ,
3979 "\\rightsquigarrow" : "\u219d" ,
3980 "\\Rrightarrow" : "\u21db" ,
3981 "\\Rsh" : "\u21b1" ,
3982 "\\searrow" : "\u2198" ,
3983 "\\swarrow" : "\u2199" ,
3985 "\\twoheadleftarrow" : "\u219e" ,
3986 "\\twoheadrightarrow" : "\u21a0" ,
3987 "\\upharpoonleft" : "\u21bf" ,
3988 "\\upharpoonright" : "\u21be" ,
3989 "\\upuparrows" : "\u21c8" ,
3990 "\\backepsilon" : "\u03f6" ,
3991 "\\because" : "\u2235" ,
3992 "\\between" : "\u226c" ,
3993 "\\blacktriangleleft" : "\u25c0" ,
3994 "\\blacktriangleright" : "\u25b6" ,
3995 "\\bowtie" : "\u22c8" ,
3996 "\\dashv" : "\u22a3" ,
3997 "\\frown" : "\u2323" ,
3999 "\\mid" : "\u2223" ,
4000 "\\models" : "\u22a7" ,
4003 "\\nmid" : "\u2224" ,
4004 "\\notin" : "\u2209" ,
4005 "\\nparallel" : "\u2226" ,
4006 "\\nshortmid" : "\u2224" ,
4007 "\\nshortparallel" : "\u2226" ,
4008 "\\nsubseteq" : "\u2286" ,
4009 "\\nsubseteq" : "\u2288" ,
4010 "\\nsubseteqq" : "\u2ac5" ,
4011 "\\nsupseteq" : "\u2287" ,
4012 "\\nsupseteq" : "\u2289" ,
4013 "\\nsupseteqq" : "\u2ac6" ,
4014 "\\ntriangleleft" : "\u22ea" ,
4015 "\\ntrianglelefteq" : "\u22ec" ,
4016 "\\ntriangleright" : "\u22eb" ,
4017 "\\ntrianglerighteq" : "\u22ed" ,
4018 "\\nvdash" : "\u22ac" ,
4019 "\\nvDash" : "\u22ad" ,
4020 "\\nVdash" : "\u22ae" ,
4021 "\\nVDash" : "\u22af" ,
4022 "\\owns" : "\u220d" ,
4023 "\\parallel" : "\u2225" ,
4024 "\\perp" : "\u22a5" ,
4025 "\\pitchfork" : "\u22d4" ,
4026 "\\propto" : "\u221d" ,
4027 "\\shortmid" : "\u2223" ,
4028 "\\shortparallel" : "\u2225" ,
4029 "\\smallfrown" : "\u2322" ,
4030 "\\smallsmile" : "\u2323" ,
4031 "\\smile" : "\u2323" ,
4032 "\\sqsubset" : "\u228f" ,
4033 "\\sqsubseteq" : "\u2291" ,
4034 "\\sqsupset" : "\u2290" ,
4035 "\\sqsupseteq" : "\u2292" ,
4036 "\\subset" : "\u2282" ,
4037 "\\Subset" : "\u22d0" ,
4038 "\\subseteq" : "\u2286" ,
4039 "\\subseteqq" : "\u2ac5" ,
4040 "\\subsetneq" : "\u228a" ,
4041 "\\subsetneqq" : "\u2acb" ,
4042 "\\supset" : "\u2283" ,
4043 "\\Supset" : "\u22d1" ,
4044 "\\supseteq" : "\u2287" ,
4045 "\\supseteqq" : "\u2ac6" ,
4046 "\\supsetneq" : "\u228b" ,
4047 "\\supsetneqq" : "\u2acc" ,
4048 "\\therefore" : "\u2234" ,
4049 "\\trianglelefteq" : "\u22b4" ,
4050 "\\trianglerighteq" : "\u22b5" ,
4051 "\\varpropto" : "\u221d" ,
4052 "\\varsubsetneq" : "\u228a" ,
4053 "\\varsubsetneqq" : "\u2acb" ,
4054 "\\varsupsetneq" : "\u228b" ,
4055 "\\varsupsetneqq" : "\u2acc" ,
4056 "\\vartriangle" : "\u25b5" ,
4057 "\\vartriangleleft" : "\u22b2" ,
4058 "\\vartriangleright" : "\u22b3" ,
4059 "\\vdash" : "\u22a2" ,
4060 "\\vDash" : "\u22a8" ,
4061 "\\Vdash" : "\u22a9" ,
4062 "\\Vvdash" : "\u22aa" ,
4064 "\\dashleftarrow" : "\u21e0" ,
4065 "\\dashrightarrow" : "\u21e2" ,
4068 var g_named_identifiers
4069 = {"\\arccos" : "arccos" ,
4070 "\\arcsin" : "arcsin" ,
4071 "\\arctan" : "arctan" ,
4095 "\\injlim" : "inj lim" ,
4097 "\\liminf" : "lim inf" ,
4098 "\\limsup" : "lum sup" ,
4101 "\\projlim" : "proj lim" ,
4103 "\\alpha" : "\u03b1" ,
4104 "\\beta" : "\u03b2" ,
4105 "\\chi" : "\u03c7" ,
4106 "\\delta" : "\u03b4" ,
4107 "\\Delta" : "\u0394" ,
4108 "\\digamma" : "\u03dd" ,
4109 "\\epsilon" : "\u03f5" ,
4110 "\\eta" : "\u03b7" ,
4111 "\\gamma" : "\u03b3" ,
4112 "\\Gamma" : "\u0393" ,
4113 "\\iota" : "\u03b9" ,
4114 "\\kappa" : "\u03ba" ,
4115 "\\lambda" : "\u03bb" ,
4116 "\\Lambda" : "\u039b" ,
4119 "\\omega" : "\u03c9" ,
4120 "\\Omega" : "\u03a9" ,
4121 "\\phi" : "\u03c6" ,
4122 "\\Phi" : "\u03a6" ,
4125 "\\psi" : "\u03c8" ,
4126 "\\Psi" : "\u03a8" ,
4127 "\\rho" : "\u03c1" ,
4128 "\\sigma" : "\u03c3" ,
4129 "\\Sigma" : "\u03a3" ,
4130 "\\tau" : "\u03c4" ,
4131 "\\theta" : "\u03b8" ,
4132 "\\Theta" : "\u0398" ,
4133 "\\upsilon" : "\u03c5" ,
4134 "\\Upsilon" : "\u03d2" ,
4135 "\\varepsilon" : "\u03b5" ,
4136 "\\varkappa" : "\u03f0" ,
4137 "\\varphi" : "\u03d5" ,
4138 "\\varpi" : "\u03d6" ,
4139 "\\varrho" : "\u03f1" ,
4140 "\\varsigma" : "\u03c2" ,
4141 "\\vartheta" : "\u03d1" ,
4144 "\\zeta" : "\u03b6" ,
4197 "\\vdots" : "\u22ee" ,
4198 "\\hdots" : "\u2026" ,
4199 "\\ldots" : "\u2026" ,
4200 "\\dots" : "\u2026" ,
4201 "\\cdots" : "\u00b7\u00b7\u00b7" ,
4202 "\\dotsb" : "\u00b7\u00b7\u00b7" ,
4203 "\\dotsc" : "\u2026" ,
4204 "\\dotsi" : "\u22c5\u22c5\u22c5" ,
4205 "\\dotsm" : "\u22c5\u22c5\u22c5" ,
4206 "\\dotso" : "\u2026" ,
4207 "\\ddots" : "\u22f1" ,
4208 // Common abbreviation for \mathbb letters
4209 "\\A" : "\uD835\uDD38" ,
4210 "\\bA" : "\uD835\uDD38" ,
4211 "\\B" : "\uD835\uDD39" ,
4212 "\\bB" : "\uD835\uDD39" ,
4215 "\\D" : "\uD835\uDD3B" ,
4216 "\\bD" : "\uD835\uDD3B" ,
4217 "\\E" : "\uD835\uDD3C" ,
4218 "\\bE" : "\uD835\uDD3C" ,
4219 "\\F" : "\uD835\uDD3D" ,
4220 "\\bF" : "\uD835\uDD3D" ,
4221 "\\G" : "\uD835\uDD3E" ,
4222 "\\bG" : "\uD835\uDD3E" ,
4225 "\\I" : "\uD835\uDD40" ,
4226 "\\bI" : "\uD835\uDD40" ,
4227 "\\J" : "\uD835\uDD41" ,
4228 "\\bJ" : "\uD835\uDD41" ,
4229 "\\K" : "\uD835\uDD42" ,
4230 "\\bK" : "\uD835\uDD42" ,
4231 "\\L" : "\uD835\uDD43" ,
4232 "\\bL" : "\uD835\uDD43" ,
4233 "\\M" : "\uD835\uDD44" ,
4234 "\\bM" : "\uD835\uDD44" ,
4237 "\\O" : "\uD835\uDD46" ,
4238 "\\bO" : "\uD835\uDD46" ,
4245 "\\S" : "\uD835\uDD4A" ,
4246 "\\bS" : "\uD835\uDD4A" ,
4247 "\\T" : "\uD835\uDD4B" ,
4248 "\\bT" : "\uD835\uDD4B" ,
4249 "\\U" : "\uD835\uDD4C" ,
4250 "\\bU" : "\uD835\uDD4C" ,
4251 "\\V" : "\uD835\uDD4D" ,
4252 "\\bV" : "\uD835\uDD4D" ,
4253 "\\W" : "\uD835\uDD4E" ,
4254 "\\bW" : "\uD835\uDD4E" ,
4255 "\\X" : "\uD835\uDD4F" ,
4256 "\\bX" : "\uD835\uDD4F" ,
4257 "\\Y" : "\uD835\uDD50" ,
4258 "\\bY" : "\uD835\uDD50" ,
4261 // Common abbreviations for \mathcal letters
4262 "\\cA" : "\uD835\uDC9C" ,
4264 "\\cC" : "\uD835\uDC9E" ,
4265 "\\cD" : "\uD835\uDC9F" ,
4268 "\\cG" : "\uD835\uDCA2" ,
4271 "\\cJ" : "\uD835\uDCA5" ,
4272 "\\cK" : "\uD835\uDCA6" ,
4275 "\\cN" : "\uD835\uDCA9" ,
4276 "\\cO" : "\uD835\uDCAA" ,
4277 "\\OO" : "\uD835\uDCAA" ,
4278 "\\cP" : "\uD835\uDCAB" ,
4279 "\\cQ" : "\uD835\uDCAC" ,
4281 "\\cS" : "\uD835\uDCAE" ,
4282 "\\cT" : "\uD835\uDCAF" ,
4283 "\\cU" : "\uD835\uDCB0" ,
4284 "\\cV" : "\uD835\uDCB1" ,
4285 "\\cW" : "\uD835\uDCB2" ,
4286 "\\cX" : "\uD835\uDCB3" ,
4287 "\\cY" : "\uD835\uDCB4" ,
4288 "\\cZ" : "\uD835\uDCB5" ,
4294 "\\eps" : "\u03f5" ,
4297 var g_word_operators
4298 = {"\\arccos" : "arccos" ,
4299 "\\arcsin" : "arcsin" ,
4300 "\\arctan" : "arctan" ,
4325 var g_big_word_operators
4326 = {"\\inf" : "inf" ,
4327 "\\injlim" : "inj lim" ,
4329 "\\liminf" : "lim inf" ,
4330 "\\limsup" : "lum sup" ,
4333 "\\projlim" : "proj lim" ,
4338 = {"\\alpha" : "\u03b1" ,
4339 "\\beta" : "\u03b2" ,
4340 "\\chi" : "\u03c7" ,
4341 "\\delta" : "\u03b4" ,
4342 "\\Delta" : "\u0394" ,
4343 "\\digamma" : "\u03dd" ,
4344 "\\epsilon" : "\u03f5" ,
4345 "\\eta" : "\u03b7" ,
4346 "\\gamma" : "\u03b3" ,
4347 "\\Gamma" : "\u0393" ,
4348 "\\iota" : "\u03b9" ,
4349 "\\kappa" : "\u03ba" ,
4350 "\\lambda" : "\u03bb" ,
4351 "\\Lambda" : "\u039b" ,
4354 "\\omega" : "\u03c9" ,
4355 "\\Omega" : "\u03a9" ,
4356 "\\phi" : "\u03c6" ,
4357 "\\Phi" : "\u03a6" ,
4360 "\\psi" : "\u03c8" ,
4361 "\\Psi" : "\u03a8" ,
4362 "\\rho" : "\u03c1" ,
4363 "\\sigma" : "\u03c3" ,
4364 "\\Sigma" : "\u03a3" ,
4365 "\\tau" : "\u03c4" ,
4366 "\\theta" : "\u03b8" ,
4367 "\\Theta" : "\u0398" ,
4368 "\\upsilon" : "\u03c5" ,
4369 "\\Upsilon" : "\u03d2" ,
4370 "\\varepsilon" : "\u03b5" ,
4371 "\\varkappa" : "\u03f0" ,
4372 "\\varphi" : "\u03d5" ,
4373 "\\varpi" : "\u03d6" ,
4374 "\\varrho" : "\u03f1" ,
4375 "\\varsigma" : "\u03c2" ,
4376 "\\vartheta" : "\u03d1" ,
4379 "\\zeta" : "\u03b6" ,
4382 function v_fraction_to_mathml (tokens ) {
4383 var v_numerator = v_piece_to_mathml (tokens ) ;
4384 var v_denominator = v_piece_to_mathml (tokens ) ;
4385 return result_element( "mfrac" ,0 , v_numerator , v_denominator ) ;
4387 function v_binom_to_mathml (tokens ) {
4388 var v_top = v_piece_to_mathml (tokens ) ;
4389 var v_bottom = v_piece_to_mathml (tokens ) ;
4390 return result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , result_element( "mfrac" , 1
4391 , "linethickness" , "0" , v_top , v_bottom ) , result_element( "mo" ,0 , ")" ) ) ;
4393 function v_sqrt_to_mathml (tokens ) {
4394 var v_index = v_optional_arg_to_mathml (tokens ) ;
4395 var v_object = v_piece_to_mathml (tokens ) ;
4396 if( ( v_index != null ) ) {
4397 return result_element( "mroot" ,0 , v_object , v_index ) ;
4400 return result_element( "msqrt" ,0 , v_object ) ;
4403 function v_parenthesized_operator (tokens , v_word ) {
4404 var v_object = v_piece_to_mathml (tokens ) ;
4405 if( ( v_word != null ) ) {
4406 return result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , result_element( "mo" ,0 , v_word ) , v_object , result_element( "mo" ,0 , ")" ) ) ;
4409 return result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , v_object , result_element( "mo" ,0 , ")" ) ) ;
4412 function v_operatorname_to_mathml (tokens ) {
4413 var v_result = result_element( "mo" ,0 , tokens.list[tokens.index] ) ;
4417 function v_displaystyle_to_mathml (tokens ) {
4418 var v_result = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4420 return result_element( "mstyle" , 2
4421 , "displaystyle" , "true" , "scriptlevel" , "0" , v_result ) ;
4423 function v_displaymath_to_mathml (tokens ) {
4424 var v_result = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4426 v_finish_latex_block (tokens );
4427 return result_element( "mstyle" , 2
4428 , "displaystyle" , "true" , "scriptlevel" , "0" , v_result ) ;
4430 function v_font_to_mathml (tokens , v_font_name ) {
4431 if( ( tokens.list[tokens.index] != "{" ) ) {
4432 var v_result = result_element( "mi" , 1
4433 , "mathvariant" , v_font_name , tokens.list[tokens.index] ) ;
4434 if( ( v_font_name == "normal" ) ) {
4436 v_result , "fontstyle" , "normal" );
4442 var v_result = v_piece_to_mathml (tokens ) ;
4444 v_result , "mathvariant" , v_font_name );
4445 if( ( v_font_name == "normal" ) ) {
4447 v_result , "fontstyle" , "normal" );
4452 function v_old_font_to_mathml (tokens , v_font_name ) {
4453 return result_element( "mstyle" , 2
4454 , "mathvariant" , v_font_name , "fontstyle" , ( ( v_font_name == "normal" ) ? "normal" : null ) , v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4457 function v_size_to_mathml (tokens , v_min_size , v_max_size ) {
4458 var v_result = v_piece_to_mathml (tokens ) ;
4460 v_result , "minsize" , v_min_size );
4462 v_result , "maxsize" , v_max_size );
4465 function v_accent_to_mathml (tokens , v_char ) {
4466 return result_element( "mover" , 1
4467 , "accent" , "true" , v_piece_to_mathml (tokens ) , result_element( "mo" ,0 , v_char ) ) ;
4469 function v_matrix_to_mathml (tokens , v_open_delim , v_close_delim ) {
4470 var v_mtable = v_matrix_to_mtable (tokens , result_element( "mtable" ,0) ) ;
4471 if( ( ( v_open_delim != null ) || ( v_close_delim != null ) ) ) {
4472 var v_mrow = result_element( "mrow" ,0) ;
4473 if( ( v_open_delim != null ) ) {
4474 result_element_append( v_mrow , result_element( "mo" ,0 , v_open_delim ) );
4476 result_element_append( v_mrow , v_mtable );
4477 if( ( v_close_delim != null ) ) {
4478 result_element_append( v_mrow , result_element( "mo" ,0 , v_close_delim ) );
4486 function v_array_to_mathml (tokens ) {
4487 var v_mtable = result_element( "mtable" ,0) ;
4488 if( ( tokens.list[tokens.index] == "{" ) ) {
4490 while( ( ( tokens.list[tokens.index] != null ) && ( tokens.list[tokens.index] != "}" ) ) ) {
4491 if( ( tokens.list[tokens.index] == "c" ) ) {
4493 v_mtable , "columnalign" , "center " );
4495 else if( ( tokens.list[tokens.index] == "l" ) ) {
4497 v_mtable , "columnalign" , "left " );
4499 else if( ( tokens.list[tokens.index] == "r" ) ) {
4501 v_mtable , "columnalign" , "right " );
4505 if( ( tokens.list[tokens.index] != null ) ) {
4509 return v_matrix_to_mtable (tokens , v_mtable ) ;
4511 function v_matrix_to_mtable (tokens , v_mtable ) {
4512 var v_mtr = result_element( "mtr" ,0) ;
4513 var v_mtd = result_element( "mtd" ,0) ;
4514 var v_token = tokens.list[tokens.index] ;
4515 result_element_append( v_mtable , v_mtr );
4516 result_element_append( v_mtr , v_mtd );
4517 while( ( ( v_token != null ) && ( v_token != "\\end" ) ) ) {
4518 if( ( v_token == "\\\\" ) ) {
4519 v_mtr = result_element( "mtr" ,0) ;
4520 v_mtd = result_element( "mtd" ,0) ;
4521 result_element_append( v_mtable , v_mtr );
4522 result_element_append( v_mtr , v_mtd );
4525 else if( ( v_token == "&" ) ) {
4526 v_mtd = result_element( "mtd" ,0) ;
4527 result_element_append( v_mtr , v_mtd );
4531 result_element_append( v_mtd , v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4534 v_token = tokens.list[tokens.index] ;
4536 v_finish_latex_block (tokens );
4539 function v_over_to_mathml (tokens , v_char ) {
4540 return result_element( "mover" ,0 , v_piece_to_mathml (tokens ) , result_element( "mo" ,0 , v_char ) ) ;
4542 function v_under_to_mathml (tokens , v_char ) {
4543 return result_element( "munder" ,0 , v_piece_to_mathml (tokens ) , result_element( "mo" ,0 , v_char ) ) ;
4545 function v_delimiter_to_mathml (tokens , v_end_command , v_min_size , v_max_size ) {
4546 var v_mrow = result_element( "mrow" ,0) ;
4547 result_element_append( v_mrow , result_element( "mo" , 2
4548 , "minsize" , v_min_size , "maxsize" , v_max_size , v_read_delimiter (tokens ) ) );
4549 result_element_append( v_mrow , v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4551 if( ( tokens.list[tokens.index] != v_end_command ) ) {
4555 result_element_append( v_mrow , result_element( "mo" , 2
4556 , "minsize" , v_min_size , "maxsize" , v_max_size , v_read_delimiter (tokens ) ) );
4559 function v_read_delimiter (tokens ) {
4560 var v_token = tokens.list[tokens.index] ;
4561 if( ( v_token == null ) ) {
4562 throw "unexpected eof" ;
4564 else if( ( v_token == "." ) ) {
4568 else if( ( v_token == "<" ) ) {
4572 else if( ( v_token == ">" ) ) {
4576 else if( ( v_token in g_punct_and_space
4579 return g_punct_and_space
4582 else if( ( v_token in g_left_delimiters
4585 return g_left_delimiters
4588 else if( ( v_token in g_right_delimiters
4591 return g_right_delimiters
4594 else if( ( v_token in g_operator_symbols
4597 return g_operator_symbols
4601 throw "invalid delimiter" ;
4604 function v_latex_block_to_mathml (tokens ) {
4605 v_cmd = tokens.list[tokens.index] ;
4606 if( ( v_cmd in g_tex_environments
4609 return g_tex_environments
4610 [ v_cmd ] (tokens ) ;
4613 throw "unknown command" ;
4616 function v_finish_latex_block (tokens ) {
4617 if( ( tokens.list[tokens.index] == null ) ) {
4618 throw "unexpected eof" ;
4623 function v_combining_to_mathml (tokens , v_char ) {
4624 var v_base = tokens.list[tokens.index] ;
4626 return result_element( "mo" ,0 , v_base , v_char ) ;
4628 var g_char_escape_codes
4632 function v_char_escape_to_mathml (tokens ) {
4633 var v_result = null ;
4634 if( ( tokens.list[tokens.index] in g_char_escape_codes
4636 v_result = result_element( "mtext" ,0 , g_char_escape_codes
4637 [ tokens.list[tokens.index] ] ) ;
4640 v_result = result_element( "merror" ,0 , "\\char" , tokens.list[tokens.index] ) ;
4645 function v_text_to_mathml (tokens ) {
4646 if( ( tokens.list[tokens.index] != "{" ) ) {
4647 var v_result = result_element( "mtext" ,0 , tokens.list[tokens.index] ) ;
4652 var v_result = null ;
4655 while( ( tokens.list[tokens.index] != null ) ) {
4656 if( ( tokens.list[tokens.index] == "}" ) ) {
4660 else if( ( tokens.list[tokens.index] == "$" ) ) {
4662 v_node = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4667 v_node = result_element( "mtext" ,0 , tokens.list[tokens.index] ) ;
4670 if( ( v_mrow != null ) ) {
4671 result_element_append( v_mrow , v_node );
4673 else if( ( v_result != null ) ) {
4674 v_mrow = result_element( "mrow" ,0 , v_result , v_node ) ;
4685 "\\frac" : v_fraction_to_mathml ,
4686 "\\dfrac" : v_fraction_to_mathml ,
4687 "\\tfrac" : v_fraction_to_mathml ,
4688 "\\binom" : v_binom_to_mathml ,
4689 "\\sqrt" : v_sqrt_to_mathml ,
4690 "\\operatorname" : v_operatorname_to_mathml ,
4691 "\\displaystyle" : v_displaystyle_to_mathml ,
4692 "\\pod" : function(tokens ) {return v_parenthesized_operator (tokens , null ) ;} ,
4693 "\\pmod" : function(tokens ) {return v_parenthesized_operator (tokens , "mod" ) ;} ,
4694 "\\boldsymbol" : function(tokens ) {return v_font_to_mathml (tokens , "bold" ) ;} ,
4695 "\\bold" : function(tokens ) {return v_font_to_mathml (tokens , "bold" ) ;} ,
4696 "\\Bbb" : function(tokens ) {return v_font_to_mathml (tokens , "double-struck" ) ;} ,
4697 "\\mathbb" : function(tokens ) {return v_font_to_mathml (tokens , "double-struck" ) ;} ,
4698 "\\mathbbmss" : function(tokens ) {return v_font_to_mathml (tokens , "double-struck" ) ;} ,
4699 "\\mathbf" : function(tokens ) {return v_font_to_mathml (tokens , "bold" ) ;} ,
4700 "\\mathop" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4701 "\\mathopen" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4702 "\\mathclose" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4703 "\\mathrm" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4704 "\\mathfrak" : function(tokens ) {return v_font_to_mathml (tokens , "fraktur" ) ;} ,
4705 "\\germ" : function(tokens ) {return v_font_to_mathml (tokens , "fraktur" ) ;} ,
4706 "\\mathit" : function(tokens ) {return v_font_to_mathml (tokens , "italic" ) ;} ,
4707 "\\mathscr" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4708 "\\scr" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4709 "\\mathcal" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4710 "\\mathsf" : function(tokens ) {return v_font_to_mathml (tokens , "sans-serif" ) ;} ,
4711 "\\mathtt" : function(tokens ) {return v_font_to_mathml (tokens , "monospace" ) ;} ,
4712 "\\EuScript" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4713 "\\bf" : function(tokens ) {return v_old_font_to_mathml (tokens , "bold" ) ;} ,
4714 "\\rm" : function(tokens ) {return v_old_font_to_mathml (tokens , "normal" ) ;} ,
4715 "\\roman" : function(tokens ) {return v_old_font_to_mathml (tokens , "normal" ) ;} ,
4716 "\\tag" : function(tokens ) {return v_old_font_to_mathml (tokens , "bold" ) ;} ,
4717 "\\big" : function(tokens ) {return v_size_to_mathml (tokens , "2" , "2" ) ;} ,
4718 "\\Big" : function(tokens ) {return v_size_to_mathml (tokens , "3" , "3" ) ;} ,
4719 "\\bigg" : function(tokens ) {return v_size_to_mathml (tokens , "4" , "4" ) ;} ,
4720 "\\Bigg" : function(tokens ) {return v_size_to_mathml (tokens , "5" , "5" ) ;} ,
4721 "\\acute" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0301" ) ;} ,
4722 "\\grave" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0300" ) ;} ,
4723 "\\tilde" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0303" ) ;} ,
4724 "\\bar" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0304" ) ;} ,
4725 "\\breve" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0306" ) ;} ,
4726 "\\check" : function(tokens ) {return v_accent_to_mathml (tokens , "\u030c" ) ;} ,
4727 "\\hat" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0302" ) ;} ,
4728 "\\vec" : function(tokens ) {return v_accent_to_mathml (tokens , "\u20d7" ) ;} ,
4729 "\\dot" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0307" ) ;} ,
4730 "\\ddot" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0308" ) ;} ,
4731 "\\dddot" : function(tokens ) {return v_accent_to_mathml (tokens , "\u20db" ) ;} ,
4732 "\\underbrace" : function(tokens ) {return v_under_to_mathml (tokens , "\ufe38" ) ;} ,
4733 "\\overbrace" : function(tokens ) {return v_over_to_mathml (tokens , "\ufe37" ) ;} ,
4734 "\\underline" : function(tokens ) {return v_under_to_mathml (tokens , "\u0332" ) ;} ,
4735 "\\overline" : function(tokens ) {return v_over_to_mathml (tokens , "\u00af" ) ;} ,
4736 "\\widetilde" : function(tokens ) {return v_over_to_mathml (tokens , "\u0303" ) ;} ,
4737 "\\widehat" : function(tokens ) {return v_over_to_mathml (tokens , "\u0302" ) ;} ,
4738 "\\not" : function(tokens ) {return v_combining_to_mathml (tokens , "\u0338" ) ;} ,
4739 "\\left" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\right" , "1" , null ) ;} ,
4740 "\\bigl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\bigr" , "2" , "2" ) ;} ,
4741 "\\Bigl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\Bigr" , "3" , "3" ) ;} ,
4742 "\\biggl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\biggr" , "4" , "4" ) ;} ,
4743 "\\Biggl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\Biggr" , "5" , "5" ) ;} ,
4744 "\\char" : v_char_escape_to_mathml ,
4745 "\\!" : function(tokens ) {return null ;} ,
4746 "\\text" : v_text_to_mathml ,
4747 "\\textnormal" : v_text_to_mathml ,
4748 "\\textrm" : v_text_to_mathml ,
4749 "\\textsl" : v_text_to_mathml ,
4750 "\\textit" : v_text_to_mathml ,
4751 "\\texttt" : v_text_to_mathml ,
4752 "\\textbf" : v_text_to_mathml ,
4753 "\\hbox" : v_text_to_mathml ,
4754 "\\mbox" : v_text_to_mathml ,
4755 "\\begin" : v_latex_block_to_mathml ,
4758 var g_tex_environments
4759 = {"smallmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "(" , ")" ) ;} ,
4760 "pmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "(" , ")" ) ;} ,
4761 "bmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "[" , "]" ) ;} ,
4762 "Bmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "{" , "}" ) ;} ,
4763 "vmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "|" , "|" ) ;} ,
4764 "Vmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "\u2016" , "\u2016" ) ;} ,
4765 "cases" : function(tokens ) {return v_matrix_to_mathml (tokens , "{" , null ) ;} ,
4766 "array" : v_array_to_mathml ,
4767 "displaymath" : v_displaymath_to_mathml ,
4770 var g_limit_commands
4771 = {"\\bigcap" : "\u22c2" ,
4772 "\\bigcup" : "\u22c3" ,
4773 "\\bigodot" : "\u2a00" ,
4774 "\\bigoplus" : "\u2a01" ,
4775 "\\bigotimes" : "\u2a02" ,
4776 "\\bigsqcup" : "\u2a06" ,
4777 "\\biguplus" : "\u2a04" ,
4778 "\\bigvee" : "\u22c1" ,
4779 "\\bigwedge" : "\u22c0" ,
4780 "\\coprod" : "\u2210" ,
4781 "\\prod" : "\u220f" ,
4782 "\\sum" : "\u2211" ,
4784 "\\injlim" : "inj lim" ,
4786 "\\liminf" : "lim inf" ,
4787 "\\limsup" : "lum sup" ,
4790 "\\projlim" : "proj lim" ,
4792 "\\underbrace" : null ,
4793 "\\overbrace" : null ,
4794 "\\underline" : null ,
4795 "\\overline" : null ,
4798 function v_piece_to_mathml (tokens ) {
4799 var v_token = tokens.list[tokens.index] ;
4800 var v_result = null ;
4801 if( ( v_token == "{" ) ) {
4803 v_result = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4805 if( ( tokens.list[tokens.index] == "}" ) ) {
4809 else if( ( v_token in g_relation_symbols
4811 v_result = result_element( "mo" ,0 , g_relation_symbols
4815 else if( ( v_token in g_operator_symbols
4817 v_result = result_element( "mo" ,0 , g_operator_symbols
4821 else if( ( v_token in g_left_delimiters
4823 v_result = result_element( "mo" ,0 , g_left_delimiters
4827 else if( ( v_token in g_right_delimiters
4829 v_result = result_element( "mo" ,0 , g_right_delimiters
4833 else if( ( v_token in g_word_operators
4835 v_result = result_element( "mi" , 1
4836 , "mathvariant" , "normal" , g_word_operators
4840 else if( ( v_token in g_greek_letters
4842 v_result = result_element( "mi" , 1
4843 , "fontstyle" , "normal" , g_greek_letters
4847 else if( ( v_token in g_named_identifiers
4849 v_result = result_element( "mi" ,0 , g_named_identifiers
4853 else if( ( v_token in g_punct_and_space
4855 v_result = result_element( "mtext" ,0 , g_punct_and_space
4859 else if( ( v_token in g_tex_commands
4862 v_result = g_tex_commands
4863 [ v_token ] (tokens ) ;
4866 v_result = result_element( "mn" ,0 , v_token ) ;
4871 function v_subexpr_to_mathml (tokens ) {
4872 var v_result = null ;
4873 var v_mmultiscripts = null ;
4874 var v_mprescripts = null ;
4875 if( ( ( tokens.list[tokens.length<=tokens.index+ 0 ? tokens.length-1 : tokens.index+ 0 ]
4876 == "{" ) && ( tokens.list[tokens.length<=tokens.index+ 1 ? tokens.length-1 : tokens.index+ 1 ]
4877 == "}" ) && ( ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4878 == "_" ) || ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4880 v_mmultiscripts = result_element( "mmultiscripts" ,0) ;
4881 v_mprescripts = result_element( "mprescripts" ,0) ;
4882 result_element_append( v_mmultiscripts , v_mprescripts );
4883 while( ( ( tokens.list[tokens.length<=tokens.index+ 0 ? tokens.length-1 : tokens.index+ 0 ]
4884 == "{" ) && ( tokens.list[tokens.length<=tokens.index+ 1 ? tokens.length-1 : tokens.index+ 1 ]
4885 == "}" ) && ( ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4886 == "_" ) || ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4888 var v_subscript = null ;
4889 var v_superscript = null ;
4892 if( ( tokens.list[tokens.index] == "_" ) ) {
4894 v_subscript = v_piece_to_mathml (tokens ) ;
4896 else if( ( tokens.list[tokens.index] == "^" ) ) {
4898 v_superscript = v_piece_to_mathml (tokens ) ;
4900 if( ( tokens.list[tokens.index] == "_" ) ) {
4902 v_subscript = v_piece_to_mathml (tokens ) ;
4904 else if( ( tokens.list[tokens.index] == "^" ) ) {
4906 v_superscript = v_piece_to_mathml (tokens ) ;
4908 result_element_append( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) );
4909 result_element_append( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) );
4912 var v_limit_style = ( tokens.list[tokens.index] in g_limit_commands
4914 if( ( tokens.list[tokens.index] == null ) ) {
4915 if( ( v_mmultiscripts != null ) ) {
4916 result_element_prepend( v_mmultiscripts , result_element( "mrow" ,0) , v_mprescripts );
4917 return v_mmultiscripts ;
4920 return result_element( "mrow" ,0) ;
4923 else if( ( tokens.list[tokens.index] in g_left_delimiters
4925 v_result = v_heuristic_subexpression (tokens ) ;
4928 v_result = v_piece_to_mathml (tokens ) ;
4930 var v_base = v_result ;
4931 var v_subscript = null ;
4932 var v_superscript = null ;
4933 if( ( tokens.list[tokens.index] == "_" ) ) {
4935 v_subscript = v_piece_to_mathml (tokens ) ;
4937 else if( ( tokens.list[tokens.index] == "^" ) ) {
4939 v_superscript = v_piece_to_mathml (tokens ) ;
4941 if( ( tokens.list[tokens.index] == "_" ) ) {
4943 v_subscript = v_piece_to_mathml (tokens ) ;
4945 else if( ( tokens.list[tokens.index] == "^" ) ) {
4947 v_superscript = v_piece_to_mathml (tokens ) ;
4949 if( ( v_mmultiscripts != null ) ) {
4950 result_element_prepend( v_mmultiscripts , v_base , v_mprescripts );
4951 result_element_prepend( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) , v_mprescripts );
4952 result_element_prepend( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) , v_mprescripts );
4954 while( ( ( tokens.list[tokens.length<=tokens.index+ 0 ? tokens.length-1 : tokens.index+ 0 ]
4955 == "{" ) && ( tokens.list[tokens.length<=tokens.index+ 1 ? tokens.length-1 : tokens.index+ 1 ]
4956 == "}" ) && ( ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4957 == "_" ) || ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4959 if( ( v_mmultiscripts == null ) ) {
4960 v_mmultiscripts = result_element( "mmultiscripts" ,0 , v_base ) ;
4961 v_mprescripts = null ;
4962 if( ( ( v_superscript != null ) || ( v_subscript != null ) ) ) {
4963 result_element_append( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) );
4964 result_element_append( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) );
4967 var v_subscript = null ;
4968 var v_superscript = null ;
4971 if( ( tokens.list[tokens.index] == "_" ) ) {
4973 v_subscript = v_piece_to_mathml (tokens ) ;
4975 else if( ( tokens.list[tokens.index] == "^" ) ) {
4977 v_superscript = v_piece_to_mathml (tokens ) ;
4979 if( ( tokens.list[tokens.index] == "_" ) ) {
4981 v_subscript = v_piece_to_mathml (tokens ) ;
4983 else if( ( tokens.list[tokens.index] == "^" ) ) {
4985 v_superscript = v_piece_to_mathml (tokens ) ;
4987 result_element_prepend( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) , v_mprescripts );
4988 result_element_prepend( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) , v_mprescripts );
4990 if( ( v_mmultiscripts != null ) ) {
4991 v_result = v_mmultiscripts ;
4993 else if( ( ( v_subscript != null ) && ( v_superscript != null ) ) ) {
4994 v_result = result_element( ( v_limit_style ? "munderover" : "msubsup" ) ,0 , v_base , v_subscript , v_superscript ) ;
4996 else if( ( v_subscript != null ) ) {
4997 v_result = result_element( ( v_limit_style ? "munder" : "msub" ) ,0 , v_base , v_subscript ) ;
4999 else if( ( v_superscript != null ) ) {
5000 v_result = result_element( ( v_limit_style ? "mover" : "msup" ) ,0 , v_base , v_superscript ) ;
5004 function v_subexpr_chain_to_mathml (tokens , v_stop_tokens ) {
5005 var v_result = null ;
5007 var v_mfrac = null ;
5008 var v_wrapped_result = null ;
5009 while( ( ( tokens.list[tokens.index] != null ) && !( ( tokens.list[tokens.index] in v_stop_tokens ) ) ) ) {
5010 if( ( tokens.list[tokens.index] == "\\over" ) ) {
5012 v_mfrac = result_element( "mfrac" ,0 , v_result ) ;
5013 v_wrapped_result = v_mfrac ;
5017 else if( ( tokens.list[tokens.index] == "\\choose" ) ) {
5019 v_mfrac = result_element( "mfrac" , 1
5020 , "linethickness" , "0" , v_result ) ;
5021 v_wrapped_result = result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , v_mfrac , result_element( "mo" ,0 , ")" ) ) ;
5026 var v_node = v_collect_precedence_group (tokens , g_relations_precedence_group
5027 , v_stop_tokens , function(tokens , v_stop_tokens ) {return v_collect_precedence_group (tokens , g_addition_precedence_group
5028 , v_stop_tokens , function(tokens , v_stop_tokens ) {return v_collect_precedence_group (tokens , g_multiplication_precedence_group
5029 , v_stop_tokens , v_collect_invisible_group ) ;} ) ;} ) ;
5030 if( ( v_mrow != null ) ) {
5031 result_element_append( v_mrow , v_node );
5033 else if( ( v_result != null ) ) {
5034 v_mrow = result_element( "mrow" ,0 , v_result , v_node ) ;
5042 if( ( v_mfrac != null ) ) {
5043 result_element_append( v_mfrac , v_result );
5044 return v_wrapped_result ;
5050 var g_optional_arg_stop_tokens
5066 function v_optional_arg_to_mathml (tokens ) {
5067 if( ( tokens.list[tokens.index] != "[" ) ) {
5071 var v_result = v_subexpr_chain_to_mathml (tokens , g_optional_arg_stop_tokens
5073 if( ( tokens.list[tokens.index] == "]" ) ) {
5078 var g_hard_stop_tokens
5093 var g_right_delimiter_stop_tokens
5112 "\\rVert" : "\u2016" ,
5113 "\\rceil" : "\u2309" ,
5114 "\\rfloor" : "\u230b" ,
5115 "\\rmoustache" : "\u23b1" ,
5116 "\\rangle" : "\u232a" ,
5119 function v_heuristic_subexpression (tokens ) {
5120 var v_result = result_element( "mrow" ,0) ;
5121 result_element_append( v_result , v_piece_to_mathml (tokens ) );
5122 result_element_append( v_result , v_subexpr_chain_to_mathml (tokens , g_right_delimiter_stop_tokens
5124 if( ( ( tokens.list[tokens.index] != null ) && !( ( tokens.list[tokens.index] in g_hard_stop_tokens
5126 result_element_append( v_result , v_piece_to_mathml (tokens ) );
5130 var g_relations_precedence_group
5131 = g_relation_symbols
5133 var g_addition_precedence_group
5139 var g_multiplication_precedence_group
5146 function v_collect_precedence_group (tokens , v_operators , v_stop_tokens , v_reader ) {
5147 var v_result = v_reader (tokens , v_stop_tokens ) ;
5149 while( ( ( tokens.list[tokens.index] != null ) && !( ( tokens.list[tokens.index] in v_stop_tokens ) ) && ( tokens.list[tokens.index] in v_operators ) ) ) {
5150 if( ( v_mrow == null ) ) {
5151 v_mrow = result_element( "mrow" ,0 , v_result ) ;
5154 result_element_append( v_mrow , v_piece_to_mathml (tokens ) );
5155 if( ( ( tokens.list[tokens.index] != null ) && ( tokens.list[tokens.index] in v_stop_tokens ) ) ) {
5159 result_element_append( v_mrow , v_reader (tokens , v_stop_tokens ) );
5164 function v_collect_invisible_group (tokens , v_stop_tokens ) {
5165 var v_result = v_subexpr_to_mathml (tokens ) ;
5167 while( ( ( tokens.list[tokens.index] != null ) && !( ( tokens.list[tokens.index] in v_stop_tokens ) ) && ( ( tokens.list[tokens.index] in g_named_identifiers
5168 ) || ( tokens.list[tokens.index] in g_left_delimiters
5170 if( ( v_mrow == null ) ) {
5171 v_mrow = result_element( "mrow" ,0 , v_result ) ;
5174 result_element_append( v_mrow , result_element( "mo" ,0 , "\u2062" ) );
5175 if( ( ( tokens.list[tokens.index] != null ) && ( tokens.list[tokens.index] in v_stop_tokens ) ) ) {
5179 result_element_append( v_mrow , v_subexpr_to_mathml (tokens ) );
5186 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;
5188 var/*const*/ tokenize_text_re = /[\${}\\]|\\[a-zA-Z]+|[^{}\$]+/g;
5190 var/*const*/ tokenize_text_commands = {
5202 function tokenize_latex_math(input)
5204 var result = new Array();
5205 var in_text_mode = 0;
5206 var brace_level = [];
5209 if(input.charAt(0) == '$' &&
5210 input.charAt(input.length-1) == '$')
5211 input = input.slice(1, input.length-1);
5215 tokenize_re.lastIndex = pos;
5216 var m = tokenize_re.exec(input);
5217 pos = tokenize_re.lastIndex;
5221 } else if(m[1] != null) {
5222 result.push(m[1], m[2]);
5223 } else if(m[3] == '\\sp') {
5225 } else if(m[3] == '\\sb') {
5230 } else if(m[4] != null) {
5232 } else if(m[3] != null && m[3] in tokenize_text_commands) {
5234 brace_level.push(0);
5240 tokenize_text_re.lastIndex = pos;
5241 var m = tokenize_text_re.exec(input);
5242 pos = tokenize_text_re.lastIndex;
5246 } else if(m[0] == '$') {
5248 } else if(m[0] == '{') {
5249 brace_level[brace_level.length-1]++;
5250 } else if(m[0] == '}') {
5251 if(--brace_level[brace_level.length-1] <= 0) {
5262 function post_process_mathml(event)
5264 var url = GM_getValue('click-post-url', null);
5268 var ser = new XMLSerializer();
5269 var xhr = GM_xmlhttpRequest({
5272 headers: { 'Content-Type': 'text/xml; charset=utf-8',
5273 'Content-Location': document.location },
5274 data: ser.serializeToString(event.currentTarget),
5275 onerror: function(details) {
5276 alert("There was an error processing the request. " +
5277 "HTTP status code " + details.status + ' ' + details.statusText);
5279 onload: function(details) {
5280 window.status = "Successfully posted MathML. Status: "
5281 + details.status + ' ' + details.statusText;
5284 window.status = "Posting MathML to " + url + "...";
5288 function patch_img(node)
5291 if(node.currentTarget)
5292 node = node.currentTarget;
5294 var alt = node.getAttribute('alt');
5297 /^\\includegraphics|^\$\\displaystyle \\xymatrix/.test(alt))
5300 var latex_string = null;
5305 if((node.parentNode.tagName == 'DIV' &&
5306 node.parentNode.getAttribute('CLASS') == 'mathdisplay')
5307 || (node.parentNode.tagName == 'SPAN' &&
5308 node.parentNode.getAttribute('CLASS') == 'MATH'))
5310 var parent = node.parentNode;
5311 var previous = parent.previousSibling;
5312 var/*const*/ non_whitespace = /[^\s]/;
5315 previous.nodeType == node.TEXT_NODE &&
5316 !non_whitespace.test(previous.data))
5317 previous = previous.previousSibling;
5320 previous.nodeType == node.ELEMENT_NODE &&
5321 previous.tagName == 'P' &&
5324 previous = previous.lastChild;
5326 previous.nodeType == node.TEXT_NODE &&
5327 !non_whitespace.test(previous.data))
5328 previous = previous.previousSibling;
5332 previous.nodeType == node.COMMENT_NODE) {
5333 latex_string = previous.data.replace(/^\s*MATH\s*/, '')
5334 .replace(/\s+$/, '');
5339 if(!latex_string && /^\$.+\$$/.test(alt)
5340 && !(/\.{3} \.{3}/.test(alt)))
5345 if(latex_string == null)
5349 tokens = new Object();
5350 tokens.list = tokenize_latex_math(latex_string);
5351 tokens.list.push(null);
5356 var mrow = v_subexpr_chain_to_mathml(tokens, {});
5357 fix_mathvariant(mrow, null);
5359 mathml = document.createElementNS(mmlns, 'math');
5360 mathml.setAttribute("latex", latex_string);
5361 mathml.setAttribute("mathvariant", "normal");
5362 mathml.appendChild(mrow);
5364 mathml.addEventListener("click", post_process_mathml, false);
5367 GM_log("Display LaTeX failed with error " + e + " on " + latex_string);
5374 node.parentNode.replaceChild(mathml, node);
5378 function patch_text(node0)
5380 var text = node0.nodeValue;
5381 var results = /\$[^$]+\$|\[tex\](.+?)\[\/tex\]/.exec(text);
5384 var latex_string = (results[1] == null ? results[0] : '$'+results[1]+'$');
5387 tokens = new Object();
5388 tokens.list = tokenize_latex_math(latex_string);
5389 tokens.list.push(null);
5394 var mrow = v_subexpr_chain_to_mathml(tokens, {});
5395 fix_mathvariant(mrow, null);
5397 mathml = document.createElementNS(mmlns, 'math');
5398 mathml.setAttribute("latex", latex_string);
5399 mathml.setAttribute("mathvariant", "normal");
5400 mathml.appendChild(mrow);
5402 mathml.addEventListener("click", post_process_mathml, false);
5405 GM_log("Display LaTeX failed with error " + e + " on " + latex_string);
5412 var node2 = node0.splitText(results.index);
5413 node2.deleteData(0, results[0].length);
5415 node2.parentNode.insertBefore(mathml, node2);
5424 function patch_element(node)
5426 if(node.nodeType == node.TEXT_NODE)
5428 else if(node.nodeType == node.ELEMENT_NODE) {if(node.tagName == 'TEXTAREA' || node.tagName == 'textarea' ||
5429 node.tagName == 'INPUT' || node.tagName == 'input' ||
5430 node.tagName == 'SCRIPT' || node.tagName == 'script')
5434 if(do_patch_images && (node.tagName == 'IMG' || node.tagName == 'img')) {
5438 node.addEventListener("click", patch_img, false);
5443 var child = node.firstChild;
5445 var next = child.nextSibling;
5446 if (child.className == 'stopLatex2mml') {
5449 patch_element(child);
5454 this.patch_element = patch_element;
5457 var do_patch_images = GM_getValue("patch-images", false);
5458 var delayed_patch = GM_getValue("delayed-patch", false);
5460 var do_patch_images = true;
5461 var delayed_patch = false;
5464 if( va_view == 'web' ){
5465 patch_element(document.documentElement);
5473 Deck JS - deck.simplemath
5474 Copyright (c) 2012 RĂ©mi Emonet,
5475 using a modified version of the script from http://gold-saucer.afraid.org/mathml/greasemonkey/ by Steve Cheng
5479 This module provides a support for latex equation syntax.
5482 (function($, deck, undefined) {
5483 var $d = $(document);
5484 var may = function(f) {return f ? f : function() {}};
5486 $d.bind('deck.init', function() {
5487 var container = $[deck]('getContainer');
5488 $('.latex', container).each(function() {
5490 var v = $(it).text();
5491 it.innerHTML = "$\\displaystyle "+v+"$";
5492 new latex2mml().patch_element(it);
5499 Deck JS - deck.clone
5500 Copyright (c) 2011-2014 RĂ©mi Emonet, original version from RĂ©mi BARRAQUAND
5501 Licensed under the MIT license.
5502 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
5506 This module provides a support for cloning the deck and enabling a presenter view.
5507 It also provides the behavior that copies the current "notes" to a "notes-target", to be used in the presenter view.
5510 (function($, deck, undefined) {
5511 var $d = $(document);
5512 var clones = new Array();
5514 $.extend(true, $[deck].defaults, {
5516 clonepointer: '.clonepointer',
5517 cloneNotes: '.notes',
5518 cloneNotesTarget: '.notes-target'
5521 isClone: 'is-clone',
5522 hasClones: 'has-clones',
5523 pointerClick: 'pointer-click'
5531 fitFollowsClone: true
5534 var hadClones = false;
5535 var cleanClones = function() {
5536 var opts = $[deck]('getOptions');
5537 // remove closed windows
5538 $.each(clones, function(index, clone) {
5539 if (clone.closed()) {
5540 clones.splice(index, 1); // remove element "index"
5543 // tag/untag the current container depending on the presence of clones
5544 if (clones.length > 0) {
5545 $("body").addClass(opts.classes.hasClones);
5546 if (opts.fitFollowsClone && !hadClones) $[deck]('disableScale');
5549 $("body").removeClass(opts.classes.hasClones);
5550 if (opts.fitFollowsClone && hadClones) $[deck]('enableScale');
5556 jQuery.deck('addClone')
5557 Create a clone of this window and add it to the clones list.
5559 $[deck]('extend', 'addClone', function() {
5560 clone = new DeckClone();
5565 $[deck]('extend', 'cleanClones', function() { // to be triggered by the closing of a clone window
5566 setTimeout(cleanClones, 1);
5568 $[deck]('extend', 'pointerAt', function(rx, ry) {
5569 var pos = {left: (rx*100)+"%", top: (ry*100)+"%"};
5570 var opts = $[deck]('getOptions');
5571 var current = $[deck]('getToplevelSlideOf', $[deck]('getSlide')).node; // actually uses the step extension
5572 var pointers = $(opts.selectors.clonepointer);
5573 if (!current.is(pointers.parent())) { // move them within the new slide if it changed
5574 pointers.show().appendTo(current);
5577 // using % position instead of ".offset" as there are jitter/glitches with it
5579 $[deck]('extend', 'pointerDown', function() {
5580 var opts = $[deck]('getOptions');
5581 var pointers = $(opts.selectors.clonepointer);
5582 pointers.addClass(opts.classes.pointerClick);
5584 $[deck]('extend', 'pointerUp', function() {
5585 var opts = $[deck]('getOptions');
5586 var pointers = $(opts.selectors.clonepointer);
5587 pointers.removeClass(opts.classes.pointerClick);
5590 var isClone = false;
5591 var parentDeck = null;
5595 $d.bind('deck.init', function() {
5596 var opts = $[deck]('getOptions');
5597 var container = $[deck]('getContainer');
5599 if (opts.snippets.clone) {
5600 var d = function() {return $('<div/>');}
5601 d().addClass("clonepointer scale-on-click").append(
5602 d().attr("style", "border: 2px solid red; border-radius: 50%; z-index:10;"
5603 +"margin: -11px 0 0 -11px; width:20px; height:20px; opacity: .5;")
5604 ).appendTo(container);
5605 d().addClass("clonepointer scale-on-click").append(
5606 d().attr("style", "border: 2px solid red; border-radius: 50%; z-index:10;"
5607 +"margin: -16px 0 0 -16px; width:30px; height:30px;")
5608 ).appendTo(container);
5609 d().addClass(opts.selectors.cloneNotesTarget.replace(/\./, ''))
5610 .appendTo(container);
5613 $(opts.selectors.clonepointer).hide();
5615 function safeIsClone(w) {
5617 return w.opener && w.opener.___iscloner___;
5619 // when linked from another origin, there is an opener
5620 // but accessing its properties throws a security exception
5625 isClone = safeIsClone(window);
5627 if (isClone) { // it's a clone!
5628 $("body").addClass(opts.classes.isClone);
5629 $(".anim-continue", container).removeClass("anim-continue"); // friend with anim extension
5630 window.___fromparent___ = false;
5631 parentDeck = function() {
5632 if (! window.___fromparent___) {
5633 window.opener.$.deck.apply(window.opener.$, arguments);
5636 $(window).on('unload', function() {
5637 parentDeck('cleanClones');
5639 } else { // it is a normal window
5640 /* bind clone key events */
5641 $d.unbind('keydown.deckclone').bind('keydown.deckclone', function(e) {
5642 if (e.which === opts.keys.clone || $.inArray(e.which, opts.keys.clone) > -1) {
5643 if (e.ctrlKey) return; // do not trigger on Ctrl+C (by default)
5644 $[deck]('addClone');
5645 window.___iscloner___ = true;
5651 /* Update current slide number with each change event */
5652 .bind('deck.change', function(e, from, to) {
5654 parentDeck('go', to);
5657 $.each(clones, function(index, clone) {
5658 clone.deck('go', to);
5661 var opts = $[deck]('getOptions');
5662 var currentTopLevel = $[deck]('getToplevelSlideOf', $[deck]('getSlide', to)).node;
5663 var notes = $(opts.selectors.cloneNotes, currentTopLevel).html();
5664 if (notes === undefined) {
5665 $(opts.selectors.cloneNotesTarget).html("");
5667 $(opts.selectors.cloneNotesTarget).html(notes);
5671 /* Replicate mouse cursor */
5672 .bind('mousemove', function(e) {
5673 if (isClone) return;
5674 var current = $[deck]('getToplevelSlideOf', $[deck]('getSlide')).node; // actually uses the step extension (dependency can be removed if needed)
5675 var r = current.get(0).getBoundingClientRect();
5676 var x = (e.clientX - r.left) / r.width;
5677 var y = (e.clientY - r.top) / r.height;
5679 if (x < 0 || y < 0 || x > 1 || y > 1) return;
5680 $.each(clones, function(index, clone) {
5681 clone.deck('pointerAt', x, y);
5684 .bind('mousedown', function(e) {
5685 if (isClone) return;
5687 $.each(clones, function(index, clone) {
5688 clone.deck('pointerDown');
5691 .bind('mouseup', function(e) {
5692 if (isClone) return;
5694 $.each(clones, function(index, clone) {
5695 clone.deck('pointerUp');
5700 Simple Clone manager (must be improved, by for instance adding cloning
5701 option e.g. propagate change, etc.)
5703 var DeckClone = function() {
5704 var clone = window.open(window.location);
5705 this.closed = function() {return clone.closed;}
5706 this.deck = function() {
5707 if (clone.closed) return;
5709 clone.___fromparent___ = true;
5710 clone.$.deck.apply(clone.$, arguments);
5711 clone.___fromparent___ = false;
5720 Copyright (c) 2011-2014 Caleb Troughton
5721 Dual licensed under the MIT license.
5722 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
5726 This module adds the necessary methods and key bindings to show and hide a form
5727 for jumping to any slide number/id in the deck (and processes that form
5728 accordingly). The form-showing state is indicated by the presence of a class on
5731 (function($, undefined) {
5732 var $document = $(document);
5735 var maybeAddSnippet = function() {
5736 var options = $.deck('getOptions');
5737 if (options.snippets.goto) {
5738 if ($(options.selectors.gotoForm).size() > 0 && options.alert.goto) {
5739 alert("'options.snippets.goto' is true but a "+options.selectors.gotoForm+" has been found."
5740 +"\nThis might cause interaction glitches."
5742 +"\nSuggestion: remove your html snippet or pass the {snippets: {goto: false}} option."
5745 $('<form/>').addClass('goto-form').attr('action', '.').attr('method', 'get')
5746 .append($('<label/>').attr('for', 'goto-slide').text('Go to slide:'))
5747 .append($('<input/>').attr('type', 'text').attr('id', 'goto-slide').attr('name', 'slidenum').attr('list', 'goto-datalist'))
5748 .append($('<datalist/>').attr('id', 'goto-datalist'))
5749 .append($('<input/>').attr('type', 'submit').attr('value', 'Go'))
5750 .appendTo($.deck('getContainer'));
5754 var bindKeyEvents = function() {
5755 $document.unbind('keydown.deckgoto');
5756 $document.bind('keydown.deckgoto', function(event) {
5757 var key = $.deck('getOptions').keys.goto;
5758 if (event.which === key || $.inArray(event.which, key) > -1) {
5759 event.preventDefault();
5760 $.deck('toggleGoTo');
5765 var populateDatalist = function() {
5766 var options = $.deck('getOptions');
5767 var $datalist = $(options.selectors.gotoDatalist);
5769 $.each($.deck('getSlides'), function(i, $slide) {
5770 var id = $slide.attr('id');
5772 $datalist.append('<option value="' + id + '">');
5777 var markRootSlides = function() {
5778 var options = $.deck('getOptions');
5779 var slideTest = $.map([
5780 options.classes.before,
5781 options.classes.previous,
5782 options.classes.current,
5783 options.classes.next,
5784 options.classes.after
5785 ], function(el, i) {
5790 $.each($.deck('getSlides'), function(i, $slide) {
5791 var $parentSlides = $slide.parentsUntil(
5792 options.selectors.container,
5796 if ($parentSlides.length) {
5797 $slide.removeData('rootIndex');
5799 else if (!options.countNested) {
5801 $slide.data('rootIndex', rootCounter);
5806 var handleFormSubmit = function() {
5807 var options = $.deck('getOptions');
5808 var $form = $(options.selectors.gotoForm);
5810 $form.unbind('submit.deckgoto');
5811 $form.bind('submit.deckgoto', function(event) {
5812 var $field = $(options.selectors.gotoInput);
5813 var indexOrId = $field.val();
5814 var index = parseInt(indexOrId, 10);
5816 if (!options.countNested) {
5817 if (!isNaN(index) && (index > rootCounter || index <= 0)) {
5820 $.each($.deck('getSlides'), function(i, $slide) {
5821 if ($slide.data('rootIndex') === index) {
5828 $.deck('go', isNaN(index) ? indexOrId : index - 1);
5831 event.preventDefault();
5836 Extends defaults/options.
5838 options.classes.goto
5839 This class is added to the deck container when showing the Go To Slide
5842 options.selectors.gotoDatalist
5843 The element that matches this selector is the datalist element that will
5844 be populated with options for each of the slide ids. In browsers that
5845 support the datalist element, this provides a drop list of slide ids to
5846 aid the user in selecting a slide.
5848 options.selectors.gotoForm
5849 The element that matches this selector is the form that is submitted
5850 when a user hits enter after typing a slide number/id in the gotoInput
5853 options.selectors.gotoInput
5854 The element that matches this selector is the text input field for
5855 entering a slide number/id in the Go To Slide form.
5858 The numeric keycode used to show the Go To Slide form.
5861 If false, only top level slides will be counted when entering a
5864 $.extend(true, $.deck.defaults, {
5870 gotoDatalist: '#goto-datalist',
5871 gotoForm: '.goto-form',
5872 gotoInput: '#goto-slide'
5891 jQuery.deck('showGoTo')
5893 Shows the Go To Slide form by adding the class specified by the goto class
5894 option to the deck container.
5896 $.deck('extend', 'showGoTo', function() {
5897 var options = $.deck('getOptions');
5898 $.deck('getContainer').addClass(options.classes.goto);
5899 $(options.selectors.gotoForm).attr('aria-hidden', false);
5900 $(options.selectors.gotoInput).focus();
5904 jQuery.deck('hideGoTo')
5906 Hides the Go To Slide form by removing the class specified by the goto class
5907 option from the deck container.
5909 $.deck('extend', 'hideGoTo', function() {
5910 var options = $.deck('getOptions');
5911 $(options.selectors.gotoInput).blur();
5912 $.deck('getContainer').removeClass(options.classes.goto);
5913 $(options.selectors.gotoForm).attr('aria-hidden', true);
5917 jQuery.deck('toggleGoTo')
5919 Toggles between showing and hiding the Go To Slide form.
5921 $.deck('extend', 'toggleGoTo', function() {
5922 var options = $.deck('getOptions');
5923 var hasGotoClass = $.deck('getContainer').hasClass(options.classes.goto);
5924 $.deck(hasGotoClass ? 'hideGoTo' : 'showGoTo');
5927 $document.bind('deck.init', function() {
5938 Deck JS - deck.progress
5939 Copyright (c) 2014 RĂ©mi Emonet
5940 Dual licensed under the MIT license.
5941 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
5945 This module adds a (current)/(total) style status indicator to the deck.
5947 It is designed to be a drop-in replacement of deck.status, but on steroĂ¯ds.
5948 Note however, that it does not handle the countNested=true case.
5950 (function($, undefined) {
5951 var $document = $(document);
5953 var INITEVENT = "dummyinit";
5954 var SIZEEVENT = "dummysize";
5956 var updateCurrent = function(event, from, to) {
5957 var opts = $.deck('getOptions');
5958 var currentSlideNumber = to + 1;
5959 var $container = $.deck('getContainer');
5960 currentSlideNumber = $.deck('getSlide', to).data('rootSlide');
5961 $(opts.selectors.statusCurrent).text(currentSlideNumber);
5964 for (; icur < $.deck('getSlides').length; icur++) {
5965 var top = $.deck('getSlide', icur).data('rootSlide');
5966 if (top == currentSlideNumber) {
5971 var currentDetail = to;
5972 var lastDetail = icur;
5973 for (; icur < $.deck('getSlides').length; icur++) {
5974 last = $.deck('getSlide', icur).data('rootSlide');
5975 lastDetail = icur+1;
5976 if ($.deck('getSlide', icur).filter(opts.selectors.statusFakeEnd).size() > 0) break;
5978 $(opts.selectors.statusTotal).text(last);
5980 // handle the data-progress
5981 var progresses = $('*['+opts.dataProgress+'], *['+opts.dataProgressOnce+'], *['+opts.dataProgressSize+']');
5982 if (progresses.size() > 0) {
5983 var visibleSlide = $.deck('getSlide').parentsUntil(opts.selectors.container).addBack().filter(opts.selectors.slides);
5985 var slide = visibleSlide.get(0).getBoundingClientRect();
5986 var screen = {width: $container.innerWidth(), height: $container.innerHeight()};
5987 var n = currentSlideNumber;
5989 var fullTotal = $.deck('getTopLevelSlides').length;
5990 var detail = {n: currentDetail+1, N: lastDetail, fullTotal: $.deck('getSlides').length};
5991 var designRatio = Math.max(slide.width / opts.designWidth, slide.height / opts.designHeight);
5994 var pFull = n/fullTotal;
5995 detail.p = detail.n/detail.N;
5996 detail.pFull = detail.n/detail.fullTotal;
5998 progresses.each(function(i, el) {
6000 bottom: function(fontSize, botByRatio, botFixed) {
6001 botFixed = botFixed || 0;
6002 $(el).css('font-size', (fontSize * designRatio)+"px");
6003 $(el).css('top', (slide.bottom - botFixed - botByRatio*designRatio)+'px');
6005 top: function(fontSize, topByRatio, topFixed) {
6006 topFixed = topFixed || 0;
6007 $(el).css('font-size', (fontSize * designRatio)+"px");
6008 $(el).css('top', (slide.top + topFixed + topByRatio*designRatio)+'px');
6011 var att = $(el).attr(event == INITEVENT ? opts.dataProgressOnce : event == SIZEEVENT ? opts.dataProgressSize : opts.dataProgress);
6012 if (att == null || att.length == 0) return;
6013 var tasks = att.split(/ *; */);
6015 var parts = tasks[t].split(/ *: */);
6016 if (parts.length != 2) {
6017 if (opts.alert.wrongDataProgress) alert(
6018 "There seem to be a problem with the following data-progress of\n '" +tasks[t]+ "'\n");
6020 var what = parts[0];
6021 var expr = parts[1];
6022 var val = eval(expr);
6024 // skip: expected to be some "magic", e.g. custom code or call to helpers
6025 } else if (what.substring(0,1) == "@") {
6026 // special attribute setting, not css
6027 what = what.substring(1);
6028 $(el).attr(what, val);
6029 } else if (what == "$text") {
6031 } else if (what == "$html") {
6034 $(el).css(what, val);
6042 var markRootSlides = function() {
6043 var opts = $.deck('getOptions');
6044 var slideTest = $.map([
6045 opts.classes.before,
6046 opts.classes.previous,
6047 opts.classes.current,
6050 ], function(el, i) {
6055 $.each($.deck('getSlides'), function(i, $slide) {
6056 var $parentSlides = $slide.parentsUntil(
6057 opts.selectors.container,
6061 if ($parentSlides.length) {
6062 $slide.data('rootSlide', $parentSlides.last().data('rootSlide'));
6066 $slide.data('rootSlide', rootCounter);
6071 var fireEventOnCurrentSlide = function(ev) {
6072 var slides = $.deck('getSlides');
6073 var $currentSlide = $.deck('getSlide');
6076 $.each(slides, function(i, $slide) {
6077 if ($slide === $currentSlide) {
6082 updateCurrent(ev, index, index);
6085 var setTotalSlideNumber = function() {
6086 var opts = $.deck('getOptions');
6087 var slides = $.deck('getSlides');
6089 var nSlides = $.deck('getTopLevelSlides').length;
6090 $(opts.selectors.statusFullTotal).text(nSlides);
6095 Extends defaults/options.
6097 opts.selectors.statusCurrent
6098 The element matching this selector displays the current slide number.
6100 opts.selectors.statusTotal
6101 The element matching this selector displays the total number of slides.
6104 If false, only top level slides will be counted in the current and
6107 $.extend(true, $.deck.defaults, {
6109 statusCurrent: '.deck-status-current',
6110 statusTotal: '.deck-status-total',
6111 statusFakeEnd: '.deck-status-fake-end',
6112 statusFullTotal: '.deck-status-full-total',
6113 progress10: '.deck-progress-10'
6116 wrongDataProgress: true,
6117 possibleDebounceProblem: true
6119 dataProgress: "data-progress",
6120 dataProgressOnce: "data-progress-once",
6121 dataProgressSize: "data-progress-size",
6122 progressSizeDebounce: 201 /* somewhat, it should be bigger that the fit debounce */
6125 $document.bind('deck.init', function() {
6126 var opts = $.deck('getOptions');
6127 $(opts.selectors.progress10).attr(opts.dataProgressSize, ':spe.bottom(10, 12)')
6129 fireEventOnCurrentSlide(INITEVENT);
6130 fireEventOnCurrentSlide(SIZEEVENT);
6131 setTotalSlideNumber();
6134 $(window).unbind('resize.deckprogress').bind('resize.deckprogress', function() {
6135 var opts = $.deck('getOptions');
6136 if (opts.alert.possibleDebounceProblem && opts.progressSizeDebounce < opts.scaleDebounce + 1) {
6138 "There might be a problem with the respective debounce value:\n progressSizeDebounce: "+opts.progressSizeDebounce+"\n scaleDebounce: "+opts.scaleDebounce);
6141 window.clearTimeout(timer);
6142 timer = window.setTimeout( function() {
6143 fireEventOnCurrentSlide(SIZEEVENT);
6144 fireEventOnCurrentSlide("fire also the update event as some things might also need resizing");
6145 }, opts.progressSizeDebounce);
6147 $document.bind('deck.change', updateCurrent);
6152 Deck JS - deck.navigation
6153 Copyright (c) 2011-2014 Caleb Troughton
6154 Dual licensed under the MIT license.
6155 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6159 This module adds clickable previous and next links to the deck.
6161 (function($, undefined) {
6162 var $document = $(document);
6164 /* Updates link hrefs, and disabled states if last/first slide */
6165 var updateButtons = function(event, from, to) {
6166 var options = $.deck('getOptions');
6167 var lastIndex = $.deck('getSlides').length - 1;
6168 var $prevSlide = $.deck('getSlide', to - 1);
6169 var $nextSlide = $.deck('getSlide', to + 1);
6170 var hrefBase = window.location.href.replace(/#.*/, '');
6171 var prevId = $prevSlide ? $prevSlide.attr('id') : undefined;
6172 var nextId = $nextSlide ? $nextSlide.attr('id') : undefined;
6173 var $prevButton = $(options.selectors.previousLink);
6174 var $nextButton = $(options.selectors.nextLink);
6176 $prevButton.toggleClass(options.classes.navDisabled, to === 0);
6177 $prevButton.attr('aria-disabled', to === 0);
6178 $prevButton.attr('href', hrefBase + '#' + (prevId ? prevId : ''));
6179 $nextButton.toggleClass(options.classes.navDisabled, to === lastIndex);
6180 $nextButton.attr('aria-disabled', to === lastIndex);
6181 $nextButton.attr('href', hrefBase + '#' + (nextId ? nextId : ''));
6185 Extends defaults/options.
6187 options.classes.navDisabled
6188 This class is added to a navigation link when that action is disabled.
6189 It is added to the previous link when on the first slide, and to the
6190 next link when on the last slide.
6192 options.selectors.nextLink
6193 The elements that match this selector will move the deck to the next
6196 options.selectors.previousLink
6197 The elements that match this selector will move to deck to the previous
6200 $.extend(true, $.deck.defaults, {
6202 navDisabled: 'deck-nav-disabled'
6206 nextLink: '.deck-next-link',
6207 previousLink: '.deck-prev-link'
6211 $document.bind('deck.init', function() {
6212 var options = $.deck('getOptions');
6213 var slides = $.deck('getSlides');
6214 var $current = $.deck('getSlide');
6215 var $prevButton = $(options.selectors.previousLink);
6216 var $nextButton = $(options.selectors.nextLink);
6219 // Setup prev/next link events
6220 $prevButton.unbind('click.decknavigation');
6221 $prevButton.bind('click.decknavigation', function(event) {
6223 event.preventDefault();
6226 $nextButton.unbind('click.decknavigation');
6227 $nextButton.bind('click.decknavigation', function(event) {
6229 event.preventDefault();
6232 // Find where we started in the deck and set initial states
6233 $.each(slides, function(i, $slide) {
6234 if ($slide === $current) {
6239 updateButtons(null, index, index);
6242 $document.bind('deck.change', updateButtons);
6248 Copyright (c) 2011-2014 Caleb Troughton
6249 Dual licensed under the MIT license.
6250 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6254 This module adds the methods and key binding to show and hide a menu of all
6255 slides in the deck. The deck menu state is indicated by the presence of a class
6256 on the deck container.
6258 (function($, undefined) {
6259 var $document = $(document);
6260 var $html = $('html');
6263 var populateRootSlidesArray = function() {
6264 var options = $.deck('getOptions');
6265 var slideTest = $.map([
6266 options.classes.before,
6267 options.classes.previous,
6268 options.classes.current,
6269 options.classes.next,
6270 options.classes.after
6271 ], function(el, i) {
6276 $.each($.deck('getSlides'), function(i, $slide) {
6277 var $parentSlides = $slide.parentsUntil(
6278 options.selectors.container,
6281 if (!$parentSlides.length) {
6282 rootSlides.push($slide);
6287 var bindKeyEvents = function() {
6288 var options = $.deck('getOptions');
6289 $document.unbind('keydown.deckmenu');
6290 $document.bind('keydown.deckmenu', function(event) {
6291 var isMenuKey = event.which === options.keys.menu;
6292 isMenuKey = isMenuKey || $.inArray(event.which, options.keys.menu) > -1;
6293 if (isMenuKey && !event.ctrlKey) {
6294 $.deck('toggleMenu');
6295 event.preventDefault();
6300 var bindTouchEvents = function() {
6301 var $container = $.deck('getContainer');
6302 var options = $.deck('getOptions');
6303 var touchEndTime = 0;
6306 $container.unbind('touchstart.deckmenu');
6307 $container.bind('touchstart.deckmenu', function() {
6308 currentSlide = $.deck('getSlide');
6310 $container.unbind('touchend.deckmenu');
6311 $container.bind('touchend.deckmenu', function(event) {
6312 var now = Date.now();
6313 var isDoubletap = now - touchEndTime < options.touch.doubletapWindow;
6315 // Ignore this touch event if it caused a nav change (swipe)
6316 if (currentSlide !== $.deck('getSlide')) {
6320 $.deck('toggleMenu');
6321 event.preventDefault();
6327 var setupMenuSlideSelection = function() {
6328 var options = $.deck('getOptions');
6330 $.each($.deck('getSlides'), function(i, $slide) {
6331 $slide.unbind('click.deckmenu');
6332 $slide.bind('click.deckmenu', function(event) {
6333 if (!$.deck('getContainer').hasClass(options.classes.menu)) {
6338 event.stopPropagation();
6339 event.preventDefault();
6345 Extends defaults/options.
6347 options.classes.menu
6348 This class is added to the deck container when showing the slide menu.
6351 The numeric keycode used to toggle between showing and hiding the slide
6354 options.touch.doubletapWindow
6355 Two consecutive touch events within this number of milliseconds will
6356 be considered a double tap, and will toggle the menu on touch devices.
6358 $.extend(true, $.deck.defaults, {
6368 doubletapWindow: 400
6373 jQuery.deck('showMenu')
6375 Shows the slide menu by adding the class specified by the menu class option
6376 to the deck container.
6378 $.deck('extend', 'showMenu', function() {
6379 var $container = $.deck('getContainer');
6380 var options = $.deck('getOptions');
6382 if ($container.hasClass(options.classes.menu)) {
6386 // Hide through loading class to short-circuit transitions (perf)
6387 $container.addClass([
6388 options.classes.loading,
6389 options.classes.menu
6392 /* Forced to do this in JS until CSS learns second-grade math. Save old
6393 style value for restoration when menu is hidden. */
6394 if (Modernizr.csstransforms) {
6395 $.each(rootSlides, function(i, $slide) {
6396 $slide.data('oldStyle', $slide.attr('style'));
6398 'position': 'absolute',
6399 'left': ((i % 4) * 25) + '%',
6400 'top': (Math.floor(i / 4) * 25) + '%'
6405 // Need to ensure the loading class renders first, then remove
6406 window.setTimeout(function() {
6407 $container.removeClass(options.classes.loading);
6408 $container.scrollTop($.deck('getSlide').position().top);
6413 jQuery.deck('hideMenu')
6415 Hides the slide menu by removing the class specified by the menu class
6416 option from the deck container.
6418 $.deck('extend', 'hideMenu', function() {
6419 var $container = $.deck('getContainer');
6420 var options = $.deck('getOptions');
6422 if (!$container.hasClass(options.classes.menu)) {
6426 $container.removeClass(options.classes.menu);
6427 $container.addClass(options.classes.loading);
6429 /* Restore old style value */
6430 if (Modernizr.csstransforms) {
6431 $.each(rootSlides, function(i, $slide) {
6432 var oldStyle = $slide.data('oldStyle');
6433 $slide.attr('style', oldStyle ? oldStyle : '');
6437 window.setTimeout(function() {
6438 $container.removeClass(options.classes.loading);
6439 $container.scrollTop(0);
6444 jQuery.deck('toggleMenu')
6446 Toggles between showing and hiding the slide menu.
6448 $.deck('extend', 'toggleMenu', function() {
6449 $.deck('getContainer').hasClass($.deck('getOptions').classes.menu) ?
6450 $.deck('hideMenu') : $.deck('showMenu');
6453 $document.bind('deck.init', function() {
6454 populateRootSlidesArray();
6457 setupMenuSlideSelection();
6460 $document.bind('deck.change', function(event, from, to) {
6461 var $container = $.deck('getContainer');
6462 var containerScroll, slideTop;
6464 if ($container.hasClass($.deck('getOptions').classes.menu)) {
6465 containerScroll = $container.scrollTop();
6466 slideTop = $.deck('getSlide', to).position().top;
6467 $container.scrollTop(containerScroll + slideTop);
6474 Copyright (c) 2011-2014 RĂ©mi Emonet
6475 Licensed under the MIT license.
6476 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6480 This module provides new methods for stepping without considering sub-slides, together with tools for finding toplevel slides etc.
6481 It also overrides the defaults keybinding and countNested value (so it is better to include it after "goto" and "status" extensions).
6484 (function($, deck, undefined) {
6485 var $d = $(document);
6486 // undo the defaults (to be sure jquery behaves properly when overriding it)
6487 $.extend(true, $[deck].defaults, { keys: {next:null, previous:null}});
6489 $.extend(true, $[deck].defaults, {
6491 subslidesToNotify: ".slide,.onshowtoplevel"
6493 // Here we redefined the defaults:
6494 // - we avoid counting nested slides
6495 // - we keep up/down for top-level slides
6496 // - we still use pgup/pgdown for inner slides as they are sent by some pluggable remote controls
6498 // backspace, left arrow, page down
6499 previous: [8, 37, 33],
6500 // enter, space, right arrow, page up
6501 next: [13, 32, 39, 34],
6503 previousTopLevel: [38],
6507 nextEndOfTopLevel: [90]
6511 var myInArray = function(el, arr) {
6512 for (i in arr) if (arr[i].is(el)) return i*1; // cast to int
6515 $[deck]('extend', 'getSlideIndex', function(node) {
6516 var slides = $[deck]('getSlides');
6517 var ind = myInArray(node, slides);
6520 $[deck]('extend', 'getToplevelSlideOf', function(node) {
6521 var opts = $[deck]('getOptions');
6522 var slides = $[deck]('getSlides');
6523 var last = {node: $(node), index: myInArray(node, slides)};
6524 $(node).parentsUntil(opts.selectors.container).each( function(ii, v) {
6525 var ind = myInArray(v, slides);
6527 last = {node: $(v), index: ind};
6532 $[deck]('extend', 'getToplevelSlideOfIndex', function(ind) {
6533 return $[deck]('getToplevelSlideOf', $[deck]('getSlide', ind));
6535 $[deck]('extend', 'previousTopLevelSlide', function() {
6536 /* Find the real previous parent */
6537 var current = $[deck]('getSlide');
6538 var currentParent = $[deck]('getToplevelSlideOf', current);
6539 var toGo = currentParent.index;
6540 if (current.is(currentParent.node) && toGo > 0) {
6541 // This is already toplevel slide, just go to the previous toplevel one (parent of the previous one)
6542 toGo = $[deck]('getToplevelSlideOfIndex', toGo-1).index;
6544 $[deck]('go', toGo);
6547 $[deck]('extend', 'nextTopLevelSlide', function() {
6548 /* Find the real next parent */
6549 var current = $[deck]('getSlide');
6550 var currentParent = $[deck]('getToplevelSlideOf', current);
6551 var icur = currentParent.index;
6552 for (; icur < $[deck]('getSlides').length; icur++) {
6553 var cursorParent = $[deck]('getToplevelSlideOfIndex', icur).node;
6554 if (!cursorParent.is(currentParent.node)) {
6555 $[deck]('go', icur);
6560 $[deck]('extend', 'nextEndOfTopLevelSlide', function() {
6561 /* Find the real next parent */
6562 var current = $[deck]('getSlideIndex', $[deck]('getSlide'));
6563 var nextParent = $[deck]('getToplevelSlideOfIndex', current + 1);
6564 var icur = nextParent.index;
6565 for (; icur < $[deck]('getSlides').length; icur++) {
6566 var cursorParent = $[deck]('getToplevelSlideOfIndex', icur).node;
6567 if (!cursorParent.is(nextParent.node)) {
6568 $[deck]('go', icur-1);
6572 if (icur == $[deck]('getSlides').length) {
6573 $[deck]('go', icur-1);
6576 $d.bind('deck.init', function() {
6577 $d.unbind('keydown.decknexttoplevel').bind('keydown.decknexttoplevel', function(e) {
6578 var $opts = $[deck]('getOptions');
6579 var key = $opts.keys.nextTopLevel;
6580 if (e.which === key || $.inArray(e.which, key) > -1) {
6582 $[deck]('nextTopLevelSlide');
6585 $d.unbind('keydown.decknextendoftoplevel').bind('keydown.decknextendoftoplevel', function(e) {
6586 var $opts = $[deck]('getOptions');
6587 var key = $opts.keys.nextEndOfTopLevel;
6588 if (e.which === key || $.inArray(e.which, key) > -1) {
6590 $[deck]('nextEndOfTopLevelSlide');
6593 $d.unbind('keydown.deckprevioustoplevel').bind('keydown.deckprevioustoplevel', function(e) {
6594 var $opts = $[deck]('getOptions');
6595 var key = $opts.keys.previousTopLevel;
6596 if (e.which === key || $.inArray(e.which, key) > -1) {
6598 $[deck]('previousTopLevelSlide');
6602 // When jumping (not steping), we will init the subslides (in case they are animations), in a backward order, and then fast forward necessary animations
6603 var bigJump = function(from, to) {
6604 var direction = "forward";
6606 direction = "reverse";
6608 var opts = $[deck]('getOptions');
6609 $($[deck]('getToplevelSlideOfIndex', to).node.find(opts.selectors.subslidesToNotify).get().reverse()).each(function(ind, el) {$(el).triggerHandler('deck.toplevelBecameCurrent', direction)});
6610 for (icur = $[deck]('getToplevelSlideOfIndex', to).index + 1; icur < to+1; icur++) {
6611 $[deck]('getSlides')[icur].triggerHandler('deck.afterToplevelBecameCurrent', 'forward');
6614 $d.bind('deck.change', function(e, from, to) {
6615 if ( Math.abs(from - to) > 1 || ! $[deck]('getToplevelSlideOfIndex', to).node.is($[deck]('getToplevelSlideOfIndex', from).node)) {
6616 // consider natural jumps and the case where we actually changed (top level) slide (even with a step)
6622 (function($, deck, undefined) {
6623 $(document).bind('deck.change', function(e, from, to) {
6624 var $prev = $[deck]('getSlide', to-1),
6625 $next = $[deck]('getSlide', to+1),
6626 $oldprev = $[deck]('getSlide', from-1),
6627 $oldnext = $[deck]('getSlide', from+1);
6629 var direction = "forward";
6631 direction = "reverse";
6634 $[deck]('getSlide', from).triggerHandler('deck.lostCurrent', [direction, from, to]);
6635 $[deck]('getSlide', to).triggerHandler('deck.becameCurrent', [direction, from, to]);
6637 $oldprev && $oldprev.triggerHandler('deck.lostPrevious', [direction, from, to]);
6638 $oldnext && $oldnext.triggerHandler('deck.lostNext', [direction, from, to]);
6640 $prev && $prev.triggerHandler('deck.becamePrevious', [direction, from, to]);
6641 $next && $next.triggerHandler('deck.becameNext', [direction, from, to]);
6648 Copyright (c) 2012-2014 RĂ©mi Emonet
6649 Licensed under the MIT license.
6650 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6654 (function($, deck, undefined) {
6655 // The next two lines are the color plugin from jquery
6656 /*! jQuery Color v@2.1.2 http://github.com/jquery/jquery-color | jquery.org/license */
6657 (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);
6659 var $d = $(document);
6660 var may = function(o,f) {return f ? f.bind(o) : function() {}};
6662 $.extend(true, $[deck].defaults, {
6664 animShow: ".anim-show",
6665 animHide: ".anim-hide",
6666 animAddClass: ".anim-addclass",
6667 animRemoveClass: ".anim-removeclass",
6668 animAttribute: ".anim-attribute",
6669 animWait: ".anim-wait",
6671 animPlay: ".anim-play",
6672 animPause: ".anim-pause",
6673 animViewboxAs: ".anim-viewboxas",
6674 animAlong: ".anim-along",
6676 animContinue: ".anim-continue"
6679 animReady: "deck-anim-ready"
6686 var doInit = function() {
6687 // first we define some tools and grab some info from deck.js
6688 var o = $[deck]('getOptions');
6689 var context = function(el) {
6691 what: function() {return $(el).attr("data-what")},
6692 dur: function() {return $(el).attr("data-dur")*1 || o.anim.duration},
6693 delay: function() {return $(el).attr("data-delay")*1 || 0},
6694 classs: function() {return $(el).attr("data-class")},
6695 attribute: function() {return $(el).attr("data-attr").split(':')[0]},
6696 as: function() {return $(el).attr("data-as")},
6697 path: function() {return $(el).attr("data-path")},
6698 reverse: function() {var r = $(el).attr("data-reverse"); return r && r.toUpperCase() == "TRUE";},
6699 value: function() {return $(el).attr("data-attr").split(':')[1]},
6700 toplevel: function() {return $[deck]('getToplevelSlideOf', el).node},
6701 all: function() {return $(this.what(),this.toplevel())}
6704 var globalHasAnimContinue = false;
6705 var classical = function(selector, methods) {
6706 $(selector).each(function(i, el) {
6707 var c = context(el);
6708 may(methods, methods.create)(c);
6709 $(el).bind('deck.toplevelBecameCurrent', function(_, direction) {
6710 may(methods, methods.init)(c);
6711 }).bind('deck.afterToplevelBecameCurrent', function(_, direction) {
6712 may(methods, methods.fast)(c);
6713 }).bind('deck.lostCurrent', function(_, direction, from, to) {
6714 if (direction == 'forward' || Math.abs(from - to)>1 ) return; // if a big step, let the "step" extension do its job
6715 may(methods, methods.undo)(c);
6716 }).bind('deck.becameCurrent', function(_, direction, from, to) {
6717 if (direction == 'reverse' || Math.abs(from - to)>1 ) return; // if a big step, let the "step" extension do its job
6719 setTimeout(function() {
6720 may(methods, methods.doit)(c);
6723 may(methods, methods.doit)(c);
6729 // here come the real animations
6730 classical(o.selectors.animShow, {
6731 init: function(c) {c.all().animate({'opacity': 0.}, 0)},
6732 undo: function(c) {c.all().animate({'opacity': 0.}, c.dur()/100)},
6733 doit: function(c) {c.all().animate({'opacity': 1.}, c.dur())},
6734 fast: function(c) {c.all().animate({'opacity': 1.}, 0)}
6736 classical(o.selectors.animHide, {
6737 init: function(c) {c.all().animate({'opacity': 1.}, 0)},
6738 undo: function(c) {c.all().animate({'opacity': 1.}, c.dur()/100)},
6739 doit: function(c) {c.all().animate({'opacity': 0.}, c.dur())},
6740 fast: function(c) {c.all().animate({'opacity': 0.}, 0)}
6742 classical(o.selectors.animAddClass, {
6743 init: function(c) {c.all().removeClass(c.classs())},
6744 undo: function(c) {c.all().removeClass(c.classs())},
6745 doit: function(c) {c.all().addClass(c.classs())},
6746 fast: function(c) {c.all().addClass(c.classs())}
6748 classical(o.selectors.animRemoveClass, {
6749 init: function(c) {c.all().addClass(c.classs())},
6750 undo: function(c) {c.all().addClass(c.classs())},
6751 doit: function(c) {c.all().removeClass(c.classs())},
6752 fast: function(c) {c.all().removeClass(c.classs())}
6754 function svgRealAttrName(a) {
6755 if (startsWith(a, "svg")) {
6756 return REST.substr(0, 1).toLowerCase() + REST.slice(1);
6760 function startsWith(longStr, part) {
6761 var res = longStr.substr(0, part.length) == part;
6762 REST = res ? longStr.slice(part.length) : null;
6765 classical(o.selectors.animAttribute, {
6770 // TODO: [feature] could allow multiple attributes to be passed and animated simultaneously
6771 var k = c.attribute()
6772 for (i in c.previousElement) { // use the saved list of elements and values
6774 whatTo[k] = c.previousCss[i];
6775 $(c.previousElement[i]).finish();
6776 if (c.previousElement[i] instanceof SVGElement) {
6777 if (whatTo[k] != null) {
6778 var realAttrName = svgRealAttrName(k) || k;
6779 c.previousElement[i].attributes.getNamedItem(realAttrName).value = whatTo[k];
6781 var realAttrName = svgRealAttrName(k) || k;
6782 c.previousElement[i].attributes.removeNamedItem(realAttrName);
6785 $(c.previousElement[i]).animate(whatTo, 0);
6789 doit: function(c, factor) {
6790 if (factor === undefined) factor = 1
6791 c.all().each( function() {
6792 // finish all previous animations
6793 if (!globalHasAnimContinue && $(this).queue().length) {
6797 var k = c.attribute()
6799 c.previousElement = []
6800 c.all().each( function(){
6801 c.previousElement.push(this);
6802 var v = $(this).css(k);
6803 if (v == null && this instanceof SVGElement) {
6804 var realAttrName = svgRealAttrName(k) || k;
6805 var attr = this.attributes.getNamedItem(realAttrName);
6806 c.previousCss.push(attr ? attr.value : null);
6808 c.previousCss.push(v);
6810 }); // save a list of elements and values
6812 whatTo[c.attribute()] = c.value()
6813 c.all().animate(whatTo, c.dur()*factor)
6815 fast: function(c) {this.doit(c,0)}
6817 classical(o.selectors.animViewboxAs, {
6818 create: function(c) {
6819 c.attribute = function() {return "svgViewBox"};
6820 c.value = function() {
6821 var asWhat = $(c.as());
6822 var a = function (i) {return asWhat.attr(i)}
6823 var toViewBox = a('x')+" "+a('y')+" "+a('width')+" "+a('height');
6827 init: function(c) {this.undo(c)},
6829 var k = c.attribute()
6830 for (i in c.previousElement) { // use the saved list of elements and values
6832 whatTo[k] = c.previousValue[i]
6833 $(c.previousElement[i]).finish();
6834 $(c.previousElement[i]).animate(whatTo, 0)
6837 doit: function(c, factor) {
6838 if (factor === undefined) factor = 1
6839 c.all().each( function() {
6840 // finish all previous animations
6841 if (!globalHasAnimContinue && $(this).queue().length) {
6845 var k = c.attribute()
6846 c.previousValue = []
6847 c.previousElement = []
6848 c.all().each( function() {
6849 c.previousElement.push(this);
6850 c.previousValue.push(this.attributes.getNamedItem('viewBox').value);
6851 }); // save a list of elements and values
6853 whatTo[k] = c.value()
6854 c.all().animate(whatTo, c.dur()*factor)
6856 fast: function(c) {this.doit(c,0)}
6858 classical(o.selectors.animAlong, {
6859 init: function(c) {this.undo(c)},
6861 for (i in c.previousElement) { // use the saved list of elements and values
6862 var prev = c.previousValue[i];
6863 $(c.previousElement[i]).finish();
6864 $(c.previousElement[i]).attr("transform", prev);
6867 doit: function(c, factor) {
6868 if (factor === undefined) factor = 1;
6869 c.all().each( function() {
6870 // finish all previous animations
6871 if (!globalHasAnimContinue && $(this).queue().length) {
6875 var path = $(c.path()).get(0);
6876 var rev = c.reverse();
6877 var len = path.getTotalLength()
6878 var s = path.getPointAtLength(rev?len:0);
6879 c.previousValue = [];
6880 c.previousElement = [];
6881 c.all().each( function() {
6883 if ($(this).attr("transform") != null) {
6884 base = $(this).attr("transform"); // TODO maybe can use attr also above (anim-attr)
6885 c.previousValue.push(base);
6887 c.previousValue.push(null);
6889 c.previousElement.push(this);
6890 $(this).css({svgDeckAnim: 0.});
6891 $(this).animate({svgDeckAnim: 1.}, {
6892 duration: c.dur()*factor,
6895 var p = path.getPointAtLength(v * len);
6896 $(this).attr("transform", 'translate('+(p.x-s.x)+','+(p.y-s.y)+')' + base);
6901 fast: function(c) {this.doit(c, 0);}
6903 classical(o.selectors.animPlay, {
6904 init: function(c) {c.all().each(function(){this.pause(); try{this.currentTime=0}catch(e){} })},
6905 undo: function(c) {c.all().each(function(){this.pause()})},
6906 doit: function(c) {c.all().each(function(){this.play()})},
6907 fast: function(c) {c.all().each(function(){this.play()})}
6909 classical(o.selectors.animPause, {
6910 undo: function(c) {c.all().each(function(){this.play()})},
6911 doit: function(c) {c.all().each(function(){this.pause()})},
6912 fast: function(c) {c.all().each(function(){this.pause()})}
6914 classical(o.selectors.animContinue, {
6915 doit: function(c) {setTimeout(function(){ globalHasAnimContinue = true; $[deck]('next') ; globalHasAnimContinue = false; }, 1)}
6916 // do not do it in fast mode
6918 classical(o.selectors.animWait, {
6919 doit: function(c) {setTimeout(function(){ globalHasAnimContinue = true; $[deck]('next') ; globalHasAnimContinue = false; }, c.dur())}
6921 // handle the chained undo for "anim-continue"
6922 $(o.selectors.animContinue + "," + o.selectors.animWait).each(function(i, curSlide) {
6923 $(curSlide).bind('deck.becameCurrent', function(_, direction) {
6924 if (direction == 'forward') return;
6925 setTimeout(function(){$[deck]('prev')}, 1)
6930 // finally force "refresh" (notification of slide change)
6931 var current = $[deck]('getSlide')
6933 for (; icur < $[deck]('getSlides').length; icur++) {
6934 if ($[deck]('getSlides')[icur] == current) break;
6936 $d.trigger("deck.change", [icur, 0]);
6937 $d.trigger("deck.change", [0, icur]);
6939 var container = $[deck]('getContainer');
6940 $(container).addClass(o.classes.animReady)
6942 $(document).bind('deck.init', function() {
6949 (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,"&").replace(/</g,"<").replace(/>/g,">"))}}}}}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);
6950 (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);
6953 Copyright (c) 2012-2014 RĂ©mi Emonet, as a major refactor from an early version from RĂ©mi Barraquand.
6954 Licensed under the MIT license.
6955 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6959 This module provides a support for managed svg inclusion (allowing proper DOM access subsequently for animations, etc.).
6962 (function($, deck, undefined) {
6963 var $d = $(document);
6964 var may = function(f) {return f ? f : function() {}};
6966 $.extend(true, $[deck].defaults, {
6968 svgPlaceholder: 'deck-svg'
6971 svgObject: "object[type='deckjs/svg'], div.svg-object",
6973 idrewrite: ".no-idrewrite",
6974 stylerewrite: ".no-stylerewrite"
6982 function walk(node, fn) {
6984 if (node.nodeType === 1) {
6986 walk(node.firstChild, fn);
6988 } while (node = node.nextSibling);
6991 styleToAttributes: function(root, svgfile) {
6992 walk(root, function() {
6994 if ($n.attr("style")) {
6995 $($n.attr("style").trim().split(/ *; */)).each(function(index, style) {
6996 if (style && style.substring(0,1) != "-") {
6997 var s = style.trim().split(/ *: */);
6998 $n.attr(s[0], s[1]);
7002 $n.attr("style", null);
7005 referencingAttributes: ["clip-path", "color-profile", "fill", "filter", "marker-start", "marker-mid", "marker-end", "mask", "stroke"],
7007 generateId: function(oldId) {
7008 var id = "uniquesvg"+svgPatcher.nextId;
7009 svgPatcher.nextId++;
7012 makeReferencedIdsUnique: function(root, svgfile, continuation) {
7013 var andThen = continuation || function(){}
7015 var referencersIds = {};
7016 var pushAdd = function(k, o) {
7017 if (referencersIds[k]) {
7018 referencersIds[k].push(o);
7020 referencersIds[k] = [ o ];
7023 // gather all ids and references
7024 walk(root, function() {
7031 $(svgPatcher.referencingAttributes).each(function(i,attr) {
7032 var val = $n.attr(attr);
7034 var groups = val.trim().match(/^url\(#(.+?)\)$/)
7035 if (groups) pushAdd(groups[1], {o:that, a:attr})
7038 var xlink = $n.attr("xlink:href");
7040 var groups = xlink.trim().match(/^#(.+?)$/)
7041 if (groups) pushAdd(groups[1], {o:that, a:"xlink:href"})
7044 // 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))
7046 for (id in referencersIds) {
7047 var newId = svgPatcher.generateId(id);
7048 byId[id].id = newId;
7052 setTimeout( // to help firefox in having updated ids
7054 for (id in referencersIds) {
7055 var newId = newIds[id];
7056 var refs = referencersIds[id];
7057 $(refs).each(function(i,pair){
7058 var prev = $(pair.o).attr(pair.a);
7059 if (pair.a == "xlink:href") {
7060 pair.o.setAttributeNS($.svg.xlinkNS, "href", prev.replace("#" + id, "#" + newId));
7062 $(pair.o).attr(pair.a, prev.replace("#" + id, "#" + newId));
7073 $d.bind('deck.beforeInit', function (event) {
7075 var opts = $[deck]('getOptions');
7076 var container = $[deck]('getContainer');
7079 Load parameters from an Object element
7081 var loadObjectParams = function(objectElement) {
7082 var attributes = {};
7083 $(objectElement).children("param").each(function(index){
7084 attributes[$(this).attr("name")] = $(this).attr("value");
7086 $.each(objectElement.attributes, function (index, attr) {
7087 if ("data-" == attr.name.substr(0, 5)) {
7088 attributes[attr.name.substr(5)] = attr.value;
7095 Return true if default params are set.
7097 var validateParams = function(params) {
7098 return params['src'];// && params['width'] && params['height'];// && params['animator'];
7102 Create SVG placeholder
7104 var createSVG = function(object, attributes) {
7105 var $canvas, $control, $next, $reload, $placeholder;
7106 /* Create svg canvas */
7107 $canvas = $("<div />").attr({
7108 'id': $(object).attr('id'),
7109 'data-src': attributes['src'],
7110 'class': opts.classes.svgPlaceholder + " " + $(object).attr('class')
7112 'height': attributes['height'],
7113 'width': attributes['width']
7119 /* Go through all toplevel slides */
7120 $($[deck]('getTopLevelSlides')).each( function(i, $slide) {
7122 /* Find all the object of type deckjs/svg */
7123 $slide.find(opts.selectors.svgObject).each(function(index, obj) {
7124 /* Load attributes and validate them */
7125 var attributes = loadObjectParams(obj);
7126 if (!validateParams(attributes) ) {
7127 throw "Error while initializing "+$(obj).attr('id')+", please ensure you have setup the required parameters."
7131 /* Create SVG placeholder */
7132 var SVG = createSVG(obj, attributes);
7133 $(obj).replaceWith(SVG);
7135 // Finaly load the SVG data
7138 var notDisabled = function(k) {
7140 var disabled = (attributes[kk] && attributes[kk] == "true") || $(obj).filter(opts.selectors.svgObjectDisable[k]).length > 0
7145 loadURL: attributes['src'],
7146 onLoad: function($svg, w, h) {
7147 var px = function (str) {return str.replace("px", "")}
7148 var aa = $($svg.root());
7149 aa.attr('width', '100%');
7150 aa.attr('height', '100%');
7151 if (aa.attr('viewBox') == undefined) {
7152 if (w==undefined || h==undefined) {
7153 if (opts.alert.missingSVG) alert(
7154 "There seem to be a problem with the loading of\n '"+attributes['src'] + "'\n"
7155 +"\nMaybe the file does not exist?"
7157 +"\n - it has no w or h attribute?"
7158 +"\n - you're using a file that is within a symbolic-link folder?"
7159 +"\n - you're using chrome with local files?"
7160 +"\n ⇒ try to restart chrome with '--disable-web-security'");
7161 event.releaseInit();
7163 var to = "0 0 " + px(w) + " " + px(h);
7164 $svg.root().setAttribute("viewBox", to);
7165 aa.attr("svgViewBox", to);
7166 if (attributes['stretch'] == 'true') $svg.root().setAttribute('preserveAspectRatio', "none");
7167 if (notDisabled('stylerewrite')) {
7168 svgPatcher.styleToAttributes($svg.root(), attributes['src']);
7170 if (notDisabled('idrewrite')) {
7171 svgPatcher.makeReferencedIdsUnique($svg.root(), attributes['src'], function() {
7172 event.releaseInit();
7175 event.releaseInit();
7183 event.releaseInit();
7191 Deck JS - deck.metadata
7192 Copyright (c) 2014 RĂ©mi Emonet
7193 Licensed under the MIT license.
7194 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7198 This module automatically takes each meta tag (e.g., author, date, ...) and the page title.
7199 It then replaces the content of all elements having a var-... class by the value of the metadata.
7201 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).
7204 (function($, deck, undefined) {
7205 $.extend(true, $.deck.defaults, {
7207 metadataPrefix: '.var-',
7208 metadataBrSuffix: '-br',
7209 metadataFullSuffix: '-full'
7211 metadataSeparator: /( |Â )/gi /* we need to handle ' ' and 'Â ' because in the title, 'Â ' becomes ' ' */
7214 var $d = $(document);
7215 $d.bind('deck.init', function() {
7216 var o = $.deck('getOptions');
7217 var app = function(_sel, v) {
7218 var sel = o.selectors.metadataPrefix + _sel;
7219 var sep = o.metadataSeparator;
7220 $(sel).html(v.replace(sep, ""));
7221 $(sel+o.selectors.metadataFullSuffix).html(v);
7222 $(sel+o.selectors.metadataBrSuffix).html(v.replace(sep, "<br/>"));
7224 app("title", $("html>head>title").html());
7225 $("html>head>meta[name]").each(function(i,e) {
7226 app($(e).attr('name'), $(e).attr('content'))
7232 Deck JS - deck.attribution
7233 Copyright (c) 2014 RĂ©mi Emonet
7234 Licensed under the MIT license.
7235 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7239 This module automatically adds some text and a link for elements having a "data-attribution" attributes.
7242 (function($, deck, undefined) {
7243 $.extend(true, $.deck.defaults, {
7245 attributionWrapper: 'attribution-wrap',
7246 attributionLink: 'attribution-link'
7248 dataAttribution: "data-attribution",
7249 dataAttributionContent: "data-attribution-content",
7250 dataAttributionClass: "data-attribution-class"
7253 var $d = $(document);
7254 $d.bind('deck.init', function() {
7255 var o = $.deck('getOptions');
7256 $('*['+o.dataAttribution+']').each(function(i, el){
7257 var c = $(el).attr(o.dataAttributionContent);
7258 var cc = $(el).attr(o.dataAttributionClass);
7259 var a = $(el).attr(o.dataAttribution);
7261 w.addClass(o.classes.attributionWrapper);
7262 var link = $("<a>");
7263 link.addClass(o.classes.attributionLink);
7264 if (!! cc) link.addClass(cc);
7265 link.attr("href", a);
7266 link.attr("target", "_blank");
7279 Deck JS - deck.container-styling
7280 Copyright (c) 2014 RĂ©mi Emonet
7281 Licensed under the MIT license.
7282 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7286 This module automatically adds/removes to the container the class specified in data-container-class (for toplevel slides).
7288 This extension relies on the events extension.
7291 (function($, deck, undefined) {
7292 var $d = $(document);
7293 $d.bind('deck.init', function() {
7294 $('*[data-container-class]').each(function(i, el) {
7295 var toRemove = ""; // one 'toRemove' per element (that's why we do .each
7296 $(el).bind('deck.becameCurrent', function(_, direction) {
7297 var target = $(_.target);
7298 var toAdd = target.attr('data-container-class');
7299 $[deck]('getContainer').addClass(toAdd);
7301 }).bind('deck.lostCurrent', function(_, direction) {
7302 $[deck]('getContainer').removeClass(toRemove);
7307 $(document).bind('deck.init', function() { // force trigger even if no #slide-... is provided
7308 var current = $[deck]('getSlide')
7310 for (; icur < $[deck]('getSlides').length; icur++) {
7311 if ($[deck]('getSlides')[icur] == current) break;
7313 $(document).trigger("deck.change", [icur, icur]);
7318 Deck JS - deck.timekeeper
7319 Copyright (c) 2013-2014 RĂ©mi Emonet
7320 Licensed under the MIT license.
7321 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7325 This module provides a support for displaying current time, time from start and logging the time spent on each slide etc.
7326 It also injects some default html for it if none is found (and styles it for the presenter/clone view).
7329 (function($, deck, undefined) {
7330 var $d = $(document);
7332 $.extend(true, $[deck].defaults, {
7334 timekeeper: ".timekeeper", /* inject if this is not present */ // TODO inject
7335 timekeeperTime: ".timekeeper-time",
7336 timekeeperRelativeTime: ".timekeeper-relative-time",
7337 timekeeperLocalRelativeTime: ".timekeeper-local-relative-time",
7338 timekeeperLogs: ".timekeeper-logs",
7339 timekeeperLogsPre: ".timekeeper-logs pre",
7340 timekeeperLogsToggle: ".timekeeper-logs-toggle",
7341 timekeeperBang: ".timekeeper-bang",
7342 timekeeperClear: ".timekeeper-clear"
7345 timekeeperNotification: "timekeeper-notification",
7346 timekeeperLogsVisible: "timekeeper-logs-visible"
7352 localStorageUnsupported: true
7355 timekeeperArchivesMaxSize: 500*1000,
7356 timekeeperArchives: 'deckjs-timekeeper-archives',
7357 timekeeperLogs: 'deckjs-timekeeper-logs',
7358 timekeeperBase: 'deckjs-timekeeper-base',
7359 timekeeperLocalBase: 'deckjs-timekeeper-local-base'
7361 timekeeperPeriod: 1000,
7362 timekeeperNotificationPeriod: 100,
7364 timekeeper: [27, 75] // escape, k (combine with SHIFT to reset the counter (when starting presenting))
7368 $d.bind('deck.init', function() {
7369 var opts = $[deck]('getOptions');
7370 var container = $[deck]('getContainer');
7372 // sligthly edited from
7373 var selectText = function(text) {
7377 if (doc.body.createTextRange) { //ms
7378 range = doc.body.createTextRange();
7379 range.moveToElementText(text);
7381 } else if (window.getSelection) { //all others
7382 selection = window.getSelection();
7383 range = doc.createRange();
7384 range.selectNodeContents(text);
7385 selection.removeAllRanges();
7386 selection.addRange(range);
7390 if (opts.snippets.timekeeper) {
7391 var d = function() {return $('<div/>');}
7392 var divTK = d().addClass("timekeeper timekeeper-logs-toggle");
7393 divTK.append(d().addClass("timekeeper-local-relative-time"));
7394 divTK.append(d().addClass("timekeeper-time"));
7395 divTK.append(d().addClass("timekeeper-relative-time"));
7396 divTK.append(d().addClass("timekeeper-clear"));
7397 divTK.append(d().addClass("timekeeper-bang"));
7398 divTK.appendTo(container);
7399 var divLog = d().addClass("timekeeper-logs");
7400 var pre = $('<pre/>').appendTo(divLog);
7401 divLog.append(d().addClass("button").click(function() { doBang() }).html("Bang!"));
7402 divLog.append(d().addClass("button").click(function() { selectText(pre.get(0)) }).html("select all"));
7403 divLog.append(d().addClass("button").click(function() { clearStorage() }).html("Clear").css({color:'#f44', marginLeft: '2em'}));
7404 divLog.append(d().addClass("button").addClass("timekeeper-logs-toggle").css({position:'float', float:'right', color:'#0f0'}).html("X"));
7405 divLog.appendTo(container);
7408 if (!window.localStorage && opts.alert.localStorageUnsupported) { alert(
7409 "LocalStorage is unsupported in your browser, timing features are disabled (timekeeper extension).");
7413 var pad = function(base, right) {
7415 if (s.length >= base.length) return s;
7416 else return base.substring(0, base.length - s.length) + s
7418 var formatTime = function(t) {
7419 var min = parseInt(t / 1000 / 60);
7420 var sec = parseInt(t / 1000 - 60 * min);
7422 var hours = parseInt(t / 1000 / 60 / 60);
7423 min = parseInt(t / 1000 / 60 - 60 * hours);
7424 return pad("00", hours) +":"+ pad("00", min) + ":" + pad("00", sec)
7426 return pad("00", min) + ":" + pad("00", sec)
7429 var clearStorage = function(what) {
7431 localStorage.setItem(opts.localStorage.timekeeperLogs, null);
7432 log("CLEARED BY USER");
7433 localStorage.setItem(opts.localStorage.timekeeperBase, JSON.stringify(new Date()));
7434 $(opts.selectors.timekeeperClear).addClass(opts.classes.timekeeperNotification);
7435 setTimeout(function() {
7436 $(opts.selectors.timekeeperClear).removeClass(opts.classes.timekeeperNotification);
7437 }, opts.timekeeperNotificationPeriod);
7439 var reset = function() {
7440 localStorage.setItem(opts.localStorage.timekeeperLocalBase, JSON.stringify(new Date()));
7442 var getDateOrSet = function(k, or) {
7443 var res = localStorage.getItem(k);
7445 res = JSON.stringify(or);
7446 localStorage.setItem(k, res);
7448 res = new Date(JSON.parse(res));
7452 var log = function(what) {
7453 var now = new Date();
7454 var time = now.toString()
7455 var localBase = getDateOrSet(opts.localStorage.timekeeperLocalBase, now);
7456 var base = getDateOrSet(opts.localStorage.timekeeperBase, now);
7457 var db = (now - localBase)/1000;
7458 var dcb = (now - base)/1000;
7459 var dbtime = formatTime(now - localBase);
7460 var dcbtime = formatTime(now - base);
7461 var log = time.replace(/GMT.*/, "") + " " + what + " " + dcb + " " + db + " " + dcbtime + " " + dbtime;
7463 var data = localStorage.getItem(opts.localStorage.timekeeperLogs);
7464 data = log + "\n" + data;
7465 localStorage.setItem(opts.localStorage.timekeeperLogs, data);
7466 $(opts.selectors.timekeeperLogsPre).html(data);
7470 var saveCurrent = -1;
7471 $(document).bind('deck.change', function(e, from, to) {
7472 log(from + " " + to);
7476 // Bind key event to add a marker in the logs
7477 var $d = $(document);
7478 var doBang = function() {
7479 log("BANG " + saveCurrent);
7480 $(opts.selectors.timekeeperBang).addClass(opts.classes.timekeeperNotification);
7481 setTimeout(function() {
7482 $(opts.selectors.timekeeperBang).removeClass(opts.classes.timekeeperNotification);
7483 }, opts.timekeeperNotificationPeriod);
7486 $d.unbind('keydown.logbang').bind('keydown.logbang', function(e) {
7487 if (e.ctrlKey) return;
7488 var K = opts.keys.timekeeper;
7489 if (e.which === K || $.inArray(e.which, K) > -1) {
7496 $(opts.selectors.timekeeperLogsToggle).unbind('click.timekeeper').bind('click.timekeeper', function(e) {
7497 $(opts.selectors.timekeeperLogs).toggleClass(opts.classes.timekeeperLogsVisible);
7502 var period = opts.timekeeperPeriod;
7503 setInterval(function() {
7504 var today = new Date();
7505 today.setMinutes(0);
7507 today.setSeconds(0);
7508 var now = new Date();
7509 $(opts.selectors.timekeeperTime).html(formatTime(now - today));
7510 var v = localStorage.getItem(opts.localStorage.timekeeperBase);
7512 var t = now - new Date(JSON.parse(v));
7513 var time = formatTime(t);
7514 $(opts.selectors.timekeeperRelativeTime).html(time);
7516 var v2 = localStorage.getItem(opts.localStorage.timekeeperLocalBase);
7518 var t = now - new Date(JSON.parse(v2));
7519 var time = formatTime(t);
7520 $(opts.selectors.timekeeperLocalRelativeTime).html(time);
7529 (function(global, document) {
7531 // Popcorn.js does not support archaic browsers
7532 if ( !document.addEventListener ) {
7537 var methods = ( "byId forEach extend effects error guid sizeOf isArray nop position disable enable destroy" +
7538 "addTrackEvent removeTrackEvent getTrackEvents getTrackEvent getLastTrackEventId " +
7539 "timeUpdate plugin removePlugin compose effect xhr getJSONP getScript" ).split(/\s+/);
7541 while ( methods.length ) {
7542 global.Popcorn[ methods.shift() ] = function() {};
7549 AP = Array.prototype,
7550 OP = Object.prototype,
7552 forEach = AP.forEach,
7554 hasOwn = OP.hasOwnProperty,
7555 toString = OP.toString,
7557 // Copy global Popcorn (may not exist)
7558 _Popcorn = global.Popcorn,
7565 // Non-public internal data object
7573 // Non-public `requestAnimFrame`
7574 // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
7575 requestAnimFrame = (function(){
7576 return global.requestAnimationFrame ||
7577 global.webkitRequestAnimationFrame ||
7578 global.mozRequestAnimationFrame ||
7579 global.oRequestAnimationFrame ||
7580 global.msRequestAnimationFrame ||
7581 function( callback, element ) {
7582 global.setTimeout( callback, 16 );
7586 // Non-public `getKeys`, return an object's keys as an array
7587 getKeys = function( obj ) {
7588 return Object.keys ? Object.keys( obj ) : (function( obj ) {
7592 for ( item in obj ) {
7593 if ( hasOwn.call( obj, item ) ) {
7602 // [[Put]] props from dictionary onto |this|
7603 // MUST BE CALLED FROM WITHIN A CONSTRUCTOR:
7604 // Abstract.put.call( this, dictionary );
7605 put: function( dictionary ) {
7606 // For each own property of src, let key be the property key
7607 // and desc be the property descriptor of the property.
7608 Object.getOwnPropertyNames( dictionary ).forEach(function( key ) {
7609 this[ key ] = dictionary[ key ];
7615 // Declare constructor
7616 // Returns an instance object.
7617 Popcorn = function( entity, options ) {
7618 // Return new Popcorn object
7619 return new Popcorn.p.init( entity, options || null );
7622 // Popcorn API version, automatically inserted via build system.
7623 Popcorn.version = "@VERSION";
7625 // Boolean flag allowing a client to determine if Popcorn can be supported
7626 Popcorn.isSupported = true;
7629 Popcorn.instances = [];
7631 // Declare a shortcut (Popcorn.p) to and a definition of
7632 // the new prototype for our Popcorn constructor
7633 Popcorn.p = Popcorn.prototype = {
7635 init: function( entity, options ) {
7637 var matches, nodeName,
7640 // Supports Popcorn(function () { /../ })
7641 // Originally proposed by Daniel Brooks
7643 if ( typeof entity === "function" ) {
7645 // If document ready has already fired
7646 if ( document.readyState === "complete" ) {
7648 entity( document, Popcorn );
7652 // Add `entity` fn to ready stack
7653 readyStack.push( entity );
7655 // This process should happen once per page load
7656 if ( !readyBound ) {
7658 // set readyBound flag
7661 var DOMContentLoaded = function() {
7665 // Remove global DOM ready listener
7666 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
7668 // Execute all ready function in the stack
7669 for ( var i = 0, readyStackLength = readyStack.length; i < readyStackLength; i++ ) {
7671 readyStack[ i ].call( document, Popcorn );
7678 // Register global DOM ready listener
7679 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
7685 if ( typeof entity === "string" ) {
7687 matches = document.querySelector( entity );
7689 throw new Error( "Popcorn.js Error: Invalid media element selector: " + entity );
7693 // Get media element by id or object reference
7694 this.media = matches || entity;
7696 // inner reference to this media element's nodeName string value
7697 nodeName = ( this.media.nodeName && this.media.nodeName.toLowerCase() ) || "video";
7699 // Create an audio or video element property reference
7700 this[ nodeName ] = this.media;
7702 this.options = Popcorn.extend( {}, options ) || {};
7704 // Resolve custom ID or default prefixed ID
7705 this.id = this.options.id || Popcorn.guid( nodeName );
7707 // Throw if an attempt is made to use an ID that already exists
7708 if ( Popcorn.byId( this.id ) ) {
7709 throw new Error( "Popcorn.js Error: Cannot use duplicate ID (" + this.id + ")" );
7712 this.isDestroyed = false;
7716 // data structure of all
7721 // Executed by either timeupdate event or in rAF loop
7722 timeUpdate: Popcorn.nop,
7724 // Allows disabling a plugin per instance
7727 // Stores DOM event queues by type
7730 // Stores Special event hooks data
7733 // Store track event history data
7736 // Stores ad-hoc state related data]
7738 volume: this.media.volume
7741 // Store track event object references by trackId
7744 // Playback track event queues
7745 trackEvents: new TrackEvents( this )
7748 // Register new instance
7749 Popcorn.instances.push( this );
7751 // function to fire when video is ready
7752 var isReady = function() {
7754 // chrome bug: http://code.google.com/p/chromium/issues/detail?id=119598
7755 // it is possible the video's time is less than 0
7756 // this has the potential to call track events more than once, when they should not
7757 // start: 0, end: 1 will start, end, start again, when it should just start
7758 // just setting it to 0 if it is below 0 fixes this issue
7759 if ( self.media.currentTime < 0 ) {
7761 self.media.currentTime = 0;
7764 self.media.removeEventListener( "loadedmetadata", isReady, false );
7766 var duration, videoDurationPlus,
7767 runningPlugins, runningPlugin, rpLength, rpNatives;
7769 // Adding padding to the front and end of the arrays
7770 // this is so we do not fall off either end
7771 duration = self.media.duration;
7773 // Check for no duration info (NaN)
7774 videoDurationPlus = duration != duration ? Number.MAX_VALUE : duration + 1;
7776 Popcorn.addTrackEvent( self, {
7777 start: videoDurationPlus,
7778 end: videoDurationPlus
7781 if ( !self.isDestroyed ) {
7782 self.data.durationChange = function() {
7783 var newDuration = self.media.duration,
7784 newDurationPlus = newDuration + 1,
7785 byStart = self.data.trackEvents.byStart,
7786 byEnd = self.data.trackEvents.byEnd;
7788 // Remove old padding events
7792 // Remove any internal tracking of events that have end times greater than duration
7793 // otherwise their end events will never be hit.
7794 for ( var k = byEnd.length - 1; k > 0; k-- ) {
7795 if ( byEnd[ k ].end > newDuration ) {
7796 self.removeTrackEvent( byEnd[ k ]._id );
7800 // Remove any internal tracking of events that have end times greater than duration
7801 // otherwise their end events will never be hit.
7802 for ( var i = 0; i < byStart.length; i++ ) {
7803 if ( byStart[ i ].end > newDuration ) {
7804 self.removeTrackEvent( byStart[ i ]._id );
7808 // References to byEnd/byStart are reset, so accessing it this way is
7810 self.data.trackEvents.byEnd.push({
7811 start: newDurationPlus,
7812 end: newDurationPlus
7815 self.data.trackEvents.byStart.push({
7816 start: newDurationPlus,
7817 end: newDurationPlus
7821 // Listen for duration changes and adjust internal tracking of event timings
7822 self.media.addEventListener( "durationchange", self.data.durationChange, false );
7825 if ( self.options.frameAnimation ) {
7827 // if Popcorn is created with frameAnimation option set to true,
7828 // requestAnimFrame is used instead of "timeupdate" media event.
7829 // This is for greater frame time accuracy, theoretically up to
7830 // 60 frames per second as opposed to ~4 ( ~every 15-250ms)
7831 self.data.timeUpdate = function () {
7833 Popcorn.timeUpdate( self, {} );
7835 // fire frame for each enabled active plugin of every type
7836 Popcorn.forEach( Popcorn.manifest, function( key, val ) {
7838 runningPlugins = self.data.running[ val ];
7840 // ensure there are running plugins on this type on this instance
7841 if ( runningPlugins ) {
7843 rpLength = runningPlugins.length;
7844 for ( var i = 0; i < rpLength; i++ ) {
7846 runningPlugin = runningPlugins[ i ];
7847 rpNatives = runningPlugin._natives;
7848 rpNatives && rpNatives.frame &&
7849 rpNatives.frame.call( self, {}, runningPlugin, self.currentTime() );
7854 self.emit( "timeupdate" );
7856 !self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
7859 !self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
7863 self.data.timeUpdate = function( event ) {
7864 Popcorn.timeUpdate( self, event );
7867 if ( !self.isDestroyed ) {
7868 self.media.addEventListener( "timeupdate", self.data.timeUpdate, false );
7873 Object.defineProperty( this, "error", {
7876 return self.media.error;
7880 // http://www.whatwg.org/specs/web-apps/current-work/#dom-media-readystate
7882 // If media is in readyState (rS) >= 1, we know the media's duration,
7883 // which is required before running the isReady function.
7884 // If rS is 0, attach a listener for "loadedmetadata",
7885 // ( Which indicates that the media has moved from rS 0 to 1 )
7887 // This has been changed from a check for rS 2 because
7888 // in certain conditions, Firefox can enter this code after dropping
7889 // to rS 1 from a higher state such as 2 or 3. This caused a "loadeddata"
7890 // listener to be attached to the media object, an event that had
7891 // already triggered and would not trigger again. This left Popcorn with an
7892 // instance that could never start a timeUpdate loop.
7893 if ( self.media.readyState >= 1 ) {
7898 self.media.addEventListener( "loadedmetadata", isReady, false );
7905 // Extend constructor prototype to instance prototype
7906 // Allows chaining methods to instances
7907 Popcorn.p.init.prototype = Popcorn.p;
7909 Popcorn.byId = function( str ) {
7910 var instances = Popcorn.instances,
7911 length = instances.length,
7914 for ( ; i < length; i++ ) {
7915 if ( instances[ i ].id === str ) {
7916 return instances[ i ];
7923 Popcorn.forEach = function( obj, fn, context ) {
7925 if ( !obj || !fn ) {
7929 context = context || this;
7933 // Use native whenever possible
7934 if ( forEach && obj.forEach === forEach ) {
7935 return obj.forEach( fn, context );
7938 if ( toString.call( obj ) === "[object NodeList]" ) {
7939 for ( key = 0, len = obj.length; key < len; key++ ) {
7940 fn.call( context, obj[ key ], key, obj );
7945 for ( key in obj ) {
7946 if ( hasOwn.call( obj, key ) ) {
7947 fn.call( context, obj[ key ], key, obj );
7953 Popcorn.extend = function( obj ) {
7954 var dest = obj, src = slice.call( arguments, 1 );
7956 Popcorn.forEach( src, function( copy ) {
7957 for ( var prop in copy ) {
7958 dest[ prop ] = copy[ prop ];
7966 // A Few reusable utils, memoized onto Popcorn
7967 Popcorn.extend( Popcorn, {
7968 noConflict: function( deep ) {
7971 global.Popcorn = _Popcorn;
7976 error: function( msg ) {
7977 throw new Error( msg );
7979 guid: function( prefix ) {
7980 Popcorn.guid.counter++;
7981 return ( prefix ? prefix : "" ) + ( +new Date() + Popcorn.guid.counter );
7983 sizeOf: function( obj ) {
7986 for ( var prop in obj ) {
7992 isArray: Array.isArray || function( array ) {
7993 return toString.call( array ) === "[object Array]";
7998 position: function( elem ) {
8000 if ( !elem.parentNode ) {
8004 var clientRect = elem.getBoundingClientRect(),
8006 doc = elem.ownerDocument,
8007 docElem = document.documentElement,
8008 body = document.body,
8009 clientTop, clientLeft, scrollTop, scrollLeft, top, left;
8011 // Determine correct clientTop/Left
8012 clientTop = docElem.clientTop || body.clientTop || 0;
8013 clientLeft = docElem.clientLeft || body.clientLeft || 0;
8015 // Determine correct scrollTop/Left
8016 scrollTop = ( global.pageYOffset && docElem.scrollTop || body.scrollTop );
8017 scrollLeft = ( global.pageXOffset && docElem.scrollLeft || body.scrollLeft );
8020 top = Math.ceil( clientRect.top + scrollTop - clientTop );
8021 left = Math.ceil( clientRect.left + scrollLeft - clientLeft );
8023 for ( var p in clientRect ) {
8024 bounds[ p ] = Math.round( clientRect[ p ] );
8027 return Popcorn.extend({}, bounds, { top: top, left: left });
8030 disable: function( instance, plugin ) {
8032 if ( instance.data.disabled[ plugin ] ) {
8036 instance.data.disabled[ plugin ] = true;
8038 if ( plugin in Popcorn.registryByName &&
8039 instance.data.running[ plugin ] ) {
8041 for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) {
8043 event = instance.data.running[ plugin ][ i ];
8044 event._natives.end.call( instance, null, event );
8046 instance.emit( "trackend",
8047 Popcorn.extend({}, event, {
8057 enable: function( instance, plugin ) {
8059 if ( !instance.data.disabled[ plugin ] ) {
8063 instance.data.disabled[ plugin ] = false;
8065 if ( plugin in Popcorn.registryByName &&
8066 instance.data.running[ plugin ] ) {
8068 for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) {
8070 event = instance.data.running[ plugin ][ i ];
8071 event._natives.start.call( instance, null, event );
8073 instance.emit( "trackstart",
8074 Popcorn.extend({}, event, {
8085 destroy: function( instance ) {
8086 var events = instance.data.events,
8087 trackEvents = instance.data.trackEvents,
8088 singleEvent, item, fn, plugin;
8090 // Iterate through all events and remove them
8091 for ( item in events ) {
8092 singleEvent = events[ item ];
8093 for ( fn in singleEvent ) {
8094 delete singleEvent[ fn ];
8096 events[ item ] = null;
8099 // remove all plugins off the given instance
8100 for ( plugin in Popcorn.registryByName ) {
8101 Popcorn.removePlugin( instance, plugin );
8104 // Remove all data.trackEvents #1178
8105 trackEvents.byStart.length = 0;
8106 trackEvents.byEnd.length = 0;
8108 if ( !instance.isDestroyed ) {
8109 instance.data.timeUpdate && instance.media.removeEventListener( "timeupdate", instance.data.timeUpdate, false );
8110 instance.isDestroyed = true;
8113 Popcorn.instances.splice( Popcorn.instances.indexOf( instance ), 1 );
8117 // Memoized GUID Counter
8118 Popcorn.guid.counter = 1;
8120 // Factory to implement getters, setters and controllers
8121 // as Popcorn instance methods. The IIFE will create and return
8122 // an object with defined methods
8123 Popcorn.extend(Popcorn.p, (function() {
8125 var methods = "load play pause currentTime playbackRate volume duration preload playbackRate " +
8126 "autoplay loop controls muted buffered readyState seeking paused played seekable ended",
8130 // Build methods, store in object that is returned and passed to extend
8131 Popcorn.forEach( methods.split( /\s+/g ), function( name ) {
8133 ret[ name ] = function( arg ) {
8136 if ( typeof this.media[ name ] === "function" ) {
8138 // Support for shorthanded play(n)/pause(n) jump to currentTime
8139 // If arg is not null or undefined and called by one of the
8140 // allowed shorthandable methods, then set the currentTime
8141 // Supports time as seconds or SMPTE
8142 if ( arg != null && /play|pause/.test( name ) ) {
8143 this.media.currentTime = Popcorn.util.toSeconds( arg );
8146 this.media[ name ]();
8151 if ( arg != null ) {
8152 // Capture the current value of the attribute property
8153 previous = this.media[ name ];
8155 // Set the attribute property with the new value
8156 this.media[ name ] = arg;
8158 // If the new value is not the same as the old value
8159 // emit an "attrchanged event"
8160 if ( previous !== arg ) {
8161 this.emit( "attrchange", {
8163 previousValue: previous,
8170 return this.media[ name ];
8179 Popcorn.forEach( "enable disable".split(" "), function( method ) {
8180 Popcorn.p[ method ] = function( plugin ) {
8181 return Popcorn[ method ]( this, plugin );
8185 Popcorn.extend(Popcorn.p, {
8187 // Rounded currentTime
8188 roundTime: function() {
8189 return Math.round( this.media.currentTime );
8192 // Attach an event to a single point in time
8193 exec: function( id, time, fn ) {
8194 var length = arguments.length,
8195 eventType = "trackadded",
8196 trackEvent, sec, options;
8198 // Check if first could possibly be a SMPTE string
8199 // p.cue( "smpte string", fn );
8200 // try/catch avoid awful throw in Popcorn.util.toSeconds
8201 // TODO: Get rid of that, replace with NaN return?
8203 sec = Popcorn.util.toSeconds( id );
8206 // If it can be converted into a number then
8207 // it's safe to assume that the string was SMPTE
8208 if ( typeof sec === "number" ) {
8212 // Shift arguments based on use case
8215 // p.cue( time, fn );
8216 if ( typeof id === "number" && length === 2 ) {
8219 id = Popcorn.guid( "cue" );
8221 // Support for new forms
8223 // p.cue( "empty-cue" );
8224 if ( length === 1 ) {
8225 // Set a time for an empty cue. It's not important what
8226 // the time actually is, because the cue is a no-op
8231 // Get the TrackEvent that matches the given id.
8232 trackEvent = this.getTrackEvent( id );
8236 // remove existing cue so a new one can be added via trackEvents.add
8237 this.data.trackEvents.remove( id );
8238 TrackEvent.end( this, trackEvent );
8239 // Update track event references
8240 Popcorn.removeTrackEvent.ref( this, id );
8242 eventType = "cuechange";
8244 // p.cue( "my-id", 12 );
8245 // p.cue( "my-id", function() { ... });
8246 if ( typeof id === "string" && length === 2 ) {
8248 // p.cue( "my-id", 12 );
8249 // The path will update the cue time.
8250 if ( typeof time === "number" ) {
8251 // Re-use existing TrackEvent start callback
8252 fn = trackEvent._natives.start;
8255 // p.cue( "my-id", function() { ... });
8256 // The path will update the cue function
8257 if ( typeof time === "function" ) {
8259 // Re-use existing TrackEvent start time
8260 time = trackEvent.start;
8265 if ( length >= 2 ) {
8267 // p.cue( "a", "00:00:00");
8268 if ( typeof time === "string" ) {
8270 sec = Popcorn.util.toSeconds( time );
8276 // p.cue( "b", 11 );
8277 // p.cue( "b", 11, function() {} );
8278 if ( typeof time === "number" ) {
8279 fn = fn || Popcorn.nop();
8282 // p.cue( "c", function() {});
8283 if ( typeof time === "function" ) {
8298 start: fn || Popcorn.nop,
8305 options = Popcorn.extend( trackEvent, options );
8308 if ( eventType === "cuechange" ) {
8310 // Supports user defined track event id
8311 options._id = options.id || options._id || Popcorn.guid( options._natives.type );
8313 this.data.trackEvents.add( options );
8314 TrackEvent.start( this, options );
8316 this.timeUpdate( this, null, true );
8318 // Store references to user added trackevents in ref table
8319 Popcorn.addTrackEvent.ref( this, options );
8321 this.emit( eventType, Popcorn.extend({}, options, {
8325 time: trackEvent.start,
8326 fn: trackEvent._natives.start
8330 fn: fn || Popcorn.nop
8335 // Creating a one second track event with an empty end
8336 Popcorn.addTrackEvent( this, options );
8342 // Mute the calling media, optionally toggle
8343 mute: function( toggle ) {
8345 var event = toggle == null || toggle === true ? "muted" : "unmuted";
8347 // If `toggle` is explicitly `false`,
8348 // unmute the media and restore the volume level
8349 if ( event === "unmuted" ) {
8350 this.media.muted = false;
8351 this.media.volume = this.data.state.volume;
8354 // If `toggle` is either null or undefined,
8355 // save the current volume and mute the media element
8356 if ( event === "muted" ) {
8357 this.data.state.volume = this.media.volume;
8358 this.media.muted = true;
8361 // Trigger either muted|unmuted event
8367 // Convenience method, unmute the calling media
8368 unmute: function( toggle ) {
8370 return this.mute( toggle == null ? false : !toggle );
8373 // Get the client bounding box of an instance element
8374 position: function() {
8375 return Popcorn.position( this.media );
8378 // Toggle a plugin's playback behaviour (on or off) per instance
8379 toggle: function( plugin ) {
8380 return Popcorn[ this.data.disabled[ plugin ] ? "enable" : "disable" ]( this, plugin );
8383 // Set default values for plugin options objects per instance
8384 defaults: function( plugin, defaults ) {
8386 // If an array of default configurations is provided,
8387 // iterate and apply each to this instance
8388 if ( Popcorn.isArray( plugin ) ) {
8390 Popcorn.forEach( plugin, function( obj ) {
8391 for ( var name in obj ) {
8392 this.defaults( name, obj[ name ] );
8399 if ( !this.options.defaults ) {
8400 this.options.defaults = {};
8403 if ( !this.options.defaults[ plugin ] ) {
8404 this.options.defaults[ plugin ] = {};
8407 Popcorn.extend( this.options.defaults[ plugin ], defaults );
8414 UIEvents: "blur focus focusin focusout load resize scroll unload",
8415 MouseEvents: "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave click dblclick",
8416 Events: "loadstart progress suspend emptied stalled play pause error " +
8417 "loadedmetadata loadeddata waiting playing canplay canplaythrough " +
8418 "seeking seeked timeupdate ended ratechange durationchange volumechange"
8421 Popcorn.Events.Natives = Popcorn.Events.UIEvents + " " +
8422 Popcorn.Events.MouseEvents + " " +
8423 Popcorn.Events.Events;
8425 internal.events.apiTypes = [ "UIEvents", "MouseEvents", "Events" ];
8427 // Privately compile events table at load time
8428 (function( events, data ) {
8430 var apis = internal.events.apiTypes,
8431 eventsList = events.Natives.split( /\s+/g ),
8432 idx = 0, len = eventsList.length, prop;
8434 for( ; idx < len; idx++ ) {
8435 data.hash[ eventsList[idx] ] = true;
8438 apis.forEach(function( val, idx ) {
8440 data.apis[ val ] = {};
8442 var apiEvents = events[ val ].split( /\s+/g ),
8443 len = apiEvents.length,
8446 for ( ; k < len; k++ ) {
8447 data.apis[ val ][ apiEvents[ k ] ] = true;
8450 })( Popcorn.Events, internal.events );
8454 isNative: function( type ) {
8455 return !!internal.events.hash[ type ];
8457 getInterface: function( type ) {
8459 if ( !Popcorn.events.isNative( type ) ) {
8463 var eventApi = internal.events,
8464 apis = eventApi.apiTypes,
8465 apihash = eventApi.apis,
8466 idx = 0, len = apis.length, api, tmp;
8468 for ( ; idx < len; idx++ ) {
8471 if ( apihash[ tmp ][ type ] ) {
8478 // Compile all native events to single array
8479 all: Popcorn.Events.Natives.split( /\s+/g ),
8480 // Defines all Event handling static functions
8482 trigger: function( type, data ) {
8483 var eventInterface, evt, clonedEvents,
8484 events = this.data.events[ type ];
8486 // setup checks for custom event system
8488 eventInterface = Popcorn.events.getInterface( type );
8490 if ( eventInterface ) {
8491 evt = document.createEvent( eventInterface );
8492 evt.initEvent( type, true, true, global, 1 );
8494 this.media.dispatchEvent( evt );
8499 // clone events in case callbacks remove callbacks themselves
8500 clonedEvents = events.slice();
8502 // iterate through all callbacks
8503 while ( clonedEvents.length ) {
8504 clonedEvents.shift().call( this, data );
8510 listen: function( type, fn ) {
8513 eventHook = Popcorn.events.hooks[ type ],
8518 if ( typeof fn !== "function" ) {
8519 throw new Error( "Popcorn.js Error: Listener is not a function" );
8522 // Setup event registry entry
8523 if ( !this.data.events[ type ] ) {
8524 this.data.events[ type ] = [];
8525 // Toggle if the previous assumption was untrue
8529 // Check and setup event hooks
8531 // Execute hook add method if defined
8532 if ( eventHook.add ) {
8533 eventHook.add.call( this, {}, fn );
8536 // Reassign event type to our piggyback event type if defined
8537 if ( eventHook.bind ) {
8538 type = eventHook.bind;
8541 // Reassign handler if defined
8542 if ( eventHook.handler ) {
8545 fn = function wrapper( event ) {
8546 eventHook.handler.call( self, event, tmp );
8550 // assume the piggy back event is registered
8553 // Setup event registry entry
8554 if ( !this.data.events[ type ] ) {
8555 this.data.events[ type ] = [];
8556 // Toggle if the previous assumption was untrue
8561 // Register event and handler
8562 this.data.events[ type ].push( fn );
8564 // only attach one event of any type
8565 if ( !hasEvents && Popcorn.events.all.indexOf( type ) > -1 ) {
8566 this.media.addEventListener( type, function( event ) {
8567 if ( self.data.events[ type ] ) {
8568 // clone events in case callbacks remove callbacks themselves
8569 clonedEvents = self.data.events[ type ].slice();
8571 // iterate through all callbacks
8572 while ( clonedEvents.length ) {
8573 clonedEvents.shift().call( self, event );
8580 unlisten: function( type, fn ) {
8582 events = this.data.events[ type ];
8585 return; // no listeners = nothing to do
8588 if ( typeof fn === "string" ) {
8589 // legacy support for string-based removal -- not recommended
8590 for ( var i = 0; i < events.length; i++ ) {
8591 if ( events[ i ].name === fn ) {
8592 // decrement i because array length just got smaller
8593 events.splice( i--, 1 );
8598 } else if ( typeof fn === "function" ) {
8599 while( ind !== -1 ) {
8600 ind = events.indexOf( fn );
8602 events.splice( ind, 1 );
8609 // if we got to this point, we are deleting all functions of this type
8610 this.data.events[ type ] = null;
8617 bind: "canplaythrough",
8618 add: function( event, callback ) {
8622 if ( this.media.readyState ) {
8624 // always call canplayall asynchronously
8625 setTimeout(function() {
8626 callback.call( this, event );
8632 this.data.hooks.canplayall = {
8636 // declare special handling instructions
8637 handler: function canplayall( event, callback ) {
8639 if ( !this.data.hooks.canplayall.fired ) {
8640 // trigger original user callback once
8641 callback.call( this, event );
8643 this.data.hooks.canplayall.fired = true;
8650 // Extend Popcorn.events.fns (listen, unlisten, trigger) to all Popcorn instances
8651 // Extend aliases (on, off, emit)
8652 Popcorn.forEach( [ [ "trigger", "emit" ], [ "listen", "on" ], [ "unlisten", "off" ] ], function( key ) {
8653 Popcorn.p[ key[ 0 ] ] = Popcorn.p[ key[ 1 ] ] = Popcorn.events.fn[ key[ 0 ] ];
8656 // Internal Only - construct simple "TrackEvent"
8657 // data type objects
8658 function TrackEvent( track ) {
8659 Abstract.put.call( this, track );
8662 // Determine if a TrackEvent's "start" and "trackstart" must be called.
8663 TrackEvent.start = function( instance, track ) {
8665 if ( track.end > instance.media.currentTime &&
8666 track.start <= instance.media.currentTime && !track._running ) {
8668 track._running = true;
8669 instance.data.running[ track._natives.type ].push( track );
8671 if ( !instance.data.disabled[ track._natives.type ] ) {
8673 track._natives.start.call( instance, null, track );
8675 instance.emit( "trackstart",
8676 Popcorn.extend( {}, track, {
8677 plugin: track._natives.type,
8686 // Determine if a TrackEvent's "end" and "trackend" must be called.
8687 TrackEvent.end = function( instance, track ) {
8691 if ( ( track.end <= instance.media.currentTime ||
8692 track.start > instance.media.currentTime ) && track._running ) {
8694 runningPlugins = instance.data.running[ track._natives.type ];
8696 track._running = false;
8697 runningPlugins.splice( runningPlugins.indexOf( track ), 1 );
8699 if ( !instance.data.disabled[ track._natives.type ] ) {
8701 track._natives.end.call( instance, null, track );
8703 instance.emit( "trackend",
8704 Popcorn.extend( {}, track, {
8705 plugin: track._natives.type,
8714 // Internal Only - construct "TrackEvents"
8715 // data type objects that are used by the Popcorn
8716 // instance, stored at p.data.trackEvents
8717 function TrackEvents( parent ) {
8718 this.parent = parent;
8729 this.animating = [];
8730 this.startIndex = 0;
8732 this.previousUpdateTime = -1;
8734 Object.defineProperty( this, "count", {
8736 return this.byStart.length;
8741 function isMatch( obj, key, value ) {
8742 return obj[ key ] && obj[ key ] === value;
8745 TrackEvents.prototype.where = function( params ) {
8746 return ( this.parent.getTrackEvents() || [] ).filter(function( event ) {
8749 // If no explicit params, match all TrackEvents
8754 // Filter keys in params against both the top level properties
8755 // and the _natives properties
8756 for ( key in params ) {
8757 value = params[ key ];
8758 if ( isMatch( event, key, value ) || isMatch( event._natives, key, value ) ) {
8766 TrackEvents.prototype.add = function( track ) {
8768 // Store this definition in an array sorted by times
8769 var byStart = this.byStart,
8771 startIndex, endIndex;
8773 // Push track event ids into the history
8774 if ( track && track._id ) {
8775 this.parent.data.history.push( track._id );
8778 track.start = Popcorn.util.toSeconds( track.start, this.parent.options.framerate );
8779 track.end = Popcorn.util.toSeconds( track.end, this.parent.options.framerate );
8781 for ( startIndex = byStart.length - 1; startIndex >= 0; startIndex-- ) {
8783 if ( track.start >= byStart[ startIndex ].start ) {
8784 byStart.splice( startIndex + 1, 0, track );
8789 for ( endIndex = byEnd.length - 1; endIndex >= 0; endIndex-- ) {
8791 if ( track.end > byEnd[ endIndex ].end ) {
8792 byEnd.splice( endIndex + 1, 0, track );
8797 // update startIndex and endIndex
8798 if ( startIndex <= this.parent.data.trackEvents.startIndex &&
8799 track.start <= this.parent.data.trackEvents.previousUpdateTime ) {
8801 this.parent.data.trackEvents.startIndex++;
8804 if ( endIndex <= this.parent.data.trackEvents.endIndex &&
8805 track.end < this.parent.data.trackEvents.previousUpdateTime ) {
8807 this.parent.data.trackEvents.endIndex++;
8812 TrackEvents.prototype.remove = function( removeId, state ) {
8814 if ( removeId instanceof TrackEvent ) {
8815 removeId = removeId.id;
8818 if ( typeof removeId === "object" ) {
8819 // Filter by key=val and remove all matching TrackEvents
8820 this.where( removeId ).forEach(function( event ) {
8821 // |this| refers to the calling Popcorn "parent" instance
8822 this.removeTrackEvent( event._id );
8828 var start, end, animate, historyLen, track,
8829 length = this.byStart.length,
8838 state = state || {};
8840 while ( --length > -1 ) {
8841 start = this.byStart[ index ];
8842 end = this.byEnd[ index ];
8844 // Padding events will not have _id properties.
8845 // These should be safely pushed onto the front and back of the
8846 // track event array
8848 byStart.push( start );
8852 // Filter for user track events (vs system track events)
8855 // If not a matching start event for removal
8856 if ( start._id !== removeId ) {
8857 byStart.push( start );
8860 // If not a matching end event for removal
8861 if ( end._id !== removeId ) {
8865 // If the _id is matched, capture the current index
8866 if ( start._id === removeId ) {
8869 // cache the track event being removed
8873 // Increment the track index
8877 // Reset length to be used by the condition below to determine
8878 // if animating track events should also be filtered for removal.
8879 // Reset index below to be used by the reverse while as an
8880 // incrementing counter
8881 length = this.animating.length;
8885 while ( --length > -1 ) {
8886 animate = this.animating[ index ];
8888 // Padding events will not have _id properties.
8889 // These should be safely pushed onto the front and back of the
8890 // track event array
8891 if ( !animate._id ) {
8892 animating.push( animate );
8895 // If not a matching animate event for removal
8896 if ( animate._id && animate._id !== removeId ) {
8897 animating.push( animate );
8899 // Increment the track index
8905 if ( indexWasAt <= this.startIndex ) {
8909 if ( indexWasAt <= this.endIndex ) {
8913 this.byStart = byStart;
8915 this.animating = animating;
8917 historyLen = this.parent.data.history.length;
8919 for ( var i = 0; i < historyLen; i++ ) {
8920 if ( this.parent.data.history[ i ] !== removeId ) {
8921 history.push( this.parent.data.history[ i ] );
8925 // Update ordered history array
8926 this.parent.data.history = history;
8930 // Helper function used to retrieve old values of properties that
8931 // are provided for update.
8932 function getPreviousProperties( oldOptions, newOptions ) {
8933 var matchProps = {};
8935 for ( var prop in oldOptions ) {
8936 if ( hasOwn.call( newOptions, prop ) && hasOwn.call( oldOptions, prop ) ) {
8937 matchProps[ prop ] = oldOptions[ prop ];
8944 // Internal Only - Adds track events to the instance object
8945 Popcorn.addTrackEvent = function( obj, track ) {
8948 if ( track instanceof TrackEvent ) {
8952 track = new TrackEvent( track );
8954 // Determine if this track has default options set for it
8955 // If so, apply them to the track object
8956 if ( track && track._natives && track._natives.type &&
8957 ( obj.options.defaults && obj.options.defaults[ track._natives.type ] ) ) {
8959 // To ensure that the TrackEvent Invariant Policy is enforced,
8960 // First, copy the properties of the newly created track event event
8961 // to a temporary holder
8962 temp = Popcorn.extend( {}, track );
8964 // Next, copy the default onto the newly created trackevent, followed by the
8965 // temporary holder.
8966 Popcorn.extend( track, obj.options.defaults[ track._natives.type ], temp );
8969 if ( track._natives ) {
8970 // Supports user defined track event id
8971 track._id = track.id || track._id || Popcorn.guid( track._natives.type );
8973 // Trigger _setup method if exists
8974 if ( track._natives._setup ) {
8976 track._natives._setup.call( obj, track );
8978 obj.emit( "tracksetup", Popcorn.extend( {}, track, {
8979 plugin: track._natives.type,
8986 obj.data.trackEvents.add( track );
8987 TrackEvent.start( obj, track );
8989 this.timeUpdate( obj, null, true );
8991 // Store references to user added trackevents in ref table
8993 Popcorn.addTrackEvent.ref( obj, track );
8996 obj.emit( "trackadded", Popcorn.extend({}, track,
8997 track._natives ? { plugin: track._natives.type } : {}, {
9003 // Internal Only - Adds track event references to the instance object's trackRefs hash table
9004 Popcorn.addTrackEvent.ref = function( obj, track ) {
9005 obj.data.trackRefs[ track._id ] = track;
9010 Popcorn.removeTrackEvent = function( obj, removeId ) {
9011 var track = obj.getTrackEvent( removeId );
9017 // If a _teardown function was defined,
9018 // enforce for track event removals
9019 if ( track._natives._teardown ) {
9020 track._natives._teardown.call( obj, track );
9023 obj.data.trackEvents.remove( removeId );
9025 // Update track event references
9026 Popcorn.removeTrackEvent.ref( obj, removeId );
9028 if ( track._natives ) {
9030 // Fire a trackremoved event
9031 obj.emit( "trackremoved", Popcorn.extend({}, track, {
9032 plugin: track._natives.type,
9033 type: "trackremoved",
9039 // Internal Only - Removes track event references from instance object's trackRefs hash table
9040 Popcorn.removeTrackEvent.ref = function( obj, removeId ) {
9041 delete obj.data.trackRefs[ removeId ];
9046 // Return an array of track events bound to this instance object
9047 Popcorn.getTrackEvents = function( obj ) {
9049 var trackevents = [],
9050 refs = obj.data.trackEvents.byStart,
9051 length = refs.length,
9055 for ( ; idx < length; idx++ ) {
9057 // Return only user attributed track event references
9059 trackevents.push( ref );
9066 // Internal Only - Returns an instance object's trackRefs hash table
9067 Popcorn.getTrackEvents.ref = function( obj ) {
9068 return obj.data.trackRefs;
9071 // Return a single track event bound to this instance object
9072 Popcorn.getTrackEvent = function( obj, trackId ) {
9073 return obj.data.trackRefs[ trackId ];
9076 // Internal Only - Returns an instance object's track reference by track id
9077 Popcorn.getTrackEvent.ref = function( obj, trackId ) {
9078 return obj.data.trackRefs[ trackId ];
9081 Popcorn.getLastTrackEventId = function( obj ) {
9082 return obj.data.history[ obj.data.history.length - 1 ];
9085 Popcorn.timeUpdate = function( obj, event ) {
9086 var currentTime = obj.media.currentTime,
9087 previousTime = obj.data.trackEvents.previousUpdateTime,
9088 tracks = obj.data.trackEvents,
9089 end = tracks.endIndex,
9090 start = tracks.startIndex,
9091 byStartLen = tracks.byStart.length,
9092 byEndLen = tracks.byEnd.length,
9093 registryByName = Popcorn.registryByName,
9094 trackstart = "trackstart",
9095 trackend = "trackend",
9097 byEnd, byStart, byAnimate, natives, type, runningPlugins;
9099 // Playbar advancing
9100 if ( previousTime <= currentTime ) {
9102 while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end <= currentTime ) {
9104 byEnd = tracks.byEnd[ end ];
9105 natives = byEnd._natives;
9106 type = natives && natives.type;
9108 // If plugin does not exist on this instance, remove it
9110 ( !!registryByName[ type ] ||
9113 if ( byEnd._running === true ) {
9115 byEnd._running = false;
9116 runningPlugins = obj.data.running[ type ];
9117 runningPlugins.splice( runningPlugins.indexOf( byEnd ), 1 );
9119 if ( !obj.data.disabled[ type ] ) {
9121 natives.end.call( obj, event, byEnd );
9124 Popcorn.extend({}, byEnd, {
9135 // remove track event
9136 Popcorn.removeTrackEvent( obj, byEnd._id );
9141 while ( tracks.byStart[ start ] && tracks.byStart[ start ].start <= currentTime ) {
9143 byStart = tracks.byStart[ start ];
9144 natives = byStart._natives;
9145 type = natives && natives.type;
9146 // If plugin does not exist on this instance, remove it
9148 ( !!registryByName[ type ] ||
9150 if ( byStart.end > currentTime &&
9151 byStart._running === false ) {
9153 byStart._running = true;
9154 obj.data.running[ type ].push( byStart );
9156 if ( !obj.data.disabled[ type ] ) {
9158 natives.start.call( obj, event, byStart );
9160 obj.emit( trackstart,
9161 Popcorn.extend({}, byStart, {
9171 // remove track event
9172 Popcorn.removeTrackEvent( obj, byStart._id );
9178 } else if ( previousTime > currentTime ) {
9180 while ( tracks.byStart[ start ] && tracks.byStart[ start ].start > currentTime ) {
9182 byStart = tracks.byStart[ start ];
9183 natives = byStart._natives;
9184 type = natives && natives.type;
9186 // if plugin does not exist on this instance, remove it
9188 ( !!registryByName[ type ] ||
9191 if ( byStart._running === true ) {
9193 byStart._running = false;
9194 runningPlugins = obj.data.running[ type ];
9195 runningPlugins.splice( runningPlugins.indexOf( byStart ), 1 );
9197 if ( !obj.data.disabled[ type ] ) {
9199 natives.end.call( obj, event, byStart );
9202 Popcorn.extend({}, byStart, {
9212 // remove track event
9213 Popcorn.removeTrackEvent( obj, byStart._id );
9218 while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end > currentTime ) {
9220 byEnd = tracks.byEnd[ end ];
9221 natives = byEnd._natives;
9222 type = natives && natives.type;
9224 // if plugin does not exist on this instance, remove it
9226 ( !!registryByName[ type ] ||
9229 if ( byEnd.start <= currentTime &&
9230 byEnd._running === false ) {
9232 byEnd._running = true;
9233 obj.data.running[ type ].push( byEnd );
9235 if ( !obj.data.disabled[ type ] ) {
9237 natives.start.call( obj, event, byEnd );
9239 obj.emit( trackstart,
9240 Popcorn.extend({}, byEnd, {
9250 // remove track event
9251 Popcorn.removeTrackEvent( obj, byEnd._id );
9257 tracks.endIndex = end;
9258 tracks.startIndex = start;
9259 tracks.previousUpdateTime = currentTime;
9261 //enforce index integrity if trackRemoved
9262 tracks.byStart.length < byStartLen && tracks.startIndex--;
9263 tracks.byEnd.length < byEndLen && tracks.endIndex--;
9267 // Map and Extend TrackEvent functions to all Popcorn instances
9268 Popcorn.extend( Popcorn.p, {
9270 getTrackEvents: function() {
9271 return Popcorn.getTrackEvents.call( null, this );
9274 getTrackEvent: function( id ) {
9275 return Popcorn.getTrackEvent.call( null, this, id );
9278 getLastTrackEventId: function() {
9279 return Popcorn.getLastTrackEventId.call( null, this );
9282 removeTrackEvent: function( id ) {
9284 Popcorn.removeTrackEvent.call( null, this, id );
9288 removePlugin: function( name ) {
9289 Popcorn.removePlugin.call( null, this, name );
9293 timeUpdate: function( event ) {
9294 Popcorn.timeUpdate.call( null, this, event );
9298 destroy: function() {
9299 Popcorn.destroy.call( null, this );
9305 Popcorn.manifest = {};
9306 // Plugins are registered
9307 Popcorn.registry = [];
9308 Popcorn.registryByName = {};
9309 // An interface for extending Popcorn
9310 // with plugin functionality
9311 Popcorn.plugin = function( name, definition, manifest ) {
9313 if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
9314 Popcorn.error( "'" + name + "' is a protected function name" );
9318 // Provides some sugar, but ultimately extends
9319 // the definition into Popcorn.p
9320 var isfn = typeof definition === "function",
9321 blacklist = [ "start", "end", "type", "manifest" ],
9322 methods = [ "_setup", "_teardown", "start", "end", "frame" ],
9326 // combines calls of two function calls into one
9327 var combineFn = function( first, second ) {
9329 first = first || Popcorn.nop;
9330 second = second || Popcorn.nop;
9333 first.apply( this, arguments );
9334 second.apply( this, arguments );
9338 // If `manifest` arg is undefined, check for manifest within the `definition` object
9339 // If no `definition.manifest`, an empty object is a sufficient fallback
9340 Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {};
9342 // apply safe, and empty default functions
9343 methods.forEach(function( method ) {
9344 definition[ method ] = safeTry( definition[ method ] || Popcorn.nop, name );
9347 var pluginFn = function( setup, options ) {
9353 // When the "ranges" property is set and its value is an array, short-circuit
9354 // the pluginFn definition to recall itself with an options object generated from
9355 // each range object in the ranges array. (eg. { start: 15, end: 16 } )
9356 if ( options.ranges && Popcorn.isArray(options.ranges) ) {
9357 Popcorn.forEach( options.ranges, function( range ) {
9358 // Create a fresh object, extend with current options
9359 // and start/end range object's properties
9360 // Works with in/out as well.
9361 var opts = Popcorn.extend( {}, options, range );
9363 // Remove the ranges property to prevent infinitely
9364 // entering this condition
9367 // Call the plugin with the newly created opts object
9368 this[ name ]( opts );
9371 // Return the Popcorn instance to avoid creating an empty track event
9375 // Storing the plugin natives
9376 var natives = options._natives = {},
9378 originalOpts, manifestOpts;
9380 Popcorn.extend( natives, setup );
9382 options._natives.type = options._natives.plugin = name;
9383 options._running = false;
9385 natives.start = natives.start || natives[ "in" ];
9386 natives.end = natives.end || natives[ "out" ];
9388 if ( options.once ) {
9389 natives.end = combineFn( natives.end, function() {
9390 this.removeTrackEvent( options._id );
9394 // extend teardown to always call end if running
9395 natives._teardown = combineFn(function() {
9397 var args = slice.call( arguments ),
9398 runningPlugins = this.data.running[ natives.type ];
9400 // end function signature is not the same as teardown,
9401 // put null on the front of arguments for the event parameter
9402 args.unshift( null );
9404 // only call end if event is running
9405 args[ 1 ]._running &&
9406 runningPlugins.splice( runningPlugins.indexOf( options ), 1 ) &&
9407 natives.end.apply( this, args );
9409 args[ 1 ]._running = false;
9410 this.emit( "trackend",
9411 Popcorn.extend( {}, options, {
9412 plugin: natives.type,
9414 track: Popcorn.getTrackEvent( this, options.id || options._id )
9417 }, natives._teardown );
9419 // extend teardown to always trigger trackteardown after teardown
9420 natives._teardown = combineFn( natives._teardown, function() {
9422 this.emit( "trackteardown", Popcorn.extend( {}, options, {
9424 type: "trackteardown",
9425 track: Popcorn.getTrackEvent( this, options.id || options._id )
9429 // default to an empty string if no effect exists
9430 // split string into an array of effects
9431 options.compose = options.compose || [];
9432 if ( typeof options.compose === "string" ) {
9433 options.compose = options.compose.split( " " );
9435 options.effect = options.effect || [];
9436 if ( typeof options.effect === "string" ) {
9437 options.effect = options.effect.split( " " );
9440 // join the two arrays together
9441 options.compose = options.compose.concat( options.effect );
9443 options.compose.forEach(function( composeOption ) {
9445 // if the requested compose is garbage, throw it away
9446 compose = Popcorn.compositions[ composeOption ] || {};
9448 // extends previous functions with compose function
9449 methods.forEach(function( method ) {
9450 natives[ method ] = combineFn( natives[ method ], compose[ method ] );
9454 // Ensure a manifest object, an empty object is a sufficient fallback
9455 options._natives.manifest = manifest;
9457 // Checks for expected properties
9458 if ( !( "start" in options ) ) {
9459 options.start = options[ "in" ] || 0;
9462 if ( !options.end && options.end !== 0 ) {
9463 options.end = options[ "out" ] || Number.MAX_VALUE;
9466 // Use hasOwn to detect non-inherited toString, since all
9467 // objects will receive a toString - its otherwise undetectable
9468 if ( !hasOwn.call( options, "toString" ) ) {
9469 options.toString = function() {
9471 "start: " + options.start,
9472 "end: " + options.end,
9473 "id: " + (options.id || options._id)
9476 // Matches null and undefined, allows: false, 0, "" and truthy
9477 if ( options.target != null ) {
9478 props.push( "target: " + options.target );
9481 return name + " ( " + props.join(", ") + " )";
9485 // Resolves 239, 241, 242
9486 if ( !options.target ) {
9488 // Sometimes the manifest may be missing entirely
9489 // or it has an options object that doesn't have a `target` property
9490 manifestOpts = "options" in manifest && manifest.options;
9492 options.target = manifestOpts && "target" in manifestOpts && manifestOpts.target;
9495 if ( !options._id && options._natives ) {
9496 // ensure an initial id is there before setup is called
9497 options._id = Popcorn.guid( options._natives.type );
9500 if ( options instanceof TrackEvent ) {
9502 if ( options._natives ) {
9503 // Supports user defined track event id
9504 options._id = options.id || options._id || Popcorn.guid( options._natives.type );
9506 // Trigger _setup method if exists
9507 if ( options._natives._setup ) {
9509 options._natives._setup.call( this, options );
9511 this.emit( "tracksetup", Popcorn.extend( {}, options, {
9512 plugin: options._natives.type,
9519 this.data.trackEvents.add( options );
9520 TrackEvent.start( this, options );
9522 this.timeUpdate( this, null, true );
9524 // Store references to user added trackevents in ref table
9525 if ( options._id ) {
9526 Popcorn.addTrackEvent.ref( this, options );
9529 // Create new track event for this instance
9530 Popcorn.addTrackEvent( this, options );
9533 // Future support for plugin event definitions
9534 // for all of the native events
9535 Popcorn.forEach( setup, function( callback, type ) {
9536 // Don't attempt to create events for certain properties:
9537 // "start", "end", "type", "manifest". Fixes #1365
9538 if ( blacklist.indexOf( type ) === -1 ) {
9539 this.on( type, callback );
9546 // Extend Popcorn.p with new named definition
9547 // Assign new named definition
9548 Popcorn.p[ name ] = plugin[ name ] = function( id, options ) {
9549 var length = arguments.length,
9550 trackEvent, defaults, mergedSetupOpts, previousOpts, newOpts;
9552 // Shift arguments based on use case
9555 // p.plugin( options );
9556 if ( id && !options ) {
9561 // Get the trackEvent that matches the given id.
9562 trackEvent = this.getTrackEvent( id );
9564 // If the track event does not exist, ensure that the options
9565 // object has a proper id
9566 if ( !trackEvent ) {
9569 // If the track event does exist, merge the updated properties
9573 previousOpts = getPreviousProperties( trackEvent, newOpts );
9575 // Call the plugins defined update method if provided. Allows for
9576 // custom defined updating for a track event to be defined by the plugin author
9577 if ( trackEvent._natives._update ) {
9579 this.data.trackEvents.remove( trackEvent );
9581 // It's safe to say that the intent of Start/End will never change
9582 // Update them first before calling update
9583 if ( hasOwn.call( options, "start" ) ) {
9584 trackEvent.start = options.start;
9587 if ( hasOwn.call( options, "end" ) ) {
9588 trackEvent.end = options.end;
9591 TrackEvent.end( this, trackEvent );
9594 definition.call( this, trackEvent );
9597 trackEvent._natives._update.call( this, trackEvent, options );
9599 this.data.trackEvents.add( trackEvent );
9600 TrackEvent.start( this, trackEvent );
9602 // This branch is taken when there is no explicitly defined
9603 // _update method for a plugin. Which will occur either explicitly or
9604 // as a result of the plugin definition being a function that _returns_
9605 // a definition object.
9607 // In either case, this path can ONLY be reached for TrackEvents that
9610 // Directly update the TrackEvent instance.
9611 // This supports TrackEvent invariant enforcement.
9612 Popcorn.extend( trackEvent, options );
9614 this.data.trackEvents.remove( id );
9616 // If a _teardown function was defined,
9617 // enforce for track event removals
9618 if ( trackEvent._natives._teardown ) {
9619 trackEvent._natives._teardown.call( this, trackEvent );
9622 // Update track event references
9623 Popcorn.removeTrackEvent.ref( this, id );
9626 pluginFn.call( this, definition.call( this, trackEvent ), trackEvent );
9629 // Supports user defined track event id
9630 trackEvent._id = trackEvent.id || trackEvent._id || Popcorn.guid( trackEvent._natives.type );
9632 if ( trackEvent._natives && trackEvent._natives._setup ) {
9634 trackEvent._natives._setup.call( this, trackEvent );
9636 this.emit( "tracksetup", Popcorn.extend( {}, trackEvent, {
9637 plugin: trackEvent._natives.type,
9643 this.data.trackEvents.add( trackEvent );
9644 TrackEvent.start( this, trackEvent );
9646 this.timeUpdate( this, null, true );
9648 // Store references to user added trackevents in ref table
9649 Popcorn.addTrackEvent.ref( this, trackEvent );
9652 // Fire an event with change information
9653 this.emit( "trackchange", {
9655 type: "trackchange",
9656 previousValue: previousOpts,
9657 currentValue: trackEvent,
9664 if ( trackEvent._natives.type !== "cue" ) {
9665 // Fire an event with change information
9666 this.emit( "trackchange", {
9668 type: "trackchange",
9669 previousValue: previousOpts,
9670 currentValue: newOpts,
9679 this.data.running[ name ] = this.data.running[ name ] || [];
9681 // Merge with defaults if they exist, make sure per call is prioritized
9682 defaults = ( this.options.defaults && this.options.defaults[ name ] ) || {};
9683 mergedSetupOpts = Popcorn.extend( {}, defaults, options );
9685 pluginFn.call( this, isfn ? definition.call( this, mergedSetupOpts ) : definition,
9691 // if the manifest parameter exists we should extend it onto the definition object
9692 // so that it shows up when calling Popcorn.registry and Popcorn.registryByName
9694 Popcorn.extend( definition, {
9699 // Push into the registry
9702 definition: definition,
9707 Popcorn.registry.push(
9708 Popcorn.extend( plugin, entry, {
9712 Popcorn.registryByName[ name ] = entry;
9717 // Storage for plugin function errors
9718 Popcorn.plugin.errors = [];
9720 // Returns wrapped plugin function
9721 function safeTry( fn, pluginName ) {
9724 // When Popcorn.plugin.debug is true, do not suppress errors
9725 if ( Popcorn.plugin.debug ) {
9726 return fn.apply( this, arguments );
9730 return fn.apply( this, arguments );
9733 // Push plugin function errors into logging queue
9734 Popcorn.plugin.errors.push({
9737 source: fn.toString()
9740 // Trigger an error that the instance can listen for
9742 this.emit( "pluginerror", Popcorn.plugin.errors );
9747 // Debug-mode flag for plugin development
9748 // True for Popcorn development versions, false for stable/tagged versions
9749 Popcorn.plugin.debug = ( Popcorn.version === "@" + "VERSION" );
9751 // removePlugin( type ) removes all tracks of that from all instances of popcorn
9752 // removePlugin( obj, type ) removes all tracks of type from obj, where obj is a single instance of popcorn
9753 Popcorn.removePlugin = function( obj, name ) {
9755 // Check if we are removing plugin from an instance or from all of Popcorn
9762 if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
9763 Popcorn.error( "'" + name + "' is a protected function name" );
9767 var registryLen = Popcorn.registry.length,
9770 // remove plugin reference from registry
9771 for ( registryIdx = 0; registryIdx < registryLen; registryIdx++ ) {
9772 if ( Popcorn.registry[ registryIdx ].name === name ) {
9773 Popcorn.registry.splice( registryIdx, 1 );
9774 delete Popcorn.registryByName[ name ];
9775 delete Popcorn.manifest[ name ];
9777 // delete the plugin
9780 // plugin found and removed, stop checking, we are done
9787 var byStart = obj.data.trackEvents.byStart,
9788 byEnd = obj.data.trackEvents.byEnd,
9789 animating = obj.data.trackEvents.animating,
9792 // remove all trackEvents
9793 for ( idx = 0, sl = byStart.length; idx < sl; idx++ ) {
9795 if ( byStart[ idx ] && byStart[ idx ]._natives && byStart[ idx ]._natives.type === name ) {
9797 byStart[ idx ]._natives._teardown && byStart[ idx ]._natives._teardown.call( obj, byStart[ idx ] );
9799 byStart.splice( idx, 1 );
9801 // update for loop if something removed, but keep checking
9803 if ( obj.data.trackEvents.startIndex <= idx ) {
9804 obj.data.trackEvents.startIndex--;
9805 obj.data.trackEvents.endIndex--;
9809 // clean any remaining references in the end index
9810 // we do this seperate from the above check because they might not be in the same order
9811 if ( byEnd[ idx ] && byEnd[ idx ]._natives && byEnd[ idx ]._natives.type === name ) {
9813 byEnd.splice( idx, 1 );
9817 //remove all animating events
9818 for ( idx = 0, sl = animating.length; idx < sl; idx++ ) {
9820 if ( animating[ idx ] && animating[ idx ]._natives && animating[ idx ]._natives.type === name ) {
9822 animating.splice( idx, 1 );
9824 // update for loop if something removed, but keep checking
9831 Popcorn.compositions = {};
9833 // Plugin inheritance
9834 Popcorn.compose = function( name, definition, manifest ) {
9836 // If `manifest` arg is undefined, check for manifest within the `definition` object
9837 // If no `definition.manifest`, an empty object is a sufficient fallback
9838 Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {};
9840 // register the effect by name
9841 Popcorn.compositions[ name ] = definition;
9844 Popcorn.plugin.effect = Popcorn.effect = Popcorn.compose;
9846 var rnaiveExpr = /^(?:\.|#|\[)/;
9848 // Basic DOM utilities and helpers API. See #1037
9851 // Popcorn.dom.find( selector, context )
9853 // Returns the first element that matches the specified selector
9854 // Optionally provide a context element, defaults to `document`
9857 // Popcorn.dom.find("video") returns the first video element
9858 // Popcorn.dom.find("#foo") returns the first element with `id="foo"`
9859 // Popcorn.dom.find("foo") returns the first element with `id="foo"`
9860 // Note: Popcorn.dom.find("foo") is the only allowed deviation
9861 // from valid querySelector selector syntax
9863 // Popcorn.dom.find(".baz") returns the first element with `class="baz"`
9864 // Popcorn.dom.find("[preload]") returns the first element with `preload="..."`
9866 // See https://developer.mozilla.org/En/DOM/Document.querySelector
9869 find: function( selector, context ) {
9872 // Default context is the `document`
9873 context = context || document;
9877 // If the selector does not begin with "#", "." or "[",
9878 // it could be either a nodeName or ID w/o "#"
9879 if ( !rnaiveExpr.test( selector ) ) {
9881 // Try finding an element that matches by ID first
9882 node = document.getElementById( selector );
9884 // If a match was found by ID, return the element
9885 if ( node !== null ) {
9889 // Assume no elements have been found yet
9890 // Catch any invalid selector syntax errors and bury them.
9892 node = context.querySelector( selector );
9894 if ( Popcorn.dom.debug ) {
9903 // Cache references to reused RegExps
9911 success: Popcorn.nop,
9914 contentType: "application/x-www-form-urlencoded; charset=UTF-8"
9917 Popcorn.xhr = function( options ) {
9920 options.dataType = options.dataType && options.dataType.toLowerCase() || null;
9922 if ( options.dataType &&
9923 ( options.dataType === "jsonp" || options.dataType === "script" ) ) {
9925 Popcorn.xhr.getJSONP(
9928 options.dataType === "script"
9933 // Merge the "setup" defaults and custom "options"
9934 // into a new plain object.
9935 settings = Popcorn.extend( {}, setup, options );
9937 // Create new XMLHttpRequest object
9938 settings.ajax = new XMLHttpRequest();
9940 if ( settings.ajax ) {
9942 if ( settings.type === "GET" && settings.data ) {
9944 // append query string
9945 settings.url += ( rparams.test( settings.url ) ? "&" : "?" ) + settings.data;
9947 // Garbage collect and reset settings.data
9948 settings.data = null;
9952 settings.ajax.open( settings.type, settings.url, settings.async );
9954 // For POST, set the content-type request header
9955 if ( settings.type === "POST" ) {
9956 settings.ajax.setRequestHeader(
9957 "Content-Type", settings.contentType
9961 settings.ajax.send( settings.data || null );
9963 return Popcorn.xhr.httpData( settings );
9968 Popcorn.xhr.httpData = function( settings ) {
9970 var data, json = null,
9973 settings.ajax.onreadystatechange = function() {
9975 if ( settings.ajax.readyState === 4 ) {
9978 json = JSON.parse( settings.ajax.responseText );
9984 xml: settings.ajax.responseXML,
9985 text: settings.ajax.responseText,
9989 // Normalize: data.xml is non-null in IE9 regardless of if response is valid xml
9990 if ( !data.xml || !data.xml.documentElement ) {
9994 parser = new DOMParser();
9995 xml = parser.parseFromString( settings.ajax.responseText, "text/xml" );
9997 if ( !xml.getElementsByTagName( "parsererror" ).length ) {
10001 // data.xml remains null
10005 // If a dataType was specified, return that type of data
10006 if ( settings.dataType ) {
10007 data = data[ settings.dataType ];
10011 settings.success.call( settings.ajax, data );
10018 Popcorn.xhr.getJSONP = function( url, success, isScript ) {
10020 var head = document.head || document.getElementsByTagName( "head" )[ 0 ] || document.documentElement,
10021 script = document.createElement( "script" ),
10024 rjsonp = /(=)\?(?=&|$)|\?\?/,
10025 replaceInUrl, prefix, paramStr, callback, callparam;
10029 // is there a calback already in the url
10030 callparam = url.match( /(callback=[^&]*)/ );
10032 if ( callparam !== null && callparam.length ) {
10034 prefix = callparam[ 1 ].split( "=" )[ 1 ];
10036 // Since we need to support developer specified callbacks
10037 // and placeholders in harmony, make sure matches to "callback="
10038 // aren't just placeholders.
10039 // We coded ourselves into a corner here.
10040 // JSONP callbacks should never have been
10041 // allowed to have developer specified callbacks
10042 if ( prefix === "?" ) {
10046 // get the callback name
10047 callback = Popcorn.guid( prefix );
10049 // replace existing callback name with unique callback name
10050 url = url.replace( /(callback=[^&]*)/, "callback=" + callback );
10053 callback = Popcorn.guid( "jsonp" );
10055 if ( rjsonp.test( url ) ) {
10056 url = url.replace( rjsonp, "$1" + callback );
10059 // split on first question mark,
10060 // this is to capture the query string
10061 params = url.split( /\?(.+)?/ );
10063 // rebuild url with callback
10064 url = params[ 0 ] + "?";
10065 if ( params[ 1 ] ) {
10066 url += params[ 1 ] + "&";
10068 url += "callback=" + callback;
10071 // Define the JSONP success callback globally
10072 window[ callback ] = function( data ) {
10073 // Fire success callbacks
10074 success && success( data );
10079 script.addEventListener( "load", function() {
10081 // Handling remote script loading callbacks
10084 success && success();
10087 // Executing for JSONP requests
10089 // Garbage collect the callback
10090 delete window[ callback ];
10092 // Garbage collect the script resource
10093 head.removeChild( script );
10096 script.addEventListener( "error", function( e ) {
10097 // Handling remote script loading callbacks
10098 success && success( { error: e } );
10100 // Executing for JSONP requests
10102 // Garbage collect the callback
10103 delete window[ callback ];
10105 // Garbage collect the script resource
10106 head.removeChild( script );
10110 head.insertBefore( script, head.firstChild );
10115 Popcorn.getJSONP = Popcorn.xhr.getJSONP;
10117 Popcorn.getScript = Popcorn.xhr.getScript = function( url, success ) {
10119 return Popcorn.xhr.getJSONP( url, success, true );
10123 // Simple function to parse a timestamp into seconds
10124 // Acceptable formats are:
10127 // Hours and minutes are optional. They default to 0
10128 toSeconds: function( timeStr, framerate ) {
10129 // Hours and minutes are optional
10130 // Seconds must be specified
10131 // Seconds can be followed by milliseconds OR by the frame information
10132 var validTimeFormat = /^([0-9]+:){0,2}[0-9]+([.;][0-9]+)?$/,
10133 errorMessage = "Invalid time format",
10134 digitPairs, lastIndex, lastPair, firstPair,
10135 frameInfo, frameTime;
10137 if ( typeof timeStr === "number" ) {
10141 if ( typeof timeStr === "string" &&
10142 !validTimeFormat.test( timeStr ) ) {
10143 Popcorn.error( errorMessage );
10146 digitPairs = timeStr.split( ":" );
10147 lastIndex = digitPairs.length - 1;
10148 lastPair = digitPairs[ lastIndex ];
10150 // Fix last element:
10151 if ( lastPair.indexOf( ";" ) > -1 ) {
10153 frameInfo = lastPair.split( ";" );
10156 if ( framerate && ( typeof framerate === "number" ) ) {
10157 frameTime = parseFloat( frameInfo[ 1 ], 10 ) / framerate;
10160 digitPairs[ lastIndex ] = parseInt( frameInfo[ 0 ], 10 ) + frameTime;
10163 firstPair = digitPairs[ 0 ];
10167 1: parseFloat( firstPair, 10 ),
10169 2: ( parseInt( firstPair, 10 ) * 60 ) +
10170 parseFloat( digitPairs[ 1 ], 10 ),
10172 3: ( parseInt( firstPair, 10 ) * 3600 ) +
10173 ( parseInt( digitPairs[ 1 ], 10 ) * 60 ) +
10174 parseFloat( digitPairs[ 2 ], 10 )
10176 }[ digitPairs.length || 1 ];
10180 // alias for exec function
10181 Popcorn.p.cue = Popcorn.p.exec;
10183 // Protected API methods
10184 Popcorn.protect = {
10185 natives: getKeys( Popcorn.p ).map(function( val ) {
10186 return val.toLowerCase();
10190 // Setup logging for deprecated methods
10192 // Deprecated: Recommended
10198 }, function( recommend, api ) {
10199 var original = Popcorn.p[ api ];
10200 // Override the deprecated api method with a method of the same name
10201 // that logs a warning and defers to the new recommended method
10202 Popcorn.p[ api ] = function() {
10203 if ( typeof console !== "undefined" && console.warn ) {
10205 "Deprecated method '" + api + "', " +
10206 (recommend == null ? "do not use." : "use '" + recommend + "' instead." )
10209 // Restore api after first warning
10210 Popcorn.p[ api ] = original;
10212 return Popcorn.p[ recommend ].apply( this, [].slice.call( arguments ) );
10217 // Exposes Popcorn to global context
10218 global.Popcorn = Popcorn;
10220 })(window, window.document);
10222 (function (global, document, $, deck, window, undefined) {
10225 function maybeAddSnippet(audioDataFile, options, andThen) {
10226 if (options.snippets.browsercast) {
10227 if ($(options.selectors.browsercast).size() > 0 && options.alert.goto) {
10228 alert("'options.snippets.browsercast' is true but a "+options.selectors.browsercast+" has been found."
10229 +"\nThis might cause interaction glitches."
10231 +"\nSuggestion: remove your html snippet or pass the {snippets: {browsercast: false}} option."
10234 var ext = audioDataFile.replace(/.*[.]([^.]*)/, '$1');
10235 $('<div/>').addClass('browsercast')
10236 .append($('<audio/>').addClass("browsercast-audio")
10237 .append($('<source/>').attr('src', audioDataFile).attr('type', 'audio/'+ext)))
10238 .append($('<menu/>').append($('<button/>').addClass('playpause')))
10239 .append($('<div/>').addClass('browsercast-markers')
10240 .append($('<div/>').addClass('browsercast-time-label').text('1:00')))
10241 .appendTo($.deck('getContainer'));
10245 var $document = $(document);
10247 function togglePlay(popcorn) {
10248 if (popcorn.paused() === true) {
10255 function timeString(nSeconds) {
10256 return new Date(null, null, null, null, null, nSeconds)
10258 .replace(/ .*$/, '')
10259 .replace(/^00:/, '');
10262 function updatePlayPauseClass(paused, that, ifPlay, ifPause) {
10263 if (paused == true) {
10264 $(that).removeClass(ifPlay);
10265 $(that).addClass(ifPause);
10267 $(that).removeClass(ifPause);
10268 $(that).addClass(ifPlay);
10272 // Use the audio timeupdates to drive existing slides.
10273 function playBrowserCast(timings, options) {
10274 var audio, popcorn, markers, bc;
10276 var nTimings = Object.keys(timings).length;
10277 var defaultWidth = (100./nTimings)+'%';
10279 var forEachTiming = function(f) {
10280 Object.keys(timings)
10281 .sort(function(a, b) {return a - b;})
10285 var inited = false; // to avoid the audio setting the current slide to 0 at the beginning (and allow bookmarking)
10287 bc = $(options.selectors.browsercast).get(0);
10288 audio = $(options.selectors.browsercastAudio).get(0);
10289 markers = $(options.selectors.browsercastMarkers).get(0);
10290 popcorn = Popcorn(audio);
10292 $('.playpause', bc).click(function() {
10293 togglePlay(popcorn);
10296 forEachTiming(function(k, i) {
10297 var div = document.createElement('div');
10298 div.className = 'browsercast-cue';
10299 div.onclick = function(event) {
10300 popcorn.currentTime(timings[k]);
10303 .css('width', defaultWidth)
10304 .css('box-sizing', 'border-box');
10305 markers.appendChild(div);
10307 popcorn.cue(k, timings[k], function () {
10308 if (!inited) return;
10309 transitionLock = true;
10310 $.deck('go', parseInt(k));
10311 $('.active', markers).removeClass('active');
10312 $(div).addClass('active');
10313 transitionLock = false;
10316 var trySetCueLengthAndPlay = function(retries, delay) {
10317 if (retries <= 0) { return; }
10318 var totalDuration = popcorn.duration();
10319 if (totalDuration > 0) { // it tests also for NaN
10321 forEachTiming(function(k, i) {
10323 var pc = 100 * (timings[k] - timings[kPrev]) / totalDuration;
10324 $(divs[kPrev]).css('width', pc+'%');
10328 var pc = 100 * (totalDuration - timings[kPrev]) / totalDuration;
10329 $(divs[kPrev]).css('width', pc+'%');
10330 // Start the 'cast!
10332 var currentSlideIndex = $.deck('getSlides').indexOf($.deck('getSlide'));
10333 setTimeout(function() { // delay initialization for popcorn to be properly inited
10334 $.deck('go', currentSlideIndex);
10337 setTimeout(function() {
10338 trySetCueLengthAndPlay(retries - 1, delay*1.5);
10343 // lock for preventing slidechanged event handler during timeupdate handler.
10344 // TODO using a mutex seems clunky.
10345 var transitionLock = false;
10347 // Decorator for creating an event handler that doesn't run
10348 // when the lock is active.
10349 var ifNotLocked = function (f) {
10350 return function (event) {
10351 if (!transitionLock) {
10352 f.apply(this, arguments);
10357 $document.bind('deck.change', ifNotLocked(function (event, from, to) {
10358 popcorn.currentTime(timings[to.toString()]);
10363 var updatePlayPause = function() {
10364 $('.playpause').each(function() {
10365 updatePlayPauseClass(popcorn.paused(), this, 'pause', 'play');
10368 audio.addEventListener('pause', updatePlayPause);
10369 audio.addEventListener('playing', updatePlayPause);
10370 audio.addEventListener('timeupdate', function () {
10371 var estimatedTotal = popcorn.duration();
10372 var pc = 100 * audio.currentTime / estimatedTotal;
10373 var timeTxt = timeString(audio.currentTime);
10374 $(options.selectors.browsercastTimeLabel).css('left', pc+'%').text(timeTxt);
10377 $document.unbind('keydown.deckbcast').bind('keydown.deckbcast', function(e) {
10378 //opts.keys.scale || $.inArray(e.which, opts.keys.scale) > -1) {
10379 if (e.which === 32) {
10380 togglePlay(popcorn);
10381 e.preventDefault();
10385 trySetCueLengthAndPlay(20, 10);
10389 function leftPad(number, targetLength, padding) {
10390 padding = padding || ' ';
10391 var output = number + '';
10392 while (output.length < targetLength) {
10393 output = padding + output;
10398 // Start recording a 'cast
10399 // In the end you can get the slide HTML with the cue attributes set
10401 // browsercastRecorder.getHTMLSlides()
10402 // in the Javascript console.
10404 // Press 'Left' on the first slide to start recording.
10405 function recordBrowserCast(options) {
10407 var bc = $(options.selectors.browsercast);
10408 $(options.selectors.browsercastAudio).attr('controls', 'true');
10409 $(options.selectors.browsercastMarkers).hide();
10410 setTimeout(function(){ $.deck('go', 0); logs = [{time:0, slide:0}];}, 200);
10412 var $document = $(document);
10413 var audio = $(options.selectors.browsercastAudio).get(0);
10414 var logs = []; // as a list of pairs, so we can have multiple values and clean afterwards
10415 var exportLogs = function() {
10421 res += leftPad('"'+logs[i].slide+'"', 8) + ':' + leftPad(logs[i].time.toFixed(2), 6);
10427 $document.bind('deck.change', function(event, from, to) {
10428 logs.push({time: audio.currentTime, slide: to});
10430 $document.unbind('keydown.deckbcastrecord').bind('keydown.deckbcastrecord', function(e) {
10431 if (e.which === 84) { // 't'
10437 function unsetKey(which, fromWhat) {
10438 if ($.isArray(fromWhat)) {
10440 while( (match = fromWhat.indexOf(which)) > -1 ) {
10441 fromWhat.splice(match, 1);
10443 } else if ($.isPlainObject(fromWhat)) {
10444 for (var p in fromWhat) {
10445 if (fromWhat.hasOwnProperty(p)) {
10446 unsetKey(which, fromWhat[p]);
10453 $.extend(true, $.deck.defaults, {
10455 browsercast: '.browsercast',
10456 browsercastAudio: '.browsercast-audio',
10457 browsercastMarkers: '.browsercast-markers',
10458 browsercastTimeLabel: '.browsercast-time-label'
10463 browsercastAlways: false
10472 unsetKey(32, $.deck.defaults.keys); // unbind space from 'next slide'
10473 $document.bind('deck.init', function() {
10474 var options = $.deck('getOptions');
10475 var audioDataFile = $('html>head>meta[name="audio"]').attr('content');
10476 if (audioDataFile === undefined) {
10479 maybeAddSnippet(audioDataFile, options);
10480 var timingDataFile = $('html>head>meta[name="timings"]').attr('content');
10481 if (timingDataFile === undefined) {
10482 recordBrowserCast(options);
10484 $.getJSON(timingDataFile, function(timings) {
10485 playBrowserCast(timings, options);
10486 }).fail(function( jqxhr, textStatus, error ) {
10487 var err = textStatus + ', ' + error;
10488 console.log('[Browsercast] Request Failed: ' + err);
10489 if (options.alert.browsercast) {
10490 alert('Timing file "' + timingDataFile + '" referenced but it was not found or wrong.\n' +
10491 'See console logs for more details.\n' +
10492 "Browsercast replay won't work, falling back to timing recording.");
10494 recordBrowserCast();
10499 })(window, window.document, jQuery, 'deck', this);
10500 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 {\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 /*\n height: 100px;\n width: 100px;\n */\n font-size: 10px;\n display: inline-block;\n position: absolute;\n left: 0%;\n transition: left 200ms linear;\n top: -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: 7px solid transparent;\n border-top-color: grey;\n \n top: 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: 1em; height: 10px;\n left: 3em; right: 1em;\n background-color: #e3e3e3;\n}\n") }