2 This is a packed deck.js with some extensions and styles.
3 It has been generated from version 16322c026d0e5b6e9953e12362ca665d5d09304e .
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() {
300 window.defaultDeckCallIsAnError = true;
301 $.deck('init', conf);
305 // delay and callback logic
308 setTimeout(doIt, initDelay);
317 /*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license
318 //@ sourceMappingURL=jquery-1.10.2.min.map
320 (function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.2",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav></:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t
321 }({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Ct=/^(?:checkbox|radio)$/i,Nt=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle);
322 u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=un(e,t),Pt.detach()),Gt[e]=n),n}function un(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,n){x.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(x.css(e,"display"))?x.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x.support.opacity||(x.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=x.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===x.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,n){return n?x.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,n){x.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?x(e).position()[n]+"px":r):t}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!x.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||x.css(e,"display"))},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(x.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Ct.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),x.param=function(e,n){var r,i=[],o=function(e,t){t=x.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}x.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var mn,yn,vn=x.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Cn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Nn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=x.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=o.href}catch(Ln){yn=a.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(T)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(l){var u;return o[l]=!0,x.each(e[l]||[],function(e,l){var c=l(n,r,i);return"string"!=typeof c||a||o[c]?a?!(u=c):t:(n.dataTypes.unshift(c),s(c),!1)}),u}return s(n.dataTypes[0])||!o["*"]&&s("*")}function _n(e,n){var r,i,o=x.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,l=e.indexOf(" ");return l>=0&&(i=e.slice(l,e.length),e=e.slice(0,l)),x.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&x.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?x("<div>").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?"80":"443"))===(mn[3]||("http:"===mn[1]?"80":"443")))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Fn.push(o)),s&&x.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(a=n.start=+a||+r||0,n.unit=o,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);(i||x._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=x.timers,a=x._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,x.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window);
323 /* Modernizr 2.0.6 (Custom Build) | MIT & BSD
324 * Contains: fontface | backgroundsize | borderimage | borderradius | boxshadow | flexbox | hsla | multiplebgs | opacity | rgba | textshadow | cssanimations | csscolumns | generatedcontent | cssgradients | cssreflections | csstransforms | csstransforms3d | csstransitions | applicationcache | canvas | canvastext | draganddrop | hashchange | history | audio | video | indexeddb | input | inputtypes | localstorage | postmessage | sessionstorage | websockets | websqldatabase | webworkers | geolocation | inlinesvg | smil | svg | svgclippaths | touch | webgl | iepp | cssclasses | addtest | teststyles | testprop | testallprops | hasevent | prefixes | domprefixes | load
326 ;window.Modernizr=function(a,b,c){function H(){e.input=function(a){for(var b=0,c=a.length;b<c;b++)t[a[b]]=a[b]in l;return t}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),e.inputtypes=function(a){for(var d=0,e,f,h,i=a.length;d<i;d++)l.setAttribute("type",f=a[d]),e=l.type!=="text",e&&(l.value=m,l.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(f)&&l.style.WebkitAppearance!==c?(g.appendChild(l),h=b.defaultView,e=h.getComputedStyle&&h.getComputedStyle(l,null).WebkitAppearance!=="textfield"&&l.offsetHeight!==0,g.removeChild(l)):/^(search|tel)$/.test(f)||(/^(url|email)$/.test(f)?e=l.checkValidity&&l.checkValidity()===!1:/^color$/.test(f)?(g.appendChild(l),g.offsetWidth,e=l.value!=m,g.removeChild(l)):e=l.value!=m)),s[a[d]]=!!e;return s}("search tel url email datetime date month week time datetime-local number range color".split(" "))}function F(a,b){var c=a.charAt(0).toUpperCase()+a.substr(1),d=(a+" "+p.join(c+" ")+c).split(" ");return E(d,b)}function E(a,b){for(var d in a)if(k[a[d]]!==c)return b=="pfx"?a[d]:!0;return!1}function D(a,b){return!!~(""+a).indexOf(b)}function C(a,b){return typeof a===b}function B(a,b){return A(o.join(a+";")+(b||""))}function A(a){k.cssText=a}var d="2.0.6",e={},f=!0,g=b.documentElement,h=b.head||b.getElementsByTagName("head")[0],i="modernizr",j=b.createElement(i),k=j.style,l=b.createElement("input"),m=":)",n=Object.prototype.toString,o=" -webkit- -moz- -o- -ms- -khtml- ".split(" "),p="Webkit Moz O ms Khtml".split(" "),q={svg:"http://www.w3.org/2000/svg"},r={},s={},t={},u=[],v=function(a,c,d,e){var f,h,j,k=b.createElement("div");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:i+(d+1),k.appendChild(j);f=["­","<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))};
329 Copyright (c) 2011-2014 Caleb Troughton
330 Dual licensed under the MIT license.
331 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
335 The deck.core module provides all the basic functionality for creating and
336 moving through a deck. It does so by applying classes to indicate the state of
337 the deck and its slides, allowing CSS to take care of the visual representation
338 of each state. It also provides methods for navigating the deck and inspecting
339 its state, as well as basic key bindings for going to the next and previous
340 slides. More functionality is provided by wholly separate extension modules
341 that use the API provided by core.
343 (function($, undefined) {
344 var slides, currentIndex, $container, $fragmentLinks;
348 This event fires at the beginning of a slide change, before the actual
349 change occurs. Its purpose is to give extension authors a way to prevent
350 the slide change from occuring. This is done by calling preventDefault
351 on the event object within this event. If that is done, the deck.change
352 event will never be fired and the slide will not change.
354 beforeChange: 'deck.beforeChange',
357 This event fires whenever the current slide changes, whether by way of
358 next, prev, or go. The callback function is passed two parameters, from
359 and to, equal to the indices of the old slide and the new slide
360 respectively. If preventDefault is called on the event within this handler
361 the slide change does not occur.
363 $(document).bind('deck.change', function(event, from, to) {
364 alert('Moving from slide ' + from + ' to ' + to);
367 change: 'deck.change',
370 This event fires at the beginning of deck initialization. This event makes
371 a good hook for preprocessing extensions looking to modify the DOM before
372 the deck is fully initialized. It is also possible to halt the deck.init
373 event from firing while you do things in beforeInit. This can be done by
374 calling lockInit on the event object passed to this event. The init can be
375 released by calling releaseInit.
377 $(document).bind('deck.beforeInit', function(event) {
378 event.lockInit(); // halts deck.init event
379 window.setTimeout(function() {
380 event.releaseInit(); // deck.init will now fire 2 seconds later
384 The init event will be fired regardless of locks after
385 options.initLockTimeout milliseconds.
387 beforeInitialize: 'deck.beforeInit',
390 This event fires at the end of deck initialization. Extensions should
391 implement any code that relies on user extensible options (key bindings,
392 element selectors, classes) within a handler for this event. Native
393 events associated with Deck JS should be scoped under a .deck event
394 namespace, as with the example below:
396 var $d = $(document);
397 $.deck.defaults.keys.myExtensionKeycode = 70; // 'h'
398 $d.bind('deck.init', function() {
399 $d.bind('keydown.deck', function(event) {
400 if (event.which === $.deck.getOptions().keys.myExtensionKeycode) {
406 initialize: 'deck.init'
410 var $document = $(document);
411 var $window = $(window);
412 var stopPropagation = function(event) {
413 event.stopPropagation();
416 var updateContainerState = function() {
417 var oldIndex = $container.data('onSlide');
418 $container.removeClass(options.classes.onPrefix + oldIndex);
419 $container.addClass(options.classes.onPrefix + currentIndex);
420 $container.data('onSlide', currentIndex);
423 var updateChildCurrent = function() {
424 var $oldCurrent = $('.' + options.classes.current);
425 var $oldParents = $oldCurrent.parentsUntil(options.selectors.container);
426 var $newCurrent = slides[currentIndex];
427 var $newParents = $newCurrent.parentsUntil(options.selectors.container);
428 $oldParents.removeClass(options.classes.childCurrent);
429 $newParents.addClass(options.classes.childCurrent);
432 var removeOldSlideStates = function() {
434 $.each(slides, function(i, el) {
438 options.classes.before,
439 options.classes.previous,
440 options.classes.current,
441 options.classes.next,
442 options.classes.after
446 var addNewSlideStates = function() {
447 slides[currentIndex].addClass(options.classes.current);
448 if (currentIndex > 0) {
449 slides[currentIndex-1].addClass(options.classes.previous);
451 if (currentIndex + 1 < slides.length) {
452 slides[currentIndex+1].addClass(options.classes.next);
454 if (currentIndex > 1) {
455 $.each(slides.slice(0, currentIndex - 1), function(i, $slide) {
456 $slide.addClass(options.classes.before);
459 if (currentIndex + 2 < slides.length) {
460 $.each(slides.slice(currentIndex+2), function(i, $slide) {
461 $slide.addClass(options.classes.after);
466 var setAriaHiddens = function() {
467 $(options.selectors.slides).each(function() {
468 var $slide = $(this);
469 var isSub = $slide.closest('.' + options.classes.childCurrent).length;
470 var isBefore = $slide.hasClass(options.classes.before) && !isSub;
471 var isPrevious = $slide.hasClass(options.classes.previous) && !isSub;
472 var isNext = $slide.hasClass(options.classes.next);
473 var isAfter = $slide.hasClass(options.classes.after);
474 var ariaHiddenValue = isBefore || isPrevious || isNext || isAfter;
475 $slide.attr('aria-hidden', ariaHiddenValue);
479 var updateStates = function() {
480 updateContainerState();
481 updateChildCurrent();
482 removeOldSlideStates();
484 if (options.setAriaHiddens) {
489 var initSlidesArray = function(elements) {
490 if ($.isArray(elements)) {
491 $.each(elements, function(i, element) {
492 slides.push($(element));
496 $(elements).each(function(i, element) {
497 slides.push($(element));
502 var bindKeyEvents = function() {
513 $document.unbind('keydown.deck').bind('keydown.deck', function(event) {
514 var isNext = event.which === options.keys.next;
515 var isPrev = event.which === options.keys.previous;
516 isNext = isNext || $.inArray(event.which, options.keys.next) > -1;
517 isPrev = isPrev || $.inArray(event.which, options.keys.previous) > -1;
521 event.preventDefault();
525 event.preventDefault();
529 $document.undelegate(editables, 'keydown.deck', stopPropagation);
530 $document.delegate(editables, 'keydown.deck', stopPropagation);
533 var bindTouchEvents = function() {
535 var direction = options.touch.swipeDirection;
536 var tolerance = options.touch.swipeTolerance;
537 var listenToHorizontal = ({ both: true, horizontal: true })[direction];
538 var listenToVertical = ({ both: true, vertical: true })[direction];
540 $container.unbind('touchstart.deck');
541 $container.bind('touchstart.deck', function(event) {
543 startTouch = $.extend({}, event.originalEvent.targetTouches[0]);
547 $container.unbind('touchmove.deck');
548 $container.bind('touchmove.deck', function(event) {
549 $.each(event.originalEvent.changedTouches, function(i, touch) {
550 if (!startTouch || touch.identifier !== startTouch.identifier) {
553 var xDistance = touch.screenX - startTouch.screenX;
554 var yDistance = touch.screenY - startTouch.screenY;
555 var leftToRight = xDistance > tolerance && listenToHorizontal;
556 var rightToLeft = xDistance < -tolerance && listenToHorizontal;
557 var topToBottom = yDistance > tolerance && listenToVertical;
558 var bottomToTop = yDistance < -tolerance && listenToVertical;
560 if (leftToRight || topToBottom) {
562 startTouch = undefined;
564 else if (rightToLeft || bottomToTop) {
566 startTouch = undefined;
571 if (listenToVertical) {
572 event.preventDefault();
576 $container.unbind('touchend.deck');
577 $container.bind('touchend.deck', function(event) {
578 $.each(event.originalEvent.changedTouches, function(i, touch) {
579 if (startTouch && touch.identifier === startTouch.identifier) {
580 startTouch = undefined;
586 var indexInBounds = function(index) {
587 return typeof index === 'number' && index >=0 && index < slides.length;
590 var createBeforeInitEvent = function() {
591 var event = $.Event(events.beforeInitialize);
594 event.lockInit = function() {
597 event.releaseInit = function() {
606 var goByHash = function(str) {
607 var id = str.substr(str.indexOf("#") + 1);
609 $.each(slides, function(i, $slide) {
610 if ($slide.attr('id') === id) {
616 // If we don't set these to 0 the container scrolls due to hashchange
617 if (options.preventFragmentScroll) {
618 $.deck('getContainer').scrollLeft(0).scrollTop(0);
622 var assignSlideId = function(i, $slide) {
623 var currentId = $slide.attr('id');
624 var previouslyAssigned = $slide.data('deckAssignedId') === currentId;
625 if (!currentId || previouslyAssigned) {
626 $slide.attr('id', options.hashPrefix + i);
627 $slide.data('deckAssignedId', options.hashPrefix + i);
631 var removeContainerHashClass = function(id) {
632 $container.removeClass(options.classes.onPrefix + id);
635 var addContainerHashClass = function(id) {
636 $container.addClass(options.classes.onPrefix + id);
639 var setupHashBehaviors = function() {
640 $fragmentLinks = $();
641 $.each(slides, function(i, $slide) {
644 assignSlideId(i, $slide);
645 hash = '#' + $slide.attr('id');
646 altHash = '#/' + $slide.attr('id');
647 if (hash === window.location.hash || altHash === window.location.hash) {
648 setTimeout(function() {
652 $fragmentLinks = $fragmentLinks.add('a[href="' + hash + '"]');
656 addContainerHashClass($.deck('getSlide').attr('id'));
660 var changeHash = function(from, to) {
661 var hash = '#' + $.deck('getSlide', to).attr('id');
662 var hashPath = window.location.href.replace(/#.*/, '') + hash;
664 removeContainerHashClass($.deck('getSlide', from).attr('id'));
665 addContainerHashClass($.deck('getSlide', to).attr('id'));
666 if (Modernizr.history) {
667 window.history.replaceState({}, "", hashPath);
671 /* Methods exposed in the jQuery.deck namespace */
675 jQuery.deck(selector, options)
677 selector: string | jQuery | array
678 options: object, optional
680 Initializes the deck, using each element matched by selector as a slide.
681 May also be passed an array of string selectors or jQuery objects, in
682 which case each selector in the array is considered a slide. The second
683 parameter is an optional options object which will extend the default
686 Users may also pass only an options object to init. In this case the slide
687 selector will be options.selectors.slides which defaults to .slide.
699 init: function(opts) {
700 var beforeInitEvent = createBeforeInitEvent();
701 var overrides = opts;
703 if (!$.isPlainObject(opts)) {
704 overrides = arguments[1] || {};
705 $.extend(true, overrides, {
712 options = $.extend(true, {}, $.deck.defaults, overrides);
715 $container = $(options.selectors.container);
717 // Hide the deck while states are being applied to kill transitions
718 $container.addClass(options.classes.loading);
720 // populate the array of slides for pre-init
721 initSlidesArray(options.selectors.slides);
722 // Pre init event for preprocessing hooks
723 beforeInitEvent.done = function() {
724 // reInitSlidesArray is meant only for beforeInit
725 methods['reInitSlidesArray'] = function() {
726 alert('Deck.js method "reInitSlidesArray" is meant to be called in the beforeInit phase only.');
728 // re-populate the array of slides
730 initSlidesArray(options.selectors.slides);
731 setupHashBehaviors();
734 $container.scrollLeft(0).scrollTop(0);
740 // Show deck again now that slides are in place
741 $container.removeClass(options.classes.loading);
742 $document.trigger(events.initialize);
745 beforeInitEvent.lockInit();
746 $document.trigger(beforeInitEvent);
747 beforeInitEvent.releaseInit();
748 window.setTimeout(function() {
749 if (beforeInitEvent.locks) {
750 if (window.console) {
751 window.console.warn('Something locked deck initialization\
752 without releasing it before the timeout. Proceeding with\
753 initialization anyway.');
755 beforeInitEvent.done();
757 }, options.initLockTimeout);
761 jQuery.deck('reInitSlidesArray')
763 Force a recomputation of the "slides" array. This method is meant
764 to be used by extensions that generate new slides in the
768 reInitSlidesArray: function() {
770 initSlidesArray(options.selectors.slides);
774 jQuery.deck('go', index)
776 index: integer | string
778 Moves to the slide at the specified index if index is a number. Index is
779 0-based, so $.deck('go', 0); will move to the first slide. If index is a
780 string this will move to the slide with the specified id. If index is out
781 of bounds or doesn't match a slide id the call is ignored.
783 go: function(indexOrId) {
784 var beforeChangeEvent = $.Event(events.beforeChange);
787 /* Number index, easy. */
788 if (indexInBounds(indexOrId)) {
791 /* Id string index, search for it and set integer index */
792 else if (typeof indexOrId === 'string') {
793 $.each(slides, function(i, $slide) {
794 if ($slide.attr('id') === indexOrId) {
800 if (typeof index === 'undefined') {
804 /* Trigger beforeChange. If nothing prevents the change, trigger
806 $document.trigger(beforeChangeEvent, [currentIndex, index]);
807 if (!beforeChangeEvent.isDefaultPrevented()) {
808 $document.trigger(events.change, [currentIndex, index]);
809 changeHash(currentIndex, index);
810 currentIndex = index;
818 Moves to the next slide. If the last slide is already active, the call
822 methods.go(currentIndex+1);
828 Moves to the previous slide. If the first slide is already active, the
832 methods.go(currentIndex-1);
836 jQuery.deck('getSlide', index)
838 index: integer, optional
840 Returns a jQuery object containing the slide at index. If index is not
841 specified, the current slide is returned.
843 getSlide: function(index) {
844 index = typeof index !== 'undefined' ? index : currentIndex;
845 if (!indexInBounds(index)) {
848 return slides[index];
852 jQuery.deck('getSlides')
854 Returns all slides as an array of jQuery objects.
856 getSlides: function() {
861 jQuery.deck('getTopLevelSlides')
863 Returns all slides that are not subslides.
865 getTopLevelSlides: function() {
866 var topLevelSlides = [];
867 var slideSelector = options.selectors.slides;
868 var subSelector = [slideSelector, slideSelector].join(' ');
869 $.each(slides, function(i, $slide) {
870 if (!$slide.is(subSelector)) {
871 topLevelSlides.push($slide);
874 return topLevelSlides;
878 jQuery.deck('getNestedSlides', index)
880 index: integer, optional
882 Returns all the nested slides of the current slide. If index is
883 specified it returns the nested slides of the slide at that index.
884 If there are no nested slides this will return an empty array.
886 getNestedSlides: function(index) {
887 var targetIndex = index == null ? currentIndex : index;
888 var $targetSlide = $.deck('getSlide', targetIndex);
889 var $nesteds = $targetSlide.find(options.selectors.slides);
890 var nesteds = $nesteds.get();
891 return $.map(nesteds, function(slide, i) {
898 jQuery.deck('getContainer')
900 Returns a jQuery object containing the deck container as defined by the
903 getContainer: function() {
908 jQuery.deck('getOptions')
910 Returns the options object for the deck, including any overrides that
911 were defined at initialization.
913 getOptions: function() {
918 jQuery.deck('extend', name, method)
923 Adds method to the deck namespace with the key of name. This doesn’t
924 give access to any private member data — public methods must still be
925 used within method — but lets extension authors piggyback on the deck
926 namespace rather than pollute jQuery.
928 $.deck('extend', 'alert', function(msg) {
933 $.deck('alert', 'boom');
935 extend: function(name, method) {
936 methods[name] = method;
940 /* jQuery extension */
941 $.deck = function(method, arg) {
942 var args = Array.prototype.slice.call(arguments, 1);
943 if (methods[method]) {
944 return methods[method].apply(this, args);
947 if (window.defaultDeckCallIsAnError) {
948 alert("'" + method + "' not found (or meant to be a parameter-less init)");
951 return methods.init(method, arg);
957 The default settings object for a deck. All deck extensions should extend
958 this object to add defaults for any of their options.
960 options.classes.after
961 This class is added to all slides that appear after the 'next' slide.
963 options.classes.before
964 This class is added to all slides that appear before the 'previous'
967 options.classes.childCurrent
968 This class is added to all elements in the DOM tree between the
969 'current' slide and the deck container. For standard slides, this is
970 mostly seen and used for nested slides.
972 options.classes.current
973 This class is added to the current slide.
975 options.classes.loading
976 This class is applied to the deck container during loading phases and is
977 primarily used as a way to short circuit transitions between states
978 where such transitions are distracting or unwanted. For example, this
979 class is applied during deck initialization and then removed to prevent
980 all the slides from appearing stacked and transitioning into place
984 This class is added to the slide immediately following the 'current'
987 options.classes.onPrefix
988 This prefix, concatenated with the current slide index, is added to the
989 deck container as you change slides.
991 options.classes.previous
992 This class is added to the slide immediately preceding the 'current'
995 options.selectors.container
996 Elements matched by this CSS selector will be considered the deck
997 container. The deck container is used to scope certain states of the
998 deck, as with the onPrefix option, or with extensions such as deck.goto
1001 options.selectors.slides
1002 Elements matched by this selector make up the individual deck slides.
1003 If a user chooses to pass the slide selector as the first argument to
1004 $.deck() on initialization it does the same thing as passing in this
1005 option and this option value will be set to the value of that parameter.
1008 The numeric keycode used to go to the next slide.
1010 options.keys.previous
1011 The numeric keycode used to go to the previous slide.
1013 options.touch.swipeDirection
1014 The direction swipes occur to cause slide changes. Can be 'horizontal',
1015 'vertical', or 'both'. Any other value or a falsy value will disable
1016 swipe gestures for navigation.
1018 options.touch.swipeTolerance
1019 The number of pixels the users finger must travel to produce a swipe
1022 options.initLockTimeout
1023 The number of milliseconds the init event will wait for BeforeInit event
1024 locks to be released before firing the init event regardless.
1027 Every slide that does not have an id is assigned one at initialization.
1028 Assigned ids take the form of hashPrefix + slideIndex, e.g., slide-0,
1031 options.preventFragmentScroll
1032 When deep linking to a hash of a nested slide, this scrolls the deck
1033 container to the top, undoing the natural browser behavior of scrolling
1034 to the document fragment on load.
1036 options.setAriaHiddens
1037 When set to true, deck.js will set aria hidden attributes for slides
1038 that do not appear onscreen according to a typical heirarchical
1039 deck structure. You may want to turn this off if you are using a theme
1040 where slides besides the current slide are visible on screen and should
1041 be accessible to screenreaders.
1045 after: 'deck-after',
1046 before: 'deck-before',
1047 childCurrent: 'deck-child-current',
1048 current: 'deck-current',
1049 loading: 'deck-loading',
1051 onPrefix: 'on-slide-',
1052 previous: 'deck-previous'
1056 container: '.deck-container',
1061 // enter, space, page down, right arrow, down arrow,
1062 next: [13, 32, 34, 39, 40],
1063 // backspace, page up, left arrow, up arrow
1064 previous: [8, 33, 37, 38]
1068 swipeDirection: 'horizontal',
1072 initLockTimeout: 10000,
1073 hashPrefix: 'slide-',
1074 preventFragmentScroll: true,
1075 setAriaHiddens: true
1078 $document.ready(function() {
1079 $('html').addClass('ready');
1082 $window.bind('hashchange.deck', function(event) {
1083 if (event.originalEvent && event.originalEvent.newURL) {
1084 goByHash(event.originalEvent.newURL);
1087 goByHash(window.location.hash);
1091 $window.bind('load.deck', function() {
1092 if (options.preventFragmentScroll) {
1093 $container.scrollLeft(0).scrollTop(0);
1098 // Released under MIT license
1099 // Copyright (c) 2009-2010 Dominic Baggott
1100 // Copyright (c) 2009-2010 Ash Berlin
1101 // Copyright (c) 2011 Christoph Dorn <christoph@christophdorn.com> (http://www.christophdorn.com)
1103 /*jshint browser:true, devel:true */
1105 (function( expose ) {
1110 * Markdown processing in Javascript done right. We have very particular views
1111 * on what constitutes 'right' which include:
1113 * - produces well-formed HTML (this means that em and strong nesting is
1116 * - has an intermediate representation to allow processing of parsed data (We
1117 * in fact have two, both as [JsonML]: a markdown tree and an HTML tree).
1119 * - is easily extensible to add new dialects without having to rewrite the
1120 * entire parsing mechanics
1122 * - has a good test suite
1124 * This implementation fulfills all of these (except that the test suite could
1125 * do with expanding to automatically run all the fixtures from other Markdown
1128 * ##### Intermediate Representation
1130 * *TODO* Talk about this :) Its JsonML, but document the node names we use.
1132 * [JsonML]: http://jsonml.org/ "JSON Markup Language"
1134 var Markdown = expose.Markdown = function(dialect) {
1135 switch (typeof dialect) {
1137 this.dialect = Markdown.dialects.Gruber;
1140 this.dialect = dialect;
1143 if ( dialect in Markdown.dialects ) {
1144 this.dialect = Markdown.dialects[dialect];
1147 throw new Error("Unknown Markdown dialect '" + String(dialect) + "'");
1152 this.strong_state = [];
1153 this.debug_indent = "";
1157 * parse( markdown, [dialect] ) -> JsonML
1158 * - markdown (String): markdown string to parse
1159 * - dialect (String | Dialect): the dialect to use, defaults to gruber
1161 * Parse `markdown` and return a markdown document as a Markdown.JsonML tree.
1163 expose.parse = function( source, dialect ) {
1164 // dialect will default if undefined
1165 var md = new Markdown( dialect );
1166 return md.toTree( source );
1170 * toHTML( markdown, [dialect] ) -> String
1171 * toHTML( md_tree ) -> String
1172 * - markdown (String): markdown string to parse
1173 * - md_tree (Markdown.JsonML): parsed markdown tree
1175 * Take markdown (either as a string or as a JsonML tree) and run it through
1176 * [[toHTMLTree]] then turn it into a well-formated HTML fragment.
1178 expose.toHTML = function toHTML( source , dialect , options ) {
1179 var input = expose.toHTMLTree( source , dialect , options );
1181 return expose.renderJsonML( input );
1185 * toHTMLTree( markdown, [dialect] ) -> JsonML
1186 * toHTMLTree( md_tree ) -> JsonML
1187 * - markdown (String): markdown string to parse
1188 * - dialect (String | Dialect): the dialect to use, defaults to gruber
1189 * - md_tree (Markdown.JsonML): parsed markdown tree
1191 * Turn markdown into HTML, represented as a JsonML tree. If a string is given
1192 * to this function, it is first parsed into a markdown tree by calling
1195 expose.toHTMLTree = function toHTMLTree( input, dialect , options ) {
1196 // convert string input to an MD tree
1197 if ( typeof input ==="string" ) input = this.parse( input, dialect );
1199 // Now convert the MD tree to an HTML tree
1201 // remove references from the tree
1202 var attrs = extract_attr( input ),
1205 if ( attrs && attrs.references ) {
1206 refs = attrs.references;
1209 var html = convert_tree_to_html( input, refs , options );
1210 merge_text_nodes( html );
1214 // For Spidermonkey based engines
1215 function mk_block_toSource() {
1216 return "Markdown.mk_block( " +
1217 uneval(this.toString()) +
1219 uneval(this.trailing) +
1221 uneval(this.lineNumber) +
1226 function mk_block_inspect() {
1227 var util = require("util");
1228 return "Markdown.mk_block( " +
1229 util.inspect(this.toString()) +
1231 util.inspect(this.trailing) +
1233 util.inspect(this.lineNumber) +
1238 var mk_block = Markdown.mk_block = function(block, trail, line) {
1239 // Be helpful for default case in tests.
1240 if ( arguments.length == 1 ) trail = "\n\n";
1242 var s = new String(block);
1244 // To make it clear its not just a string
1245 s.inspect = mk_block_inspect;
1246 s.toSource = mk_block_toSource;
1248 if ( line != undefined )
1249 s.lineNumber = line;
1254 function count_lines( str ) {
1256 while ( ( i = str.indexOf("\n", i + 1) ) !== -1 ) n++;
1260 // Internal - split source into rough blocks
1261 Markdown.prototype.split_blocks = function splitBlocks( input, startLine ) {
1262 input = input.replace(/(\r\n|\n|\r)/g, "\n");
1263 // [\s\S] matches _anything_ (newline or space)
1264 // [^] is equivalent but doesn't work in IEs.
1265 var re = /([\s\S]+?)($|\n#|\n(?:\s*\n|$)+)/g,
1271 if ( ( m = /^(\s*\n)/.exec(input) ) != null ) {
1272 // skip (but count) leading blank lines
1273 line_no += count_lines( m[0] );
1274 re.lastIndex = m[0].length;
1277 while ( ( m = re.exec(input) ) !== null ) {
1278 if (m[2] == "\n#") {
1282 blocks.push( mk_block( m[1], m[2], line_no ) );
1283 line_no += count_lines( m[0] );
1290 * Markdown#processBlock( block, next ) -> undefined | [ JsonML, ... ]
1291 * - block (String): the block to process
1292 * - next (Array): the following blocks
1294 * Process `block` and return an array of JsonML nodes representing `block`.
1296 * It does this by asking each block level function in the dialect to process
1297 * the block until one can. Succesful handling is indicated by returning an
1298 * array (with zero or more JsonML nodes), failure by a false value.
1300 * Blocks handlers are responsible for calling [[Markdown#processInline]]
1301 * themselves as appropriate.
1303 * If the blocks were split incorrectly or adjacent blocks need collapsing you
1304 * can adjust `next` in place using shift/splice etc.
1306 * If any of this default behaviour is not right for the dialect, you can
1307 * define a `__call__` method on the dialect that will get invoked to handle
1308 * the block processing.
1310 Markdown.prototype.processBlock = function processBlock( block, next ) {
1311 var cbs = this.dialect.block,
1312 ord = cbs.__order__;
1314 if ( "__call__" in cbs ) {
1315 return cbs.__call__.call(this, block, next);
1318 for ( var i = 0; i < ord.length; i++ ) {
1319 //D:this.debug( "Testing", ord[i] );
1320 var res = cbs[ ord[i] ].call( this, block, next );
1322 //D:this.debug(" matched");
1323 if ( !isArray(res) || ( res.length > 0 && !( isArray(res[0]) ) ) )
1324 this.debug(ord[i], "didn't return a proper array");
1325 //D:this.debug( "" );
1330 // Uhoh! no match! Should we throw an error?
1334 Markdown.prototype.processInline = function processInline( block ) {
1335 return this.dialect.inline.__call__.call( this, String( block ) );
1339 * Markdown#toTree( source ) -> JsonML
1340 * - source (String): markdown source to parse
1342 * Parse `source` into a JsonML tree representing the markdown document.
1344 // custom_tree means set this.tree to `custom_tree` and restore old value on return
1345 Markdown.prototype.toTree = function toTree( source, custom_root ) {
1346 var blocks = source instanceof Array ? source : this.split_blocks( source );
1348 // Make tree a member variable so its easier to mess with in extensions
1349 var old_tree = this.tree;
1351 this.tree = custom_root || this.tree || [ "markdown" ];
1354 while ( blocks.length ) {
1355 var b = this.processBlock( blocks.shift(), blocks );
1357 // Reference blocks and the like won't return any content
1358 if ( !b.length ) continue blocks;
1360 this.tree.push.apply( this.tree, b );
1365 if ( custom_root ) {
1366 this.tree = old_tree;
1372 Markdown.prototype.debug = function () {
1373 var args = Array.prototype.slice.call( arguments);
1374 args.unshift(this.debug_indent);
1375 if ( typeof print !== "undefined" )
1376 print.apply( print, args );
1377 if ( typeof console !== "undefined" && typeof console.log !== "undefined" )
1378 console.log.apply( null, args );
1381 Markdown.prototype.loop_re_over_block = function( re, block, cb ) {
1382 // Dont use /g regexps with this
1384 b = block.valueOf();
1386 while ( b.length && (m = re.exec(b) ) != null ) {
1387 b = b.substr( m[0].length );
1396 * Namespace of built-in dialects.
1398 Markdown.dialects = {};
1401 * Markdown.dialects.Gruber
1403 * The default dialect that follows the rules set out by John Gruber's
1404 * markdown.pl as closely as possible. Well actually we follow the behaviour of
1405 * that script which in some places is not exactly what the syntax web page
1408 Markdown.dialects.Gruber = {
1410 atxHeader: function atxHeader( block, next ) {
1411 var m = block.match( /^(#{1,6})\s*(.*?)\s*#*\s*(?:\n|$)/ );
1413 if ( !m ) return undefined;
1415 var header = [ "header", { level: m[ 1 ].length } ];
1416 Array.prototype.push.apply(header, this.processInline(m[ 2 ]));
1418 if ( m[0].length < block.length )
1419 next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) );
1424 setextHeader: function setextHeader( block, next ) {
1425 var m = block.match( /^(.*)\n([-=])\2\2+(?:\n|$)/ );
1427 if ( !m ) return undefined;
1429 var level = ( m[ 2 ] === "=" ) ? 1 : 2;
1430 var header = [ "header", { level : level }, m[ 1 ] ];
1432 if ( m[0].length < block.length )
1433 next.unshift( mk_block( block.substr( m[0].length ), block.trailing, block.lineNumber + 2 ) );
1438 code: function code( block, next ) {
1441 // should be a code block followed by a paragraph. Fun
1443 // There might also be adjacent code block to merge.
1446 re = /^(?: {0,3}\t| {4})(.*)\n?/,
1449 // 4 spaces + content
1450 if ( !block.match( re ) ) return undefined;
1454 // Now pull out the rest of the lines
1455 var b = this.loop_re_over_block(
1456 re, block.valueOf(), function( m ) { ret.push( m[1] ); } );
1459 // Case alluded to in first comment. push it back on as a new block
1460 next.unshift( mk_block(b, block.trailing) );
1463 else if ( next.length ) {
1464 // Check the next block - it might be code too
1465 if ( !next[0].match( re ) ) break block_search;
1467 // Pull how how many blanks lines follow - minus two to account for .join
1468 ret.push ( block.trailing.replace(/[^\n]/g, "").substring(2) );
1470 block = next.shift();
1477 return [ [ "code_block", ret.join("\n") ] ];
1480 horizRule: function horizRule( block, next ) {
1481 // this needs to find any hr in the block to handle abutting blocks
1482 var m = block.match( /^(?:([\s\S]*?)\n)?[ \t]*([-_*])(?:[ \t]*\2){2,}[ \t]*(?:\n([\s\S]*))?$/ );
1488 var jsonml = [ [ "hr" ] ];
1490 // if there's a leading abutting block, process it
1492 jsonml.unshift.apply( jsonml, this.processBlock( m[ 1 ], [] ) );
1495 // if there's a trailing abutting block, stick it into next
1497 next.unshift( mk_block( m[ 3 ] ) );
1503 // There are two types of lists. Tight and loose. Tight lists have no whitespace
1504 // between the items (and result in text just in the <li>) and loose lists,
1505 // which have an empty line between list items, resulting in (one or more)
1506 // paragraphs inside the <li>.
1508 // There are all sorts weird edge cases about the original markdown.pl's
1509 // handling of lists:
1511 // * Nested lists are supposed to be indented by four chars per level. But
1512 // if they aren't, you can get a nested list by indenting by less than
1513 // four so long as the indent doesn't match an indent of an existing list
1514 // item in the 'nest stack'.
1516 // * The type of the list (bullet or number) is controlled just by the
1517 // first item at the indent. Subsequent changes are ignored unless they
1518 // are for nested lists
1520 lists: (function( ) {
1521 // Use a closure to hide a few variables.
1522 var any_list = "[*+-]|\\d+\\.",
1523 bullet_list = /[*+-]/,
1524 number_list = /\d+\./,
1525 // Capture leading indent as it matters for determining nested lists.
1526 is_list_re = new RegExp( "^( {0,3})(" + any_list + ")[ \t]+" ),
1527 indent_re = "(?: {0,3}\\t| {4})";
1529 // TODO: Cache this regexp for certain depths.
1530 // Create a regexp suitable for matching an li for a given stack depth
1531 function regex_for_depth( depth ) {
1534 // m[1] = indent, m[2] = list_type
1535 "(?:^(" + indent_re + "{0," + depth + "} {0,3})(" + any_list + ")\\s+)|" +
1537 "(^" + indent_re + "{0," + (depth-1) + "}[ ]{0,4})"
1540 function expand_tab( input ) {
1541 return input.replace( / {0,3}\t/g, " " );
1544 // Add inline content `inline` to `li`. inline comes from processInline
1545 // so is an array of content
1546 function add(li, loose, inline, nl) {
1548 li.push( [ "para" ].concat(inline) );
1551 // Hmmm, should this be any block level element or just paras?
1552 var add_to = li[li.length -1] instanceof Array && li[li.length - 1][0] == "para"
1556 // If there is already some content in this list, add the new line in
1557 if ( nl && li.length > 1 ) inline.unshift(nl);
1559 for ( var i = 0; i < inline.length; i++ ) {
1560 var what = inline[i],
1561 is_str = typeof what == "string";
1562 if ( is_str && add_to.length > 1 && typeof add_to[add_to.length-1] == "string" ) {
1563 add_to[ add_to.length-1 ] += what;
1566 add_to.push( what );
1571 // contained means have an indent greater than the current one. On
1572 // *every* line in the block
1573 function get_contained_blocks( depth, blocks ) {
1575 var re = new RegExp( "^(" + indent_re + "{" + depth + "}.*?\\n?)*$" ),
1576 replace = new RegExp("^" + indent_re + "{" + depth + "}", "gm"),
1579 while ( blocks.length > 0 ) {
1580 if ( re.exec( blocks[0] ) ) {
1581 var b = blocks.shift(),
1582 // Now remove that indent
1583 x = b.replace( replace, "");
1585 ret.push( mk_block( x, b.trailing, b.lineNumber ) );
1594 // passed to stack.forEach to turn list items up the stack into paras
1595 function paragraphify(s, i, stack) {
1597 var last_li = list[list.length-1];
1599 if ( last_li[1] instanceof Array && last_li[1][0] == "para" ) {
1602 if ( i + 1 == stack.length ) {
1604 // Keep the same array, but replace the contents
1605 last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ) );
1608 var sublist = last_li.pop();
1609 last_li.push( ["para"].concat( last_li.splice(1, last_li.length - 1) ), sublist );
1613 // The matcher function
1614 return function( block, next ) {
1615 var m = block.match( is_list_re );
1616 if ( !m ) return undefined;
1618 function make_list( m ) {
1619 var list = bullet_list.exec( m[2] )
1623 stack.push( { list: list, indent: m[1] } );
1628 var stack = [], // Stack of lists for nesting.
1629 list = make_list( m ),
1632 ret = [ stack[0].list ],
1635 // Loop to search over block looking for inner block elements and loose lists
1638 // Split into lines preserving new lines at end of line
1639 var lines = block.split( /(?=\n)/ );
1641 // We have to grab all lines for a li and call processInline on them
1642 // once as there are some inline things that can span lines.
1643 var li_accumulate = "";
1645 // Loop over the lines in this block looking for tight lists.
1647 for ( var line_no = 0; line_no < lines.length; line_no++ ) {
1649 l = lines[line_no].replace(/^\n/, function(n) { nl = n; return ""; });
1651 // TODO: really should cache this
1652 var line_re = regex_for_depth( stack.length );
1654 m = l.match( line_re );
1655 //print( "line:", uneval(l), "\nline match:", uneval(m) );
1657 // We have a list item
1658 if ( m[1] !== undefined ) {
1659 // Process the previous list item, if any
1660 if ( li_accumulate.length ) {
1661 add( last_li, loose, this.processInline( li_accumulate ), nl );
1662 // Loose mode will have been dealt with. Reset it
1667 m[1] = expand_tab( m[1] );
1668 var wanted_depth = Math.floor(m[1].length/4)+1;
1669 //print( "want:", wanted_depth, "stack:", stack.length);
1670 if ( wanted_depth > stack.length ) {
1671 // Deep enough for a nested list outright
1672 //print ( "new nested list" );
1673 list = make_list( m );
1674 last_li.push( list );
1675 last_li = list[1] = [ "listitem" ];
1678 // We aren't deep enough to be strictly a new level. This is
1679 // where Md.pl goes nuts. If the indent matches a level in the
1680 // stack, put it there, else put it one deeper then the
1681 // wanted_depth deserves.
1683 for ( i = 0; i < stack.length; i++ ) {
1684 if ( stack[ i ].indent != m[1] ) continue;
1685 list = stack[ i ].list;
1686 stack.splice( i+1, stack.length - (i+1) );
1692 //print("not found. l:", uneval(l));
1694 if ( wanted_depth <= stack.length ) {
1695 stack.splice(wanted_depth, stack.length - wanted_depth);
1696 //print("Desired depth now", wanted_depth, "stack:", stack.length);
1697 list = stack[wanted_depth-1].list;
1698 //print("list:", uneval(list) );
1701 //print ("made new stack for messy indent");
1702 list = make_list(m);
1707 //print( uneval(list), "last", list === stack[stack.length-1].list );
1708 last_li = [ "listitem" ];
1710 } // end depth of shenegains
1715 if ( l.length > m[0].length ) {
1716 li_accumulate += nl + l.substr( m[0].length );
1720 if ( li_accumulate.length ) {
1721 add( last_li, loose, this.processInline( li_accumulate ), nl );
1722 // Loose mode will have been dealt with. Reset it
1727 // Look at the next block - we might have a loose list. Or an extra
1728 // paragraph for the current li
1729 var contained = get_contained_blocks( stack.length, next );
1731 // Deal with code blocks or properly nested lists
1732 if ( contained.length > 0 ) {
1733 // Make sure all listitems up the stack are paragraphs
1734 forEach( stack, paragraphify, this);
1736 last_li.push.apply( last_li, this.toTree( contained, [] ) );
1739 var next_block = next[0] && next[0].valueOf() || "";
1741 if ( next_block.match(is_list_re) || next_block.match( /^ / ) ) {
1742 block = next.shift();
1744 // Check for an HR following a list: features/lists/hr_abutting
1745 var hr = this.dialect.block.horizRule( block, next );
1748 ret.push.apply(ret, hr);
1752 // Make sure all listitems up the stack are paragraphs
1753 forEach( stack, paragraphify, this);
1756 continue loose_search;
1765 blockquote: function blockquote( block, next ) {
1766 if ( !block.match( /^>/m ) )
1771 // separate out the leading abutting block, if any. I.e. in this case:
1776 if ( block[ 0 ] != ">" ) {
1777 var lines = block.split( /\n/ ),
1779 line_no = block.lineNumber;
1781 // keep shifting lines until you find a crotchet
1782 while ( lines.length && lines[ 0 ][ 0 ] != ">" ) {
1783 prev.push( lines.shift() );
1787 var abutting = mk_block( prev.join( "\n" ), "\n", block.lineNumber );
1788 jsonml.push.apply( jsonml, this.processBlock( abutting, [] ) );
1789 // reassemble new block of just block quotes!
1790 block = mk_block( lines.join( "\n" ), block.trailing, line_no );
1794 // if the next block is also a blockquote merge it in
1795 while ( next.length && next[ 0 ][ 0 ] == ">" ) {
1796 var b = next.shift();
1797 block = mk_block( block + block.trailing + b, b.trailing, block.lineNumber );
1800 // Strip off the leading "> " and re-process as a block.
1801 var input = block.replace( /^> ?/gm, "" ),
1802 old_tree = this.tree,
1803 processedBlock = this.toTree( input, [ "blockquote" ] ),
1804 attr = extract_attr( processedBlock );
1806 // If any link references were found get rid of them
1807 if ( attr && attr.references ) {
1808 delete attr.references;
1809 // And then remove the attribute object if it's empty
1810 if ( isEmpty( attr ) ) {
1811 processedBlock.splice( 1, 1 );
1815 jsonml.push( processedBlock );
1819 referenceDefn: function referenceDefn( block, next) {
1820 var re = /^\s*\[(.*?)\]:\s*(\S+)(?:\s+(?:(['"])(.*?)\3|\((.*?)\)))?\n?/;
1821 // interesting matches are [ , ref_id, url, , title, title ]
1823 if ( !block.match(re) )
1826 // make an attribute node if it doesn't exist
1827 if ( !extract_attr( this.tree ) ) {
1828 this.tree.splice( 1, 0, {} );
1831 var attrs = extract_attr( this.tree );
1833 // make a references hash if it doesn't exist
1834 if ( attrs.references === undefined ) {
1835 attrs.references = {};
1838 var b = this.loop_re_over_block(re, block, function( m ) {
1840 if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" )
1841 m[2] = m[2].substring( 1, m[2].length - 1 );
1843 var ref = attrs.references[ m[1].toLowerCase() ] = {
1847 if ( m[4] !== undefined )
1849 else if ( m[5] !== undefined )
1855 next.unshift( mk_block( b, block.trailing ) );
1860 para: function para( block, next ) {
1861 // everything's a para!
1862 return [ ["para"].concat( this.processInline( block ) ) ];
1867 Markdown.dialects.Gruber.inline = {
1869 __oneElement__: function oneElement( text, patterns_or_re, previous_nodes ) {
1874 patterns_or_re = patterns_or_re || this.dialect.inline.__patterns__;
1875 var re = new RegExp( "([\\s\\S]*?)(" + (patterns_or_re.source || patterns_or_re) + ")" );
1877 m = re.exec( text );
1880 return [ text.length, text ];
1883 // Some un-interesting text matched. Return that first
1884 return [ m[1].length, m[1] ];
1888 if ( m[2] in this.dialect.inline ) {
1889 res = this.dialect.inline[ m[2] ].call(
1891 text.substr( m.index ), m, previous_nodes || [] );
1893 // Default for now to make dev easier. just slurp special and output it.
1894 res = res || [ m[2].length, m[2] ];
1898 __call__: function inline( text, patterns ) {
1904 //D:self.debug(" adding output", uneval(x));
1905 if ( typeof x == "string" && typeof out[out.length-1] == "string" )
1906 out[ out.length-1 ] += x;
1911 while ( text.length > 0 ) {
1912 res = this.dialect.inline.__oneElement__.call(this, text, patterns, out );
1913 text = text.substr( res.shift() );
1920 // These characters are intersting elsewhere, so have rules for them so that
1921 // chunks of plain text blocks don't include them
1922 "]": function () {},
1923 "}": function () {},
1925 __escape__ : /^\\[\\`\*_{}\[\]()#\+.!\-]/,
1927 "\\": function escaped( text ) {
1928 // [ length of input processed, node/children to add... ]
1929 // Only esacape: \ ` * _ { } [ ] ( ) # * + - . !
1930 if ( this.dialect.inline.__escape__.exec( text ) )
1931 return [ 2, text.charAt( 1 ) ];
1937 "![": function image( text ) {
1939 // Unlike images, alt text is plain text only. no other elements are
1942 // ![Alt text](/path/to/img.jpg "Optional title")
1943 // 1 2 3 4 <--- captures
1944 var m = text.match( /^!\[(.*?)\][ \t]*\([ \t]*([^")]*?)(?:[ \t]+(["'])(.*?)\3)?[ \t]*\)/ );
1947 if ( m[2] && m[2][0] == "<" && m[2][m[2].length-1] == ">" )
1948 m[2] = m[2].substring( 1, m[2].length - 1 );
1950 m[2] = this.dialect.inline.__call__.call( this, m[2], /\\/ )[0];
1952 var attrs = { alt: m[1], href: m[2] || "" };
1953 if ( m[4] !== undefined)
1956 return [ m[0].length, [ "img", attrs ] ];
1960 m = text.match( /^!\[(.*?)\][ \t]*\[(.*?)\]/ );
1963 // We can't check if the reference is known here as it likely wont be
1964 // found till after. Check it in md tree->hmtl tree conversion
1965 return [ m[0].length, [ "img_ref", { alt: m[1], ref: m[2].toLowerCase(), original: m[0] } ] ];
1968 // Just consume the '!['
1972 "[": function link( text ) {
1974 var orig = String(text);
1975 // Inline content is possible inside `link text`
1976 var res = Markdown.DialectHelpers.inline_until_char.call( this, text.substr(1), "]" );
1978 // No closing ']' found. Just consume the [
1979 if ( !res ) return [ 1, "[" ];
1981 var consumed = 1 + res[ 0 ],
1982 children = res[ 1 ],
1986 // At this point the first [...] has been parsed. See what follows to find
1987 // out which kind of link we are (reference or direct url)
1988 text = text.substr( consumed );
1990 // [link text](/path/to/img.jpg "Optional title")
1991 // 1 2 3 <--- captures
1992 // This will capture up to the last paren in the block. We then pull
1993 // back based on if there a matching ones in the url
1994 // ([here](/url/(test))
1995 // The parens have to be balanced
1996 var m = text.match( /^\s*\([ \t]*([^"']*)(?:[ \t]+(["'])(.*?)\2)?[ \t]*\)/ );
1999 consumed += m[0].length;
2001 if ( url && url[0] == "<" && url[url.length-1] == ">" )
2002 url = url.substring( 1, url.length - 1 );
2004 // If there is a title we don't have to worry about parens in the url
2006 var open_parens = 1; // One open that isn't in the capture
2007 for ( var len = 0; len < url.length; len++ ) {
2008 switch ( url[len] ) {
2013 if ( --open_parens == 0) {
2014 consumed -= url.length - len;
2015 url = url.substring(0, len);
2022 // Process escapes only
2023 url = this.dialect.inline.__call__.call( this, url, /\\/ )[0];
2025 attrs = { href: url || "" };
2026 if ( m[3] !== undefined)
2029 link = [ "link", attrs ].concat( children );
2030 return [ consumed, link ];
2035 m = text.match( /^\s*\[(.*?)\]/ );
2039 consumed += m[ 0 ].length;
2041 // [links][] uses links as its reference
2042 attrs = { ref: ( m[ 1 ] || String(children) ).toLowerCase(), original: orig.substr( 0, consumed ) };
2044 link = [ "link_ref", attrs ].concat( children );
2046 // We can't check if the reference is known here as it likely wont be
2047 // found till after. Check it in md tree->hmtl tree conversion.
2048 // Store the original so that conversion can revert if the ref isn't found.
2049 return [ consumed, link ];
2053 // Only if id is plain (no formatting.)
2054 if ( children.length == 1 && typeof children[0] == "string" ) {
2056 attrs = { ref: children[0].toLowerCase(), original: orig.substr( 0, consumed ) };
2057 link = [ "link_ref", attrs, children[0] ];
2058 return [ consumed, link ];
2061 // Just consume the "["
2066 "<": function autoLink( text ) {
2069 if ( ( m = text.match( /^<(?:((https?|ftp|mailto):[^>]+)|(.*?@.*?\.[a-zA-Z]+))>/ ) ) != null ) {
2071 return [ m[0].length, [ "link", { href: "mailto:" + m[3] }, m[3] ] ];
2074 else if ( m[2] == "mailto" ) {
2075 return [ m[0].length, [ "link", { href: m[1] }, m[1].substr("mailto:".length ) ] ];
2078 return [ m[0].length, [ "link", { href: m[1] }, m[1] ] ];
2084 "`": function inlineCode( text ) {
2085 // Inline code block. as many backticks as you like to start it
2086 // Always skip over the opening ticks.
2087 var m = text.match( /(`+)(([\s\S]*?)\1)/ );
2090 return [ m[1].length + m[2].length, [ "inlinecode", m[3] ] ];
2092 // TODO: No matching end code found - warn!
2097 " \n": function lineBreak( text ) {
2098 return [ 3, [ "linebreak" ] ];
2103 // Meta Helper/generator method for em and strong handling
2104 function strong_em( tag, md ) {
2106 var state_slot = tag + "_state",
2107 other_slot = tag == "strong" ? "em_state" : "strong_state";
2109 function CloseTag(len) {
2110 this.len_after = len;
2111 this.name = "close_" + md;
2114 return function ( text, orig_match ) {
2116 if ( this[state_slot][0] == md ) {
2117 // Most recent em is of this type
2118 //D:this.debug("closing", md);
2119 this[state_slot].shift();
2121 // "Consume" everything to go back to the recrusion in the else-block below
2122 return[ text.length, new CloseTag(text.length-md.length) ];
2125 // Store a clone of the em/strong states
2126 var other = this[other_slot].slice(),
2127 state = this[state_slot].slice();
2129 this[state_slot].unshift(md);
2131 //D:this.debug_indent += " ";
2134 var res = this.processInline( text.substr( md.length ) );
2135 //D:this.debug_indent = this.debug_indent.substr(2);
2137 var last = res[res.length - 1];
2139 //D:this.debug("processInline from", tag + ": ", uneval( res ) );
2141 var check = this[state_slot].shift();
2142 if ( last instanceof CloseTag ) {
2144 // We matched! Huzzah.
2145 var consumed = text.length - last.len_after;
2146 return [ consumed, [ tag ].concat(res) ];
2149 // Restore the state of the other kind. We might have mistakenly closed it.
2150 this[other_slot] = other;
2151 this[state_slot] = state;
2153 // We can't reuse the processed result as it could have wrong parsing contexts in it.
2154 return [ md.length, md ];
2157 }; // End returned function
2160 Markdown.dialects.Gruber.inline["**"] = strong_em("strong", "**");
2161 Markdown.dialects.Gruber.inline["__"] = strong_em("strong", "__");
2162 Markdown.dialects.Gruber.inline["*"] = strong_em("em", "*");
2163 Markdown.dialects.Gruber.inline["_"] = strong_em("em", "_");
2166 // Build default order from insertion order.
2167 Markdown.buildBlockOrder = function(d) {
2169 for ( var i in d ) {
2170 if ( i == "__order__" || i == "__call__" ) continue;
2176 // Build patterns for inline matcher
2177 Markdown.buildInlinePatterns = function(d) {
2180 for ( var i in d ) {
2181 // __foo__ is reserved and not a pattern
2182 if ( i.match( /^__.*__$/) ) continue;
2183 var l = i.replace( /([\\.*+?|()\[\]{}])/g, "\\$1" )
2184 .replace( /\n/, "\\n" );
2185 patterns.push( i.length == 1 ? l : "(?:" + l + ")" );
2188 patterns = patterns.join("|");
2189 d.__patterns__ = patterns;
2190 //print("patterns:", uneval( patterns ) );
2192 var fn = d.__call__;
2193 d.__call__ = function(text, pattern) {
2194 if ( pattern != undefined ) {
2195 return fn.call(this, text, pattern);
2199 return fn.call(this, text, patterns);
2204 Markdown.DialectHelpers = {};
2205 Markdown.DialectHelpers.inline_until_char = function( text, want ) {
2210 if ( text.charAt( consumed ) == want ) {
2211 // Found the character we were looking for
2213 return [ consumed, nodes ];
2216 if ( consumed >= text.length ) {
2217 // No closing char found. Abort.
2221 var res = this.dialect.inline.__oneElement__.call(this, text.substr( consumed ) );
2222 consumed += res[ 0 ];
2223 // Add any returned nodes.
2224 nodes.push.apply( nodes, res.slice( 1 ) );
2228 // Helper function to make sub-classing a dialect easier
2229 Markdown.subclassDialect = function( d ) {
2231 Block.prototype = d.block;
2232 function Inline() {}
2233 Inline.prototype = d.inline;
2235 return { block: new Block(), inline: new Inline() };
2238 Markdown.buildBlockOrder ( Markdown.dialects.Gruber.block );
2239 Markdown.buildInlinePatterns( Markdown.dialects.Gruber.inline );
2241 Markdown.dialects.Maruku = Markdown.subclassDialect( Markdown.dialects.Gruber );
2243 Markdown.dialects.Maruku.processMetaHash = function processMetaHash( meta_string ) {
2244 var meta = split_meta_hash( meta_string ),
2247 for ( var i = 0; i < meta.length; ++i ) {
2249 if ( /^#/.test( meta[ i ] ) ) {
2250 attr.id = meta[ i ].substring( 1 );
2253 else if ( /^\./.test( meta[ i ] ) ) {
2254 // if class already exists, append the new one
2255 if ( attr["class"] ) {
2256 attr["class"] = attr["class"] + meta[ i ].replace( /./, " " );
2259 attr["class"] = meta[ i ].substring( 1 );
2262 // attribute: foo=bar
2263 else if ( /\=/.test( meta[ i ] ) ) {
2264 var s = meta[ i ].split( /\=/ );
2265 attr[ s[ 0 ] ] = s[ 1 ];
2272 function split_meta_hash( meta_string ) {
2273 var meta = meta_string.split( "" ),
2277 while ( meta.length ) {
2278 var letter = meta.shift();
2281 // if we're in a quoted section, keep it
2283 parts[ parts.length - 1 ] += letter;
2285 // otherwise make a new part
2292 // reverse the quotes and move straight on
2293 in_quotes = !in_quotes;
2296 // shift off the next letter to be used straight away.
2297 // it was escaped so we'll keep it whatever it is
2298 letter = meta.shift();
2300 parts[ parts.length - 1 ] += letter;
2308 Markdown.dialects.Maruku.block.document_meta = function document_meta( block, next ) {
2309 // we're only interested in the first block
2310 if ( block.lineNumber > 1 ) return undefined;
2312 // document_meta blocks consist of one or more lines of `Key: Value\n`
2313 if ( ! block.match( /^(?:\w+:.*\n)*\w+:.*$/ ) ) return undefined;
2315 // make an attribute node if it doesn't exist
2316 if ( !extract_attr( this.tree ) ) {
2317 this.tree.splice( 1, 0, {} );
2320 var pairs = block.split( /\n/ );
2321 for ( p in pairs ) {
2322 var m = pairs[ p ].match( /(\w+):\s*(.*)$/ ),
2323 key = m[ 1 ].toLowerCase(),
2326 this.tree[ 1 ][ key ] = value;
2329 // document_meta produces no content!
2333 Markdown.dialects.Maruku.block.block_meta = function block_meta( block, next ) {
2334 // check if the last line of the block is an meta hash
2335 var m = block.match( /(^|\n) {0,3}\{:\s*((?:\\\}|[^\}])*)\s*\}$/ );
2336 if ( !m ) return undefined;
2338 // process the meta hash
2339 var attr = this.dialect.processMetaHash( m[ 2 ] );
2343 // if we matched ^ then we need to apply meta to the previous block
2344 if ( m[ 1 ] === "" ) {
2345 var node = this.tree[ this.tree.length - 1 ];
2346 hash = extract_attr( node );
2348 // if the node is a string (rather than JsonML), bail
2349 if ( typeof node === "string" ) return undefined;
2351 // create the attribute hash if it doesn't exist
2354 node.splice( 1, 0, hash );
2357 // add the attributes in
2359 hash[ a ] = attr[ a ];
2362 // return nothing so the meta hash is removed
2366 // pull the meta hash off the block and process what's left
2367 var b = block.replace( /\n.*$/, "" ),
2368 result = this.processBlock( b, [] );
2370 // get or make the attributes hash
2371 hash = extract_attr( result[ 0 ] );
2374 result[ 0 ].splice( 1, 0, hash );
2377 // attach the attributes to the block
2379 hash[ a ] = attr[ a ];
2385 Markdown.dialects.Maruku.block.definition_list = function definition_list( block, next ) {
2386 // one or more terms followed by one or more definitions, in a single block
2387 var tight = /^((?:[^\s:].*\n)+):\s+([\s\S]+)$/,
2391 // see if we're dealing with a tight or loose block
2392 if ( ( m = block.match( tight ) ) ) {
2393 // pull subsequent tight DL blocks out of `next`
2394 var blocks = [ block ];
2395 while ( next.length && tight.exec( next[ 0 ] ) ) {
2396 blocks.push( next.shift() );
2399 for ( var b = 0; b < blocks.length; ++b ) {
2400 var m = blocks[ b ].match( tight ),
2401 terms = m[ 1 ].replace( /\n$/, "" ).split( /\n/ ),
2402 defns = m[ 2 ].split( /\n:\s+/ );
2404 // print( uneval( m ) );
2406 for ( i = 0; i < terms.length; ++i ) {
2407 list.push( [ "dt", terms[ i ] ] );
2410 for ( i = 0; i < defns.length; ++i ) {
2411 // run inline processing over the definition
2412 list.push( [ "dd" ].concat( this.processInline( defns[ i ].replace( /(\n)\s+/, "$1" ) ) ) );
2423 // splits on unescaped instances of @ch. If @ch is not a character the result
2424 // can be unpredictable
2426 Markdown.dialects.Maruku.block.table = function table (block, next) {
2428 var _split_on_unescaped = function(s, ch) {
2430 if (ch.match(/^[\\|\[\]{}?*.+^$]$/)) { ch = '\\' + ch; }
2432 r = new RegExp('^((?:\\\\.|[^\\\\' + ch + '])*)' + ch + '(.*)'),
2434 while(m = s.match(r)) {
2442 var leading_pipe = /^ {0,3}\|(.+)\n {0,3}\|\s*([\-:]+[\-| :]*)\n((?:\s*\|.*(?:\n|$))*)(?=\n|$)/,
2443 // find at least an unescaped pipe in each line
2444 no_leading_pipe = /^ {0,3}(\S(?:\\.|[^\\|])*\|.*)\n {0,3}([\-:]+\s*\|[\-| :]*)\n((?:(?:\\.|[^\\|])*\|.*(?:\n|$))*)(?=\n|$)/,
2446 if (m = block.match(leading_pipe)) {
2447 // remove leading pipes in contents
2448 // (header and horizontal rule already have the leading pipe left out)
2449 m[3] = m[3].replace(/^\s*\|/gm, '');
2450 } else if (! ( m = block.match(no_leading_pipe))) {
2454 var table = [ "table", [ "thead", [ "tr" ] ], [ "tbody" ] ];
2456 // remove trailing pipes, then split on pipes
2457 // (no escaped pipes are allowed in horizontal rule)
2458 m[2] = m[2].replace(/\|\s*$/, '').split('|');
2460 // process alignment
2461 var html_attrs = [ ];
2462 forEach (m[2], function (s) {
2463 if (s.match(/^\s*-+:\s*$/)) html_attrs.push({align: "right"});
2464 else if (s.match(/^\s*:-+\s*$/)) html_attrs.push({align: "left"});
2465 else if (s.match(/^\s*:-+:\s*$/)) html_attrs.push({align: "center"});
2466 else html_attrs.push({});
2469 // now for the header, avoid escaped pipes
2470 m[1] = _split_on_unescaped(m[1].replace(/\|\s*$/, ''), '|');
2471 for (i = 0; i < m[1].length; i++) {
2472 table[1][1].push(['th', html_attrs[i] || {}].concat(
2473 this.processInline(m[1][i].trim())));
2476 // now for body contents
2477 forEach (m[3].replace(/\|\s*$/mg, '').split('\n'), function (row) {
2478 var html_row = ['tr'];
2479 row = _split_on_unescaped(row, '|');
2480 for (i = 0; i < row.length; i++) {
2481 html_row.push(['td', html_attrs[i] || {}].concat(this.processInline(row[i].trim())));
2483 table[2].push(html_row);
2489 Markdown.dialects.Maruku.inline[ "{:" ] = function inline_meta( text, matches, out ) {
2490 if ( !out.length ) {
2494 // get the preceeding element
2495 var before = out[ out.length - 1 ];
2497 if ( typeof before === "string" ) {
2501 // match a meta hash
2502 var m = text.match( /^\{:\s*((?:\\\}|[^\}])*)\s*\}/ );
2504 // no match, false alarm
2509 // attach the attributes to the preceeding element
2510 var meta = this.dialect.processMetaHash( m[ 1 ] ),
2511 attr = extract_attr( before );
2515 before.splice( 1, 0, attr );
2518 for ( var k in meta ) {
2519 attr[ k ] = meta[ k ];
2522 // cut out the string and replace it with nothing
2523 return [ m[ 0 ].length, "" ];
2526 Markdown.dialects.Maruku.inline.__escape__ = /^\\[\\`\*_{}\[\]()#\+.!\-|:]/;
2528 Markdown.buildBlockOrder ( Markdown.dialects.Maruku.block );
2529 Markdown.buildInlinePatterns( Markdown.dialects.Maruku.inline );
2531 var isArray = Array.isArray || function(obj) {
2532 return Object.prototype.toString.call(obj) == "[object Array]";
2536 // Don't mess with Array.prototype. Its not friendly
2537 if ( Array.prototype.forEach ) {
2538 forEach = function( arr, cb, thisp ) {
2539 return arr.forEach( cb, thisp );
2543 forEach = function(arr, cb, thisp) {
2544 for (var i = 0; i < arr.length; i++) {
2545 cb.call(thisp || arr, arr[i], i, arr);
2550 var isEmpty = function( obj ) {
2551 for ( var key in obj ) {
2552 if ( hasOwnProperty.call( obj, key ) ) {
2560 function extract_attr( jsonml ) {
2561 return isArray(jsonml)
2562 && jsonml.length > 1
2563 && typeof jsonml[ 1 ] === "object"
2564 && !( isArray(jsonml[ 1 ]) )
2572 * renderJsonML( jsonml[, options] ) -> String
2573 * - jsonml (Array): JsonML array to render to XML
2574 * - options (Object): options
2576 * Converts the given JsonML into well-formed XML.
2578 * The options currently understood are:
2580 * - root (Boolean): wether or not the root node should be included in the
2581 * output, or just its children. The default `false` is to not include the
2584 expose.renderJsonML = function( jsonml, options ) {
2585 options = options || {};
2586 // include the root element in the rendered output?
2587 options.root = options.root || false;
2591 if ( options.root ) {
2592 content.push( render_tree( jsonml ) );
2595 jsonml.shift(); // get rid of the tag
2596 if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) {
2597 jsonml.shift(); // get rid of the attributes
2600 while ( jsonml.length ) {
2601 content.push( render_tree( jsonml.shift() ) );
2605 return content.join( "\n\n" );
2608 function escapeHTML( text ) {
2609 return text.replace( /&/g, "&" )
2610 .replace( /</g, "<" )
2611 .replace( />/g, ">" )
2612 .replace( /"/g, """ )
2613 .replace( /'/g, "'" );
2616 function render_tree( jsonml ) {
2618 if ( typeof jsonml === "string" ) {
2619 return jsonml; // modified for deck.smarkdown.js
2622 var tag = jsonml.shift(),
2626 if ( jsonml.length && typeof jsonml[ 0 ] === "object" && !( jsonml[ 0 ] instanceof Array ) ) {
2627 attributes = jsonml.shift();
2630 while ( jsonml.length ) {
2631 content.push( render_tree( jsonml.shift() ) );
2635 for ( var a in attributes ) {
2636 tag_attrs += " " + a + '="' + escapeHTML( attributes[ a ] ) + '"';
2639 // be careful about adding whitespace here for inline elements
2640 if ( tag == "img" || tag == "br" || tag == "hr" ) {
2641 return "<"+ tag + tag_attrs + "/>";
2644 return "<"+ tag + tag_attrs + ">" + content.join( "" ) + "</" + tag + ">";
2648 function convert_tree_to_html( tree, references, options ) {
2650 options = options || {};
2653 var jsonml = tree.slice( 0 );
2655 if ( typeof options.preprocessTreeNode === "function" ) {
2656 jsonml = options.preprocessTreeNode(jsonml, references);
2659 // Clone attributes if they exist
2660 var attrs = extract_attr( jsonml );
2663 for ( i in attrs ) {
2664 jsonml[ 1 ][ i ] = attrs[ i ];
2666 attrs = jsonml[ 1 ];
2670 if ( typeof jsonml === "string" ) {
2674 // convert this node
2675 switch ( jsonml[ 0 ] ) {
2677 jsonml[ 0 ] = "h" + jsonml[ 1 ].level;
2678 delete jsonml[ 1 ].level;
2693 jsonml[ 0 ] = "html";
2694 if ( attrs ) delete attrs.references;
2697 jsonml[ 0 ] = "pre";
2699 var code = [ "code" ];
2700 code.push.apply( code, jsonml.splice( i, jsonml.length - i ) );
2704 jsonml[ 0 ] = "code";
2707 jsonml[ 1 ].src = jsonml[ 1 ].href;
2708 delete jsonml[ 1 ].href;
2719 // grab this ref and clean up the attribute node
2720 var ref = references[ attrs.ref ];
2722 // if the reference exists, make the link
2726 // add in the href and title, if present
2727 attrs.href = ref.href;
2729 attrs.title = ref.title;
2732 // get rid of the unneeded original text
2733 delete attrs.original;
2735 // the reference doesn't exist, so revert to plain text
2737 return attrs.original;
2741 jsonml[ 0 ] = "img";
2743 // grab this ref and clean up the attribute node
2744 var ref = references[ attrs.ref ];
2746 // if the reference exists, make the link
2750 // add in the href and title, if present
2751 attrs.src = ref.href;
2753 attrs.title = ref.title;
2756 // get rid of the unneeded original text
2757 delete attrs.original;
2759 // the reference doesn't exist, so revert to plain text
2761 return attrs.original;
2766 // convert all the children
2769 // deal with the attribute node, if it exists
2771 // if there are keys, skip over it
2772 for ( var key in jsonml[ 1 ] ) {
2776 // if there aren't, remove it
2778 jsonml.splice( i, 1 );
2782 for ( ; i < jsonml.length; ++i ) {
2783 jsonml[ i ] = convert_tree_to_html( jsonml[ i ], references, options );
2790 // merges adjacent text nodes into a single node
2791 function merge_text_nodes( jsonml ) {
2792 // skip the tag name and attribute hash
2793 var i = extract_attr( jsonml ) ? 2 : 1;
2795 while ( i < jsonml.length ) {
2796 // if it's a string check the next item too
2797 if ( typeof jsonml[ i ] === "string" ) {
2798 if ( i + 1 < jsonml.length && typeof jsonml[ i + 1 ] === "string" ) {
2799 // merge the second string into the first and remove it
2800 jsonml[ i ] += jsonml.splice( i + 1, 1 )[ 0 ];
2806 // if it's not a string recurse
2808 merge_text_nodes( jsonml[ i ] );
2815 if ( typeof exports === "undefined" ) {
2816 window.markdown = {};
2817 return window.markdown;
2825 Deck JS - deck.smarkdown
2826 Copyright (c) 2014-2014 RĂ©mi Emonet
2827 Licensed under the MIT license.
2828 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
2832 This module provides a support for a shorter syntax for slides, with a syntax that is closer to plain markdown.
2834 - configurize the .smark and the default duration also
2835 - have a shortcut for {slide}?
2839 (function($, deck, undefined) {
2840 var $d = $(document);
2841 var may = function(f) {return f ? f : function() {}};
2842 var endsWith = function(longStr, part) {return longStr.indexOf(part, longStr.length - part.length) !== -1;}
2844 var startsWith = function(longStr, part) {
2845 if (part == "%+class:") alert(":::"+longStr+":::");
2846 var res = longStr.substr(0, part.length) == part;
2847 REST = res ? longStr.slice(part.length) : null;
2848 RESTRIM = res ? REST.replace(/^ */, "") : null;
2851 var startsWithIgnoreCase = function(longStr, part) {
2852 var res = longStr.substr(0, part.length).toUpperCase() == part.toUpperCase();
2853 REST = res ? longStr.slice(part.length) : null;
2854 RESTRIM = res ? REST.replace(/^ */, "") : null;
2857 var isArray = Array.isArray || $.isArray; // there is also an alternative in markdownjs
2859 // the animation duration is stateful across the smarkdown sections
2860 var animationDurationDefault = 400;
2861 var animationDuration = animationDurationDefault;
2863 function clone(a) { return JSON.parse(JSON.stringify(a)) }
2864 function findTag(tree, regexp, startAt) {
2865 var i = startAt || 0;
2866 while (i < tree.length) {
2867 if (isArray(tree[i]) && tree[i][0].match(regexp)) {
2874 function addSpaceSeparatedAttr(o, a, c) {
2875 ensureHasAttributes(o);
2881 function addClass(o, c) {
2882 addSpaceSeparatedAttr(o, 'class', c);
2884 function hasClass(o, c) {
2885 if (!isObject(o[1]) || !o[1]['class']) {
2888 return o[1]['class'].match(new RegExp("\\b"+c+"\\b"));
2891 function isObject(o) {
2892 return !isArray(o) && typeof(o) === 'object';
2894 function ensureHasAttributes(tree) {
2895 if (!isObject(tree[1])) {
2896 tree.splice(1, 0, {});
2901 function lazyGetAttributes(tree) {
2902 if (isObject(tree[1])) {
2908 function lazyUnsetAttributes(tree) {
2909 if (isObject(tree[1])) {
2913 function hasIDOrClassDecoration(s) {
2914 return s.match(/^(.*)\{([^{}<>]*)\}$/);
2916 function maybeProcessCopySlide(tree, index) {
2917 var slide = tree[index];
2918 ensureHasAttributes(slide);
2919 if (slide.length != 3) return false;
2920 if (slide[2][0] != "h1") return false;
2921 ensureHasAttributes(slide[2]);
2922 if (startsWithIgnoreCase(slide[2][2], "@COPY:#")) {
2923 var main = RESTRIM.split(/:/);
2924 var idOfBase = main[0];
2925 var animPart = main.slice(1).join(":");
2926 var hasAnim = ! animPart.match(/^\s*$/);
2929 if (i == 0 || (i==1 && isObject(tree[1]))) continue;
2930 ensureHasAttributes(tree[i]);
2931 if (tree[i][1].id == idOfBase) {
2936 if (base == null) { alert("pb"); return false; } // TODO should alert based on options
2937 var content = [["div", {}, "@anim:" + animPart]];
2938 content = content.concat(clone(base.slice(2)));
2939 slide[1] = clone(base[1]);
2941 if (hasAnim) addClass(slide, "anim-continue");
2942 slide.splice.apply(slide, [2, 1].concat(content)); // replace the h1 with content
2947 function processIDOrClassDecoration(tree, index) {
2948 var matched = hasIDOrClassDecoration(tree[index]); // make sure the group is set
2949 if (!matched) { alert("should call processIDOrClassDecoration() only if hasIDOrClassDecoration is true"); return; }
2950 var returnValue = false; // whether we added the attributes
2951 var base = RegExp.$1;
2952 var decorations = RegExp.$2.split(/ +/);
2953 if (ensureHasAttributes(tree)) {
2954 if (index>0) index++;
2958 for (d in decorations) {
2959 // allow .class and class notations
2960 if (startsWith(decorations[d], ".")) decorations[d] = decorations[d].slice(1);
2962 if (startsWith(decorations[d], "#")) {
2963 tree[1].id = decorations[d].slice(1);
2965 if (startsWith(decorations[d], "*") | startsWith(decorations[d], "/")) {
2966 addSpaceSeparatedAttr(tree, "data-container-class", decorations[d].slice(1));
2968 addClass(tree, decorations[d]);
2974 function possiblyHideIfEmpty(tree) { // if it contains only anim stuf etc
2976 var i = isObject(tree[1]) ? 2 : 1;
2977 function onlyDivAnims(tt) {
2979 var start = isObject(tt[1]) ? 2 : 1;
2980 tt.slice(start).forEach(function(e) {
2981 if (!isArray(e) || !isObject(e[1]) || (" "+e[1]["class"]).indexOf(" anim-") == -1) {
2988 if (onlyDivAnims(tree)) hide = true;
2989 else if (tree.length == i+1 && isArray(tree[i]) && tree[i][0] == "p"
2990 && onlyDivAnims(tree[i])) hide = true;
2992 ensureHasAttributes(tree);
2993 tree[1].style = "display: none";
2996 function maybeProcessComment(tree, index) {
2997 var line = tree[index];
2998 var clean = function(s) { return s;}; //return s.replace(/\/\\\//g, '//'); };
2999 if (line.match(/^(.*?)[\n\s]*\/\/ +(.*)/)) {
3002 }, clean(RegExp.$2)];
3003 tree.splice(index, 1, RegExp.$1, obj);
3006 tree[index] = clean(tree[index]);
3009 function maybeProcessAtSomething(tree, index) {
3010 var line = tree[index];
3011 if (startsWithIgnoreCase(line, "@SVG:")) {
3012 var content = RESTRIM
3013 var parts = content.split(/ +/);
3014 if (hasIDOrClassDecoration(content) || parts.length == 3) {
3017 'data-src': parts[0],
3018 'data-width': parts[1],
3019 'data-height': parts[2],
3020 'class': "svg-object"
3021 }, parts.slice(3).join(" ")];
3022 // TODO: alert when wrong number of args
3023 if (hasIDOrClassDecoration(content)) processIDOrClassDecoration(obj, 2);
3026 // TODO allow this only when an option is set option
3027 // old, smartsyntax version
3029 'data-src': parts[1],
3030 'data-width': parts[2],
3031 'data-height': parts[3],
3032 'class': "svg-object"
3034 parts[0].split(/,/).forEach(function (p) { addClass(obj, p); });
3037 } else if (startsWithIgnoreCase(line, "@ANIM:")) {
3038 line = RESTRIM.replace(/%[+]/i, "%%"); // protect the "%+class" from being split
3040 var parts = line.split(/ *\| */); // TODO: configurize + reconsider all separators?
3042 // process each group of simultaneous animations
3043 var subparts = parts[i].split(/ *\+ */);
3044 for (ii in subparts) {
3045 var what = subparts[ii];
3046 if (what == "") continue; // as a good side effect, this allows to set a "anim-continue" on all elements (e.g., put a + at the end of the line)
3047 var continuating = ii != subparts.length-1;
3048 var toAdd = ["div", {}, ""];
3049 addClass(toAdd, "slide");
3050 // process the individual element (reminder: animationDuration is global)
3051 function dw() { addSpaceSeparatedAttr(toAdd, "data-what", REST); }
3052 function dd() { addSpaceSeparatedAttr(toAdd, "data-dur", ""+animationDuration); }
3053 if (startsWithIgnoreCase(what, "%duration:")) {
3054 animationDuration = RESTRIM == "" ? animationDurationDefault : RESTRIM;
3056 } else if (startsWithIgnoreCase(what, "%dur:")) {
3057 animationDuration = RESTRIM == "" ? animationDurationDefault : RESTRIM;
3059 } else if (startsWithIgnoreCase(what, "%play:")) {
3060 addClass(toAdd, "anim-play");
3062 } else if (startsWithIgnoreCase(what, "%pause:")) {
3063 addClass(toAdd, "anim-pause");
3065 } else if (startsWith(what, "%viewbox:")) {
3066 addClass(toAdd, "anim-viewboxas");
3067 // TODO: if REST contains ':', two params (then the target is specified, else it is just all SVGs root elements)
3068 addSpaceSeparatedAttr(toAdd, "data-as", REST);
3069 addSpaceSeparatedAttr(toAdd, "data-what", "svg");
3071 } else if (startsWith(what, "%attr:")) {
3072 var main = RESTRIM.split(/ *: */);
3073 addClass(toAdd, "anim-attribute");
3074 addSpaceSeparatedAttr(toAdd, "data-what", main[0]);
3075 addSpaceSeparatedAttr(toAdd, "data-attr", main.slice(1).join(":"));
3077 } else if (startsWith(what, "%along:")) {
3078 var main = RESTRIM.split(/ *: */);
3079 addClass(toAdd, "anim-along");
3080 if (startsWith(main[0], "-")) {
3082 addSpaceSeparatedAttr(toAdd, "data-reverse", "true");
3084 addSpaceSeparatedAttr(toAdd, "data-path", main[0]);
3085 addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
3087 } else if (startsWith(what, "%%class:")) {
3088 var main = RESTRIM.split(/ *: */);
3089 addClass(toAdd, "anim-addclass");
3090 addSpaceSeparatedAttr(toAdd, "data-class", main[0]);
3091 addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
3092 } else if (startsWith(what, "%-class:")) {
3093 var main = RESTRIM.split(/ *: */);
3094 addClass(toAdd, "anim-removeclass");
3095 addSpaceSeparatedAttr(toAdd, "data-class", main[0]);
3096 addSpaceSeparatedAttr(toAdd, "data-what", main.slice(1).join(":"));
3097 } else if (startsWith(what, "+")) {
3098 addClass(toAdd, "anim-show");
3100 } else if (startsWith(what, "-")) {
3101 addClass(toAdd, "anim-hide");
3104 addClass(toAdd, "anim-show");
3105 addSpaceSeparatedAttr(toAdd, "data-what", what);
3108 if (continuating) addClass(toAdd, "anim-continue");
3109 allToAdd.push(toAdd);
3112 tree.splice.apply(tree, [index, 1].concat(allToAdd)); // just replacing the text with allToAdd elements
3116 // TODO? handle the decorations for comments
3119 function processMath(content) {
3120 return content.replace(/\$([^$][^$]*)\$/g, '<span class="latex">\\displaystyle $1</span>').replace(/\$\$/, '$');
3123 var interpretationOfSmartLanguage = function(smark, doc) {
3124 var jstree = markdown.toHTMLTree(smark);
3126 // split at each h2 or h1
3127 (function makeTopLevelDivs(jsTree) {
3128 var firstIndex = findTag(jsTree, /^(h1|h2)$/);
3129 if (firstIndex == -1) return;
3130 var secondIndex = findTag(jsTree, /^(h1|h2)$/, firstIndex+1);
3131 if (secondIndex == -1) secondIndex = jsTree.length;
3132 var slide = ["section"].concat( // we will add the 'slide' class later below
3133 jsTree.splice(firstIndex, secondIndex - firstIndex));
3134 jsTree.splice(firstIndex, 0, slide);
3135 makeTopLevelDivs(jsTree);
3139 // - the class and id decorations like {#first hightlight slide}
3140 // - the @... custom notations
3141 // - the // for comments
3143 if (s == 0 || (s==1 && isObject(jstree[1]))) continue;
3144 var slide = jstree[s];
3145 ensureHasAttributes(slide);
3146 if (maybeProcessCopySlide(jstree, s)) {
3148 // actually we want to apply anims to it
3150 // cleanup: first, remove first "p" in a "li" (happens when one put an empty line in a bullet list, but it would break the decorations)
3151 (function patch(tree){ // tree is slide or a subelement
3153 while (i < tree.length) {
3154 if (isArray(tree[i])) {
3155 if (tree[i][0] === "li") {
3157 if (isArray(li[1]) && li[1][0] === "p") {
3158 li.splice.apply(li, [1, 1].concat(li[1].slice(1)));
3167 // process @anim... and {} decoration
3168 (function patch(tree){ // tree is slide or a subelement
3170 while (i < tree.length) {
3171 if (isArray(tree[i])) patch(tree[i]);
3172 else if (typeof(tree[i]) == 'string') {
3173 if (maybeProcessComment(tree, i)) continue;
3174 else if (maybeProcessAtSomething(tree, i)) continue;
3175 else if (hasIDOrClassDecoration(tree[i])) {
3176 if (processIDOrClassDecoration(tree, i)) {
3177 i++; // avoid processing the same element twice
3184 // cleanup: hide empty "li" after @anim processing
3185 (function patch(tree){ // tree is slide or a subelement
3187 while (i < tree.length) {
3188 if (isArray(tree[i])) {
3189 if (tree[i][0] === "li" && possiblyHideIfEmpty(tree[i])) continue;
3190 else patch(tree[i]);
3195 // process the $math$
3196 (function patch(tree){ // tree is slide or a subelement
3197 if (hasClass(tree, "smark-nomath")) return;
3199 while (i < tree.length) {
3200 if (isArray(tree[i])) patch(tree[i]);
3201 else if (typeof(tree[i]) == 'string') {
3202 tree[i] = processMath(tree[i]);
3207 // change things to textarea (to help with codemirror) https://github.com/iros/deck.js-codemirror/issues/19
3208 (function patch(tree){ // tree is slide or a subelement
3209 if (hasClass(tree, "smark-textarea")) {
3210 tree[3][0] = "textarea";
3213 while (i < tree.length) {
3214 if (isArray(tree[i])) patch(tree[i]);
3218 // now propagate to the slide
3219 var hAttributes = lazyGetAttributes(slide[2]);
3220 if (slide[1]['class']) {
3221 var cl = slide[1]['class'];
3222 slide[1] = clone(hAttributes);
3223 addClass(slide, cl);
3225 slide[1] = clone(hAttributes);
3227 lazyUnsetAttributes(slide[2]);
3228 addClass(slide, 'slide');
3231 return markdown.renderJsonML(jstree);
3234 // this have to be executed before the deck init
3235 $d.bind('deck.beforeInit', function() {
3236 $('.smark').each(function() { // TODO make it configurable
3238 var slides = interpretationOfSmartLanguage(it.innerHTML, document);
3239 $(it).after(slides);
3240 // remove the smart node (to avoid having an empty non-slide sibling (e.g., in the presenter view))
3243 var opts = $[deck]('getOptions');
3244 var maybe = function(f) { return f || (function(){}); }
3245 maybe(opts.AFTERSMARKDOWN)();
3246 $[deck]('reInitSlidesArray')
3253 Copyright (c) 2012 RĂ©mi Emonet
3254 Licensed under the MIT license.
3255 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
3259 This extension provides a way of scaling the slides to fit the slide container.
3260 A "design size" is used to do global scaling of all slides in the same way.
3261 The default design size is 800x600.
3263 (function($, deck, window, undefined) {
3264 var $d = $(document),
3266 timer, // Timeout id for debouncing
3270 Internal function to do all the dirty work of scaling the slides.
3272 scaleDeck = function() {
3273 var opts = $[deck]('getOptions');
3274 var addMarginX = opts.fitMarginX * 2;
3275 var addMarginY = opts.fitMarginY * 2;
3276 var fitMode = opts.fitMode;
3277 var sdw = opts.designWidth;
3278 var sdh = opts.designHeight;
3279 var $container = $[deck]('getContainer');
3280 var scaleX = $container.hasClass(opts.classes.globalscale) ? $container.innerWidth() / (sdw+addMarginX) : 1;
3281 var scaleY = $container.hasClass(opts.classes.globalscale) ? $container.innerHeight() / (sdh+addMarginY) : 1;
3282 //var truescaleX = $container.hasClass(opts.classes.globalscale) ? $container.innerWidth() / (sdw) : 1;
3283 //var truescaleY = $container.hasClass(opts.classes.globalscale) ? $container.innerHeight() / (sdh) : 1;
3284 var scale = scaleX < scaleY ? scaleX : scaleY;
3285 var rootSlides = [];
3286 var slideTest = $.map([opts.classes.before, opts.classes.previous, opts.classes.current, opts.classes.next, opts.classes.after],
3287 function(el, i) {return '.' + el;}).join(', ');
3289 $.each($[deck]('getSlides'), function(i, $el) {
3290 if (!$el.parentsUntil(opts.selectors.container).length) {
3291 rootSlides.push($el);
3294 $.each(rootSlides, function(i, $slide) {
3295 $slide.css('width', sdw);
3296 $slide.css('height', sdh);
3297 $.each('Webkit Moz O ms Khtml'.split(' '), function(i, prefix) {
3299 $slide.css(prefix + 'Transform', '');
3301 if (fitMode == "left top" || fitMode == "top left") {
3302 // ok align left/top (ok with the percents)
3303 $slide.css(prefix + 'Transform', 'translate(-50%,-50%) scale(' + scale + ' , ' + scale + ') translate(50%,50%) translate('+(addMarginX/2)+'px,'+(addMarginY/2)+'px)');
3304 } else if (fitMode == "center middle") {
3305 // ok align center/middle
3306 $slide.css(prefix + 'Transform', 'translate(-50%,-50%) scale(' + scale + ' , ' + scale + ') translate(50%, 50%) translate('+($container.innerWidth()/2/scale - sdw/2)+'px,'+($container.innerHeight()/2/scale - sdh/2)+'px)');
3307 } else if (fitMode == "right bottom" || fitMode == "bottom right") {
3308 // ok align right/bottom
3309 $slide.css(prefix + 'Transform', 'translate(-50%,-50%) scale(' + scale + ' , ' + scale + ') translate(50%, 50%) translate('+($container.innerWidth()/scale - sdw - addMarginX/2)+'px,'+($container.innerHeight()/scale - sdh - addMarginY/2)+'px)');
3310 } else if (fitMode == "stretched") {
3311 // ok stretched (with respect of the margin, i.e., it is center/middle)
3312 $slide.css(prefix + 'Transform', 'scale(' + scaleX + ' , ' + scaleY + ') translate('+(($container.innerWidth()-sdw)/2/scaleX)+'px,'+(($container.innerHeight()-sdh)/2/scaleY)+'px)');
3321 Extends defaults/options.
3324 Defaults to 800. You may instead specify a width as a number
3325 of px and all slides will be scaled in the same way, considering their
3326 size is the provided one.
3328 options.designHeight
3329 Defaults to 600. You may instead specify a height as a number
3330 of px and all slides will be scaled in the same way, considering their
3331 size is the provided one.
3334 How to adapt the slide to the container.
3335 Only the following combinations are available for now:
3336 "center middle", "top left", "bottom right", "stretched"
3340 Defaults to 5. Adds some margin in design space units.
3341 E.g., if the designe width is 800 and the margin is 5, the slide will be
3342 810 pixel wide before rescaling.
3344 options.scaleDebounce
3345 Scaling on the browser resize event is debounced. This number is the
3346 threshold in milliseconds. You can learn more about debouncing here:
3347 http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
3350 $.extend(true, $[deck].defaults, {
3352 globalscale: 'deck-globalscale'
3360 fitMode: "center middle",
3367 jQuery.deck('disableScale')
3369 Disables scaling and removes the scale class from the deck container.
3371 $[deck]('extend', 'disableScale', function() {
3372 $[deck]('getContainer').removeClass($[deck]('getOptions').classes.globalscale);
3377 jQuery.deck('enableScale')
3379 Enables scaling and adds the scale class to the deck container.
3381 $[deck]('extend', 'enableScale', function() {
3382 $[deck]('getContainer').addClass($[deck]('getOptions').classes.globalscale);
3387 jQuery.deck('toggleScale')
3389 Toggles between enabling and disabling scaling.
3391 $[deck]('extend', 'toggleScale', function() {
3392 var $c = $[deck]('getContainer');
3393 $[deck]($c.hasClass($[deck]('getOptions').classes.globalscale) ?
3394 'disableScale' : 'enableScale');
3397 $d.bind('deck.init', function() {
3398 var opts = $[deck]('getOptions');
3400 // Debounce the resize scaling
3401 $w.unbind('resize.deckscale').bind('resize.deckscale', function() {
3402 window.clearTimeout(timer);
3403 timer = window.setTimeout(scaleDeck, opts.scaleDebounce);
3405 // Scale once on load, in case images or something change layout
3406 .unbind('load.deckscale').bind('load.deckscale', scaleDeck);
3409 $d.unbind('keydown.deckscale').bind('keydown.deckscale', function(e) {
3410 if (e.which === opts.keys.scale || $.inArray(e.which, opts.keys.scale) > -1) {
3411 $[deck]('toggleScale');
3416 // Enable scale on init
3417 $[deck]('enableScale');
3419 })(jQuery, 'deck', this);
3422 // This script was automatically generated from a literate source.
3423 // Do not edit this file; look at the literate source instead!
3425 // Greasemonkey user script to
3426 // Display LaTeX in Web pages by transforming to MathML
3427 // --------------------------------------------------------------------
3429 // Original script by
3430 // Copyright (C) 2006 Steve Cheng <stevecheng@users.sourceforge.net>
3431 // Home page: http://gold-saucer.afraid.org/mathml/greasemonkey/
3434 // Copyright (C) 2010 Valery Alexeev <va.email.tex@gmail.com>
3435 // Version 1.15, May 7, 2010
3438 // Added arxiv.org, front.math.ucdavis.edu, *mathscinet*, mail.google.com
3439 // Changed char_map to fix the display for \mathcal, \mathbb, \mathfrak
3440 // Fixed the displayed formulas with $$...$$ and \[...\]
3441 // Added \scr, \germ, \roman, etc used by Mathscinet.
3442 // Added miscellaneous symbols and arrows
3444 // Permission is hereby granted, free of charge, to any person obtaining
3445 // a copy of this software and associated documentation files (the
3446 // "Software"), to deal in the Software without restriction, including
3447 // without limitation the rights to use, copy, modify, merge, publish,
3448 // distribute, sublicense, and/or sell copies of the Software, and to
3449 // permit persons to whom the Software is furnished to do so, subject to
3450 // the following conditions:
3452 // The above copyright notice and this permission notice shall be included
3453 // in all copies or substantial portions of the Software.
3455 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3456 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3457 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
3458 // IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
3459 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
3460 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
3461 // OTHER DEALNGS IN THE SOFTWARE.
3464 function latex2mml() {
3467 function GM_log() {}
3470 // First, find out where we are
3471 var va_loc = window.location.href;
3472 var va_view = 'web';
3474 //alert( 'va_view=' + va_view );
3476 // The script itself begins
3478 var/*const*/ mmlns = 'http://www.w3.org/1998/Math/MathML';
3481 // VA: Fix displayed equations first.
3482 if( va_view == 'web' ){
3483 document.body.innerHTML=
3484 document.body.innerHTML.replace(/\n/g," "); // remove end-of-lines
3485 document.body.innerHTML=
3486 document.body.innerHTML.replace(/(\$\$|\\\[)([^$]+)(\$\$|\\\])/g,
3487 "<p style=\"text-indent: 20px;\"> \$ $2 \$ </p>");
3488 // VA: Experimental: may lead to slow down. \spcheck is used on MathSciNet
3489 // document.body.innerHTML=
3490 // document.body.innerHTML.replace(/\\spcheck/g,"^{\\vee}");
3495 function result_element(tag, num_attrs)
3497 var node = document.createElementNS(mmlns, tag);
3500 while(--num_attrs >= 0) {
3501 if(arguments[k+1] != null) {
3502 node.setAttribute(arguments[k], arguments[k+1]);
3507 for(; k < arguments.length; k++) {
3508 if(arguments[k] != null) {
3509 if(typeof(arguments[k]) == 'string')
3510 node.appendChild(document.createTextNode(arguments[k]));
3512 node.appendChild(arguments[k]);
3520 function result_element_append(parent, child)
3522 if(parent != null && child != null) {
3523 if(typeof(child) == 'string')
3524 parent.appendChild(document.createTextNode(child));
3526 parent.appendChild(child);
3531 function result_element_prepend(parent, child, next)
3534 result_element_append(parent, child);
3535 else if (parent != null && child != null)
3536 parent.insertBefore(child, next);
3540 function result_set_attr(elem, attr, value)
3542 if(elem != null && attr != null) {
3544 elem.setAttribute(attr, value);
3546 elem.removeAttribute(attr);
3551 function result_append_attr(elem, attr, value)
3553 if(elem != null && attr != null) {
3554 var old_value = elem.getAttribute(elem, attr);
3555 if(old_value == null)
3556 elem.setAttribute(attr, value);
3558 elem.setAttribute(attr, old_value + value);
3563 if( va_view == 'web' ){
3564 if(!this.GM_getValue) {
3565 this.GM_getValue = function(key, value) { return value; }
3566 this.GM_log = function() {}
3570 if(this.GM_registerMenuCommand) {
3571 GM_registerMenuCommand("Enable native display of math images",
3573 GM_setValue("patch-images", true);
3574 do_patch_images = true;
3575 patch_element(document.documentElement);
3577 GM_registerMenuCommand("Disable native display of math images",
3579 GM_setValue("patch-images", false);
3585 // VA: changed char_map
3586 var/*const*/ char_map = {
3588 '\uD835\uDC9C', '\u212C', '\uD835\uDC9E', //abc
3589 '\uD835\uDC9F', '\u2130', '\u2131', //def
3590 '\uD835\uDCA2', '\u210B', '\u2110', //ghi
3591 '\uD835\uDCA5', '\uD835\uDCA6', '\u2112', //jkl
3592 '\u2133', '\uD835\uDCA9', '\uD835\uDCAA', //mno
3593 '\uD835\uDCAB', '\uD835\uDCAC', '\u211B', //pqr
3594 '\uD835\uDCAE', '\uD835\uDCAF', '\uD835\uDCB0', //stu
3595 '\uD835\uDCB1', '\uD835\uDCB2', '\uD835\uDCB3', //vwx
3596 '\uD835\uDCB4', '\uD835\uDCB5' ], //yz
3599 '\uD835\uDD04', '\uD835\uDD05', '\u212D', //abc
3600 '\uD835\uDD07', '\uD835\uDD08', '\uD835\uDD09', //def
3601 '\uD835\uDD0A', '\u210C', '\u2111', //ghi
3602 '\uD835\uDD0D', '\uD835\uDD0E', '\uD835\uDD0F', //jkl
3603 '\uD835\uDD10', '\uD835\uDD11', '\uD835\uDD12', //mno
3604 '\uD835\uDD13', '\uD835\uDD14', '\u211C', //pqr
3605 '\uD835\uDD16', '\uD835\uDD17', '\uD835\uDD18', //stu
3606 '\uD835\uDD19', '\uD835\uDD1A', '\uD835\uDD1B', //vwx
3607 '\uD835\uDD1C', '\u2128' ], //yz
3610 '\uD835\uDD38', '\uD835\uDD39', '\u2102', //abc
3611 '\uD835\uDD3B', '\uD835\uDD3C', '\uD835\uDD3D', //def
3612 '\uD835\uDD3E', '\u210D', '\uD835\uDD40', //ghi
3613 '\uD835\uDD41', '\uD835\uDD42', '\uD835\uDD43', //jkl
3614 '\uD835\uDD44', '\u2115', '\uD835\uDD46', //mno
3615 '\u2119', '\u211A', '\u211D', //pqr
3616 '\uD835\uDD4A', '\uD835\uDD4B', '\uD835\uDD4C', //stu
3617 '\uD835\uDD4D', '\uD835\uDD4E', '\uD835\uDD4F', //vwx
3618 '\uD835\uDD50', '\u2124', ], //yz
3621 var/*const*/ uppercase_re = /[A-Z]/;
3623 function fix_mathvariant(node, style)
3625 if(node.nodeType == node.TEXT_NODE) {
3626 if(style != null && style != '' && style in char_map) {
3627 node.data = node.data.replace(uppercase_re,
3628 function(s) {return char_map[style][s.charCodeAt(0)-65]});
3630 } else if(node.nodeType == node.ELEMENT_NODE) {
3631 var new_style = node.getAttribute('mathvariant');
3632 if(new_style != null && new_style != '')
3635 for(var i=0; i < node.childNodes.length; i++)
3636 fix_mathvariant(node.childNodes.item(i), style);
3640 var g_punct_and_space
3641 = {"\\quad" : "\u2003" ,
3642 "\\qquad" : "\u2003\u2003" ,
3643 "\\thickspace" : "\u2002" ,
3645 "\\medspace" : "\u2005" ,
3647 "\\thinspace" : "\u2004" ,
3653 "\\qedsymbol" : "\u25a0" ,
3656 var g_left_delimiters
3663 "\\lVert" : "\u2016" ,
3664 "\\lceil" : "\u2308" ,
3665 "\\lfloor" : "\u230a" ,
3666 "\\lmoustache" : "\u23b0" ,
3667 "\\langle" : "\u2329" ,
3670 var g_right_delimiters
3677 "\\rVert" : "\u2016" ,
3678 "\\rceil" : "\u2309" ,
3679 "\\rfloor" : "\u230b" ,
3680 "\\rmoustache" : "\u23b1" ,
3681 "\\rangle" : "\u232a" ,
3684 var g_operator_symbols
3685 = {"\\amalg" : "\u2a3f" ,
3687 "\\ast" : "\u2217" ,
3688 "\\barwedge" : "\u22bc" ,
3689 "\\barwedge" : "\u2305" ,
3690 "\\bigcirc" : "\u25cb" ,
3691 "\\bigtriangledown" : "\u25bd" ,
3692 "\\bigtriangleup" : "\u25b3" ,
3693 "\\boxdot" : "\u22a1" ,
3694 "\\boxminus" : "\u229f" ,
3695 "\\boxplus" : "\u229e" ,
3696 "\\boxtimes" : "\u22a0" ,
3697 "\\bullet" : "\u2022" ,
3698 "\\bullet" : "\u2219" ,
3699 "\\cap" : "\u2229" ,
3700 "\\Cap" : "\u22d2" ,
3701 "\\cdot" : "\u22c5" ,
3702 "\\centerdot" : "\u00b7" ,
3703 "\\circ" : "\u2218" ,
3704 "\\circledast" : "\u229b" ,
3705 "\\circledcirc" : "\u229a" ,
3706 "\\circleddash" : "\u229d" ,
3707 "\\cup" : "\u222a" ,
3708 "\\Cup" : "\u22d3" ,
3709 "\\curlyvee" : "\u22ce" ,
3710 "\\curlywedge" : "\u22cf" ,
3711 "\\dagger" : "\u2020" ,
3712 "\\ddagger" : "\u2021" ,
3713 "\\diamond" : "\u22c4" ,
3714 "\\div" : "\u00f7" ,
3715 "\\divideontimes" : "\u22c7" ,
3716 "\\dotplus" : "\u2214" ,
3717 "\\doublebarwedge" : "\u2306" ,
3718 "\\doublecap" : "\u22d2" ,
3719 "\\doublecup" : "\u22d3" ,
3720 "\\gtrdot" : "\u22d7" ,
3721 "\\intercal" : "\u22ba" ,
3722 "\\land" : "\u2227" ,
3723 "\\leftthreetimes" : "\u22cb" ,
3724 "\\lessdot" : "\u22d6" ,
3725 "\\lor" : "\u2228" ,
3726 "\\ltimes" : "\u22c9" ,
3728 "\\odot" : "\u2299" ,
3729 "\\ominus" : "\u2296" ,
3730 "\\oplus" : "\u2295" ,
3731 "\\oslash" : "\u2298" ,
3732 "\\otimes" : "\u2297" ,
3734 "\\rightthreetimes" : "\u22cc" ,
3735 "\\rtimes" : "\u22ca" ,
3736 "\\setminus" : "\u2216" ,
3737 "\\smallsetminus" : "\u2216" ,
3738 "\\sqcap" : "\u2293" ,
3739 "\\sqcup" : "\u2294" ,
3740 "\\star" : "\u22c6" ,
3741 "\\times" : "\u00d7" ,
3742 "\\triangleleft" : "\u25c1" ,
3743 "\\triangleright" : "\u25b7" ,
3744 "\\uplus" : "\u228e" ,
3745 "\\vee" : "\u2228" ,
3746 "\\spcheck" : "\u207a" , // has to be ^{\vee} instead but that's hard
3748 //"\\spcheck" : "\u002a" ,
3749 "\\veebar" : "\u22bb" ,
3750 "\\veebar" : "\u2a61" ,
3751 "\\wedge" : "\u2227" ,
3762 "\\Vert" : "\u2016" ,
3764 "\\backslash" : "\\" ,
3769 "\\downarrow" : "\u2193" ,
3770 "\\Downarrow" : "\u21d3" ,
3771 "\\uparrow" : "\u2191" ,
3772 "\\Uparrow" : "\u21d1" ,
3773 "\\updownarrow" : "\u2195" ,
3774 "\\Updownarrow" : "\u21d5" ,
3775 "\\bigcap" : "\u22c2" ,
3776 "\\bigcup" : "\u22c3" ,
3777 "\\bigodot" : "\u2a00" ,
3778 "\\bigoplus" : "\u2a01" ,
3779 "\\bigotimes" : "\u2a02" ,
3780 "\\bigsqcup" : "\u2a06" ,
3781 "\\biguplus" : "\u2a04" ,
3782 "\\bigvee" : "\u22c1" ,
3783 "\\bigwedge" : "\u22c0" ,
3784 "\\coprod" : "\u2210" ,
3785 "\\prod" : "\u220f" ,
3786 "\\sum" : "\u2211" ,
3787 "\\int" : "\u222b" ,
3788 "\\smallint" : "\u222b" ,
3789 "\\oint" : "\u222e" ,
3790 "\\angle" : "\u2220" ,
3791 "\\backprime" : "\u2035" ,
3792 "\\bigstar" : "\u2605" ,
3793 "\\blacklozenge" : "\u29eb" ,
3794 "\\blacksquare" : "\u25a0" ,
3795 "\\blacktriangle" : "\u25b4" ,
3796 "\\blacktriangledown" : "\u25be" ,
3797 "\\bot" : "\u22a5" ,
3798 "\\clubsuit" : "\u2663" ,
3799 "\\diagdown" : "\u2572" ,
3800 "\\diagup" : "\u2571" ,
3801 "\\diamondsuit" : "\u2662" ,
3802 "\\emptyset" : "\u2205" ,
3803 "\\exists" : "\u2203" ,
3804 "\\flat" : "\u266d" ,
3805 "\\forall" : "\u2200" ,
3806 "\\heartsuit" : "\u2661" ,
3807 "\\infty" : "\u221e" ,
3808 "\\lnot" : "\u00ac" ,
3809 "\\lozenge" : "\u25ca" ,
3810 "\\measuredangle" : "\u2221" ,
3811 "\\nabla" : "\u2207" ,
3812 "\\natural" : "\u266e" ,
3813 "\\neg" : "\u00ac" ,
3814 "\\nexists" : "\u2204" ,
3815 "\\prime" : "\u2032" ,
3816 "\\sharp" : "\u266f" ,
3817 "\\spadesuit" : "\u2660" ,
3818 "\\sphericalangle" : "\u2222" ,
3819 "\\square" : "\u25a1" ,
3820 "\\surd" : "\u221a" ,
3821 "\\top" : "\u22a4" ,
3822 "\\triangle" : "\u25b5" ,
3823 "\\triangledown" : "\u25bf" ,
3824 "\\varnothing" : "\u2205" ,
3825 "\\aleph" : "\u2135" ,
3826 "\\Bbbk" : "\u1d55C" ,
3827 "\\beth" : "\u2136" ,
3828 "\\circledS" : "\u24c8" ,
3829 "\\complement" : "\u2201" ,
3830 "\\daleth" : "\u2138" ,
3831 "\\ell" : "\u2113" ,
3832 "\\eth" : "\u00f0" ,
3833 "\\Finv" : "\u2132" ,
3834 "\\Game" : "\u2141" ,
3835 "\\gimel" : "\u2137" ,
3836 "\\hbar" : "\u210f" ,
3837 "\\hslash" : "\u210f" ,
3839 "\\mho" : "\u2127" ,
3840 "\\partial" : "\u2202" ,
3845 var g_relation_symbols
3849 "\\approx" : "\u2248" ,
3850 "\\approxeq" : "\u224a" ,
3851 "\\asymp" : "\u2248" ,
3852 "\\backsim" : "\u223d" ,
3853 "\\backsimeq" : "\u22cd" ,
3854 "\\bumpeq" : "\u224f" ,
3855 "\\Bumpeq" : "\u224e" ,
3856 "\\circeq" : "\u2257" ,
3857 "\\cong" : "\u2245" ,
3858 "\\curlyeqprec" : "\u22de" ,
3859 "\\curlyeqsucc" : "\u22df" ,
3860 "\\doteq" : "\u2250" ,
3861 "\\doteqdot" : "\u2251" ,
3862 "\\eqcirc" : "\u2256" ,
3863 "\\eqsim" : "\u2242" ,
3864 "\\eqslantgtr" : "\u2a96" ,
3865 "\\eqslantless" : "\u2a95" ,
3866 "\\equiv" : "\u2261" ,
3867 "\\fallingdotseq" : "\u2252" ,
3869 "\\geq" : "\u2265" ,
3870 "\\geqq" : "\u2267" ,
3871 "\\geqslant" : "\u2a7e" ,
3874 "\\ggg" : "\u22d9" ,
3875 "\\gggtr" : "\u22d9" ,
3876 "\\gnapprox" : "\u2a8a" ,
3877 "\\gneq" : "\u2a88" ,
3878 "\\gneqq" : "\u2269" ,
3879 "\\gnsim" : "\u22e7" ,
3880 "\\gtrapprox" : "\u2a86" ,
3881 "\\gtreqless" : "\u22db" ,
3882 "\\gtreqqless" : "\u2a8c" ,
3883 "\\gtrless" : "\u2277" ,
3884 "\\gtrsim" : "\u2273" ,
3885 "\\gvertneqq" : "\u2269" ,
3887 "\\leq" : "\u2264" ,
3888 "\\leqq" : "\u2266" ,
3889 "\\leqslant" : "\u2a7d" ,
3890 "\\lessapprox" : "\u2a85" ,
3891 "\\lesseqgtr" : "\u22da" ,
3892 "\\lesseqqgtr" : "\u2a8b" ,
3893 "\\lessgtr" : "\u2276" ,
3894 "\\lesssim" : "\u2272" ,
3896 "\\llless" : "\u22d8" ,
3897 "\\lnapprox" : "\u2a89" ,
3898 "\\lneq" : "\u2a87" ,
3899 "\\lneqq" : "\u2268" ,
3900 "\\lnsim" : "\u22e6" ,
3901 "\\lvertneqq" : "\u2268" ,
3902 "\\ncong" : "\u2247" ,
3904 "\\neq" : "\u2260" ,
3905 "\\ngeq" : "\u2271" ,
3906 "\\ngeqq" : "\u2267" ,
3907 "\\ngeqslant" : "\u2a7e" ,
3908 "\\ngtr" : "\u226f" ,
3909 "\\nleq" : "\u2270" ,
3910 "\\nleqq" : "\u2266" ,
3911 "\\nleqslant" : "\u2a7d" ,
3912 "\\nless" : "\u226e" ,
3913 "\\nprec" : "\u2280" ,
3914 "\\npreceq" : "\u2aaf" ,
3915 "\\nsim" : "\u2241" ,
3916 "\\nsucc" : "\u2281" ,
3917 "\\nsucceq" : "\u2ab0" ,
3918 "\\prec" : "\u227a" ,
3919 "\\precapprox" : "\u2ab7" ,
3920 "\\preccurlyeq" : "\u227c" ,
3921 "\\preceq" : "\u2aaf" ,
3922 "\\precnapprox" : "\u2ab9" ,
3923 "\\precneqq" : "\u2ab5" ,
3924 "\\precnsim" : "\u22e8" ,
3925 "\\precsim" : "\u227e" ,
3926 "\\risingdotseq" : "\u2253" ,
3927 "\\sim" : "\u223c" ,
3928 "\\simeq" : "\u2243" ,
3929 "\\succ" : "\u227b" ,
3930 "\\succapprox" : "\u2ab8" ,
3931 "\\succcurlyeq" : "\u227d" ,
3932 "\\succeq" : "\u2ab0" ,
3933 "\\succnapprox" : "\u2aba" ,
3934 "\\succneqq" : "\u2ab6" ,
3935 "\\succnsim" : "\u22e9" ,
3936 "\\succsim" : "\u227f" ,
3937 "\\thickapprox" : "\u2248" ,
3938 "\\thicksim" : "\u223c" ,
3939 "\\triangleq" : "\u225c" ,
3940 "\\longrightarrow" : "\u27F6" ,
3941 "\\curvearrowleft" : "\u21b6" ,
3942 "\\curvearrowright" : "\u21b7" ,
3943 "\\downdownarrows" : "\u21ca" ,
3944 "\\downharpoonleft" : "\u21c3" ,
3945 "\\downharpoonright" : "\u21c2" ,
3946 "\\gets" : "\u2190" ,
3947 "\\hookleftarrow" : "\u21a9" ,
3948 "\\hookrightarrow" : "\u21aa" ,
3949 "\\leftarrow" : "\u2190" ,
3950 "\\Leftarrow" : "\u21d0" ,
3951 "\\leftarrowtail" : "\u21a2" ,
3952 "\\leftharpoondown" : "\u21bd" ,
3953 "\\leftharpoonup" : "\u21bc" ,
3954 "\\leftleftarrows" : "\u21c7" ,
3955 "\\leftrightarrow" : "\u2194" ,
3956 "\\leftrightarrows" : "\u21c6" ,
3957 "\\leftrightharpoons" : "\u21cb" ,
3958 "\\leftrightsquigarrow" : "\u21ad" ,
3959 "\\Lleftarrow" : "\u21da" ,
3960 "\\longleftarrow" : "\u27f5" ,
3961 "\\Longleftarrow" : "\u27f8" ,
3962 "\\longleftrightarrow" : "\u27f7" ,
3963 "\\Longleftrightarrow" : "\u27fa" ,
3964 "\\looparrowleft" : "\u21ab" ,
3965 "\\looparrowright" : "\u21ac" ,
3966 "\\Lsh" : "\u21b0" ,
3967 "\\mapsto" : "\u21a6" ,
3968 "\\multimap" : "\u22b8" ,
3969 "\\nearrow" : "\u2197" ,
3970 "\\nleftarrow" : "\u219a" ,
3971 "\\nLeftarrow" : "\u21cd" ,
3972 "\\nleftrightarrow" : "\u21ae" ,
3973 "\\nLeftrightarrow" : "\u21ce" ,
3974 "\\nrightarrow" : "\u219b" ,
3975 "\\nRightarrow" : "\u21cf" ,
3976 "\\nwarrow" : "\u2196" ,
3977 "\\restriction" : "\u21be" ,
3978 "\\rightarrow" : "\u2192" ,
3979 "\\Rightarrow" : "\u21d2" ,
3980 "\\rightarrowtail" : "\u21a3" ,
3981 "\\rightharpoondown" : "\u21c1" ,
3982 "\\rightharpoonup" : "\u21c0" ,
3983 "\\rightleftarrows" : "\u21c4" ,
3984 "\\rightleftharpoons" : "\u21cc" ,
3985 "\\rightrightarrows" : "\u21c9" ,
3986 "\\rightsquigarrow" : "\u219d" ,
3987 "\\Rrightarrow" : "\u21db" ,
3988 "\\Rsh" : "\u21b1" ,
3989 "\\searrow" : "\u2198" ,
3990 "\\swarrow" : "\u2199" ,
3992 "\\twoheadleftarrow" : "\u219e" ,
3993 "\\twoheadrightarrow" : "\u21a0" ,
3994 "\\upharpoonleft" : "\u21bf" ,
3995 "\\upharpoonright" : "\u21be" ,
3996 "\\upuparrows" : "\u21c8" ,
3997 "\\backepsilon" : "\u03f6" ,
3998 "\\because" : "\u2235" ,
3999 "\\between" : "\u226c" ,
4000 "\\blacktriangleleft" : "\u25c0" ,
4001 "\\blacktriangleright" : "\u25b6" ,
4002 "\\bowtie" : "\u22c8" ,
4003 "\\dashv" : "\u22a3" ,
4004 "\\frown" : "\u2323" ,
4006 "\\mid" : "\u2223" ,
4007 "\\models" : "\u22a7" ,
4010 "\\nmid" : "\u2224" ,
4011 "\\notin" : "\u2209" ,
4012 "\\nparallel" : "\u2226" ,
4013 "\\nshortmid" : "\u2224" ,
4014 "\\nshortparallel" : "\u2226" ,
4015 "\\nsubseteq" : "\u2286" ,
4016 "\\nsubseteq" : "\u2288" ,
4017 "\\nsubseteqq" : "\u2ac5" ,
4018 "\\nsupseteq" : "\u2287" ,
4019 "\\nsupseteq" : "\u2289" ,
4020 "\\nsupseteqq" : "\u2ac6" ,
4021 "\\ntriangleleft" : "\u22ea" ,
4022 "\\ntrianglelefteq" : "\u22ec" ,
4023 "\\ntriangleright" : "\u22eb" ,
4024 "\\ntrianglerighteq" : "\u22ed" ,
4025 "\\nvdash" : "\u22ac" ,
4026 "\\nvDash" : "\u22ad" ,
4027 "\\nVdash" : "\u22ae" ,
4028 "\\nVDash" : "\u22af" ,
4029 "\\owns" : "\u220d" ,
4030 "\\parallel" : "\u2225" ,
4031 "\\perp" : "\u22a5" ,
4032 "\\pitchfork" : "\u22d4" ,
4033 "\\propto" : "\u221d" ,
4034 "\\shortmid" : "\u2223" ,
4035 "\\shortparallel" : "\u2225" ,
4036 "\\smallfrown" : "\u2322" ,
4037 "\\smallsmile" : "\u2323" ,
4038 "\\smile" : "\u2323" ,
4039 "\\sqsubset" : "\u228f" ,
4040 "\\sqsubseteq" : "\u2291" ,
4041 "\\sqsupset" : "\u2290" ,
4042 "\\sqsupseteq" : "\u2292" ,
4043 "\\subset" : "\u2282" ,
4044 "\\Subset" : "\u22d0" ,
4045 "\\subseteq" : "\u2286" ,
4046 "\\subseteqq" : "\u2ac5" ,
4047 "\\subsetneq" : "\u228a" ,
4048 "\\subsetneqq" : "\u2acb" ,
4049 "\\supset" : "\u2283" ,
4050 "\\Supset" : "\u22d1" ,
4051 "\\supseteq" : "\u2287" ,
4052 "\\supseteqq" : "\u2ac6" ,
4053 "\\supsetneq" : "\u228b" ,
4054 "\\supsetneqq" : "\u2acc" ,
4055 "\\therefore" : "\u2234" ,
4056 "\\trianglelefteq" : "\u22b4" ,
4057 "\\trianglerighteq" : "\u22b5" ,
4058 "\\varpropto" : "\u221d" ,
4059 "\\varsubsetneq" : "\u228a" ,
4060 "\\varsubsetneqq" : "\u2acb" ,
4061 "\\varsupsetneq" : "\u228b" ,
4062 "\\varsupsetneqq" : "\u2acc" ,
4063 "\\vartriangle" : "\u25b5" ,
4064 "\\vartriangleleft" : "\u22b2" ,
4065 "\\vartriangleright" : "\u22b3" ,
4066 "\\vdash" : "\u22a2" ,
4067 "\\vDash" : "\u22a8" ,
4068 "\\Vdash" : "\u22a9" ,
4069 "\\Vvdash" : "\u22aa" ,
4071 "\\dashleftarrow" : "\u21e0" ,
4072 "\\dashrightarrow" : "\u21e2" ,
4075 var g_named_identifiers
4076 = {"\\arccos" : "arccos" ,
4077 "\\arcsin" : "arcsin" ,
4078 "\\arctan" : "arctan" ,
4102 "\\injlim" : "inj lim" ,
4104 "\\liminf" : "lim inf" ,
4105 "\\limsup" : "lum sup" ,
4108 "\\projlim" : "proj lim" ,
4110 "\\alpha" : "\u03b1" ,
4111 "\\beta" : "\u03b2" ,
4112 "\\chi" : "\u03c7" ,
4113 "\\delta" : "\u03b4" ,
4114 "\\Delta" : "\u0394" ,
4115 "\\digamma" : "\u03dd" ,
4116 "\\epsilon" : "\u03f5" ,
4117 "\\eta" : "\u03b7" ,
4118 "\\gamma" : "\u03b3" ,
4119 "\\Gamma" : "\u0393" ,
4120 "\\iota" : "\u03b9" ,
4121 "\\kappa" : "\u03ba" ,
4122 "\\lambda" : "\u03bb" ,
4123 "\\Lambda" : "\u039b" ,
4126 "\\omega" : "\u03c9" ,
4127 "\\Omega" : "\u03a9" ,
4128 "\\phi" : "\u03c6" ,
4129 "\\Phi" : "\u03a6" ,
4132 "\\psi" : "\u03c8" ,
4133 "\\Psi" : "\u03a8" ,
4134 "\\rho" : "\u03c1" ,
4135 "\\sigma" : "\u03c3" ,
4136 "\\Sigma" : "\u03a3" ,
4137 "\\tau" : "\u03c4" ,
4138 "\\theta" : "\u03b8" ,
4139 "\\Theta" : "\u0398" ,
4140 "\\upsilon" : "\u03c5" ,
4141 "\\Upsilon" : "\u03d2" ,
4142 "\\varepsilon" : "\u03b5" ,
4143 "\\varkappa" : "\u03f0" ,
4144 "\\varphi" : "\u03d5" ,
4145 "\\varpi" : "\u03d6" ,
4146 "\\varrho" : "\u03f1" ,
4147 "\\varsigma" : "\u03c2" ,
4148 "\\vartheta" : "\u03d1" ,
4151 "\\zeta" : "\u03b6" ,
4204 "\\vdots" : "\u22ee" ,
4205 "\\hdots" : "\u2026" ,
4206 "\\ldots" : "\u2026" ,
4207 "\\dots" : "\u2026" ,
4208 "\\cdots" : "\u00b7\u00b7\u00b7" ,
4209 "\\dotsb" : "\u00b7\u00b7\u00b7" ,
4210 "\\dotsc" : "\u2026" ,
4211 "\\dotsi" : "\u22c5\u22c5\u22c5" ,
4212 "\\dotsm" : "\u22c5\u22c5\u22c5" ,
4213 "\\dotso" : "\u2026" ,
4214 "\\ddots" : "\u22f1" ,
4215 // Common abbreviation for \mathbb letters
4216 "\\A" : "\uD835\uDD38" ,
4217 "\\bA" : "\uD835\uDD38" ,
4218 "\\B" : "\uD835\uDD39" ,
4219 "\\bB" : "\uD835\uDD39" ,
4222 "\\D" : "\uD835\uDD3B" ,
4223 "\\bD" : "\uD835\uDD3B" ,
4224 "\\E" : "\uD835\uDD3C" ,
4225 "\\bE" : "\uD835\uDD3C" ,
4226 "\\F" : "\uD835\uDD3D" ,
4227 "\\bF" : "\uD835\uDD3D" ,
4228 "\\G" : "\uD835\uDD3E" ,
4229 "\\bG" : "\uD835\uDD3E" ,
4232 "\\I" : "\uD835\uDD40" ,
4233 "\\bI" : "\uD835\uDD40" ,
4234 "\\J" : "\uD835\uDD41" ,
4235 "\\bJ" : "\uD835\uDD41" ,
4236 "\\K" : "\uD835\uDD42" ,
4237 "\\bK" : "\uD835\uDD42" ,
4238 "\\L" : "\uD835\uDD43" ,
4239 "\\bL" : "\uD835\uDD43" ,
4240 "\\M" : "\uD835\uDD44" ,
4241 "\\bM" : "\uD835\uDD44" ,
4244 "\\O" : "\uD835\uDD46" ,
4245 "\\bO" : "\uD835\uDD46" ,
4252 "\\S" : "\uD835\uDD4A" ,
4253 "\\bS" : "\uD835\uDD4A" ,
4254 "\\T" : "\uD835\uDD4B" ,
4255 "\\bT" : "\uD835\uDD4B" ,
4256 "\\U" : "\uD835\uDD4C" ,
4257 "\\bU" : "\uD835\uDD4C" ,
4258 "\\V" : "\uD835\uDD4D" ,
4259 "\\bV" : "\uD835\uDD4D" ,
4260 "\\W" : "\uD835\uDD4E" ,
4261 "\\bW" : "\uD835\uDD4E" ,
4262 "\\X" : "\uD835\uDD4F" ,
4263 "\\bX" : "\uD835\uDD4F" ,
4264 "\\Y" : "\uD835\uDD50" ,
4265 "\\bY" : "\uD835\uDD50" ,
4268 // Common abbreviations for \mathcal letters
4269 "\\cA" : "\uD835\uDC9C" ,
4271 "\\cC" : "\uD835\uDC9E" ,
4272 "\\cD" : "\uD835\uDC9F" ,
4275 "\\cG" : "\uD835\uDCA2" ,
4278 "\\cJ" : "\uD835\uDCA5" ,
4279 "\\cK" : "\uD835\uDCA6" ,
4282 "\\cN" : "\uD835\uDCA9" ,
4283 "\\cO" : "\uD835\uDCAA" ,
4284 "\\OO" : "\uD835\uDCAA" ,
4285 "\\cP" : "\uD835\uDCAB" ,
4286 "\\cQ" : "\uD835\uDCAC" ,
4288 "\\cS" : "\uD835\uDCAE" ,
4289 "\\cT" : "\uD835\uDCAF" ,
4290 "\\cU" : "\uD835\uDCB0" ,
4291 "\\cV" : "\uD835\uDCB1" ,
4292 "\\cW" : "\uD835\uDCB2" ,
4293 "\\cX" : "\uD835\uDCB3" ,
4294 "\\cY" : "\uD835\uDCB4" ,
4295 "\\cZ" : "\uD835\uDCB5" ,
4301 "\\eps" : "\u03f5" ,
4304 var g_word_operators
4305 = {"\\arccos" : "arccos" ,
4306 "\\arcsin" : "arcsin" ,
4307 "\\arctan" : "arctan" ,
4332 var g_big_word_operators
4333 = {"\\inf" : "inf" ,
4334 "\\injlim" : "inj lim" ,
4336 "\\liminf" : "lim inf" ,
4337 "\\limsup" : "lum sup" ,
4340 "\\projlim" : "proj lim" ,
4345 = {"\\alpha" : "\u03b1" ,
4346 "\\beta" : "\u03b2" ,
4347 "\\chi" : "\u03c7" ,
4348 "\\delta" : "\u03b4" ,
4349 "\\Delta" : "\u0394" ,
4350 "\\digamma" : "\u03dd" ,
4351 "\\epsilon" : "\u03f5" ,
4352 "\\eta" : "\u03b7" ,
4353 "\\gamma" : "\u03b3" ,
4354 "\\Gamma" : "\u0393" ,
4355 "\\iota" : "\u03b9" ,
4356 "\\kappa" : "\u03ba" ,
4357 "\\lambda" : "\u03bb" ,
4358 "\\Lambda" : "\u039b" ,
4361 "\\omega" : "\u03c9" ,
4362 "\\Omega" : "\u03a9" ,
4363 "\\phi" : "\u03c6" ,
4364 "\\Phi" : "\u03a6" ,
4367 "\\psi" : "\u03c8" ,
4368 "\\Psi" : "\u03a8" ,
4369 "\\rho" : "\u03c1" ,
4370 "\\sigma" : "\u03c3" ,
4371 "\\Sigma" : "\u03a3" ,
4372 "\\tau" : "\u03c4" ,
4373 "\\theta" : "\u03b8" ,
4374 "\\Theta" : "\u0398" ,
4375 "\\upsilon" : "\u03c5" ,
4376 "\\Upsilon" : "\u03d2" ,
4377 "\\varepsilon" : "\u03b5" ,
4378 "\\varkappa" : "\u03f0" ,
4379 "\\varphi" : "\u03d5" ,
4380 "\\varpi" : "\u03d6" ,
4381 "\\varrho" : "\u03f1" ,
4382 "\\varsigma" : "\u03c2" ,
4383 "\\vartheta" : "\u03d1" ,
4386 "\\zeta" : "\u03b6" ,
4389 function v_fraction_to_mathml (tokens ) {
4390 var v_numerator = v_piece_to_mathml (tokens ) ;
4391 var v_denominator = v_piece_to_mathml (tokens ) ;
4392 return result_element( "mfrac" ,0 , v_numerator , v_denominator ) ;
4394 function v_binom_to_mathml (tokens ) {
4395 var v_top = v_piece_to_mathml (tokens ) ;
4396 var v_bottom = v_piece_to_mathml (tokens ) ;
4397 return result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , result_element( "mfrac" , 1
4398 , "linethickness" , "0" , v_top , v_bottom ) , result_element( "mo" ,0 , ")" ) ) ;
4400 function v_sqrt_to_mathml (tokens ) {
4401 var v_index = v_optional_arg_to_mathml (tokens ) ;
4402 var v_object = v_piece_to_mathml (tokens ) ;
4403 if( ( v_index != null ) ) {
4404 return result_element( "mroot" ,0 , v_object , v_index ) ;
4407 return result_element( "msqrt" ,0 , v_object ) ;
4410 function v_parenthesized_operator (tokens , v_word ) {
4411 var v_object = v_piece_to_mathml (tokens ) ;
4412 if( ( v_word != null ) ) {
4413 return result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , result_element( "mo" ,0 , v_word ) , v_object , result_element( "mo" ,0 , ")" ) ) ;
4416 return result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , v_object , result_element( "mo" ,0 , ")" ) ) ;
4419 function v_operatorname_to_mathml (tokens ) {
4420 var v_result = result_element( "mo" ,0 , tokens.list[tokens.index] ) ;
4424 function v_displaystyle_to_mathml (tokens ) {
4425 var v_result = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4427 return result_element( "mstyle" , 2
4428 , "displaystyle" , "true" , "scriptlevel" , "0" , v_result ) ;
4430 function v_displaymath_to_mathml (tokens ) {
4431 var v_result = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4433 v_finish_latex_block (tokens );
4434 return result_element( "mstyle" , 2
4435 , "displaystyle" , "true" , "scriptlevel" , "0" , v_result ) ;
4437 function v_font_to_mathml (tokens , v_font_name ) {
4438 if( ( tokens.list[tokens.index] != "{" ) ) {
4439 var v_result = result_element( "mi" , 1
4440 , "mathvariant" , v_font_name , tokens.list[tokens.index] ) ;
4441 if( ( v_font_name == "normal" ) ) {
4443 v_result , "fontstyle" , "normal" );
4449 var v_result = v_piece_to_mathml (tokens ) ;
4451 v_result , "mathvariant" , v_font_name );
4452 if( ( v_font_name == "normal" ) ) {
4454 v_result , "fontstyle" , "normal" );
4459 function v_old_font_to_mathml (tokens , v_font_name ) {
4460 return result_element( "mstyle" , 2
4461 , "mathvariant" , v_font_name , "fontstyle" , ( ( v_font_name == "normal" ) ? "normal" : null ) , v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4464 function v_size_to_mathml (tokens , v_min_size , v_max_size ) {
4465 var v_result = v_piece_to_mathml (tokens ) ;
4467 v_result , "minsize" , v_min_size );
4469 v_result , "maxsize" , v_max_size );
4472 function v_accent_to_mathml (tokens , v_char ) {
4473 return result_element( "mover" , 1
4474 , "accent" , "true" , v_piece_to_mathml (tokens ) , result_element( "mo" ,0 , v_char ) ) ;
4476 function v_matrix_to_mathml (tokens , v_open_delim , v_close_delim ) {
4477 var v_mtable = v_matrix_to_mtable (tokens , result_element( "mtable" ,0) ) ;
4478 if( ( ( v_open_delim != null ) || ( v_close_delim != null ) ) ) {
4479 var v_mrow = result_element( "mrow" ,0) ;
4480 if( ( v_open_delim != null ) ) {
4481 result_element_append( v_mrow , result_element( "mo" ,0 , v_open_delim ) );
4483 result_element_append( v_mrow , v_mtable );
4484 if( ( v_close_delim != null ) ) {
4485 result_element_append( v_mrow , result_element( "mo" ,0 , v_close_delim ) );
4493 function v_array_to_mathml (tokens ) {
4494 var v_mtable = result_element( "mtable" ,0) ;
4495 if( ( tokens.list[tokens.index] == "{" ) ) {
4497 while( ( ( tokens.list[tokens.index] != null ) && ( tokens.list[tokens.index] != "}" ) ) ) {
4498 if( ( tokens.list[tokens.index] == "c" ) ) {
4500 v_mtable , "columnalign" , "center " );
4502 else if( ( tokens.list[tokens.index] == "l" ) ) {
4504 v_mtable , "columnalign" , "left " );
4506 else if( ( tokens.list[tokens.index] == "r" ) ) {
4508 v_mtable , "columnalign" , "right " );
4512 if( ( tokens.list[tokens.index] != null ) ) {
4516 return v_matrix_to_mtable (tokens , v_mtable ) ;
4518 function v_matrix_to_mtable (tokens , v_mtable ) {
4519 var v_mtr = result_element( "mtr" ,0) ;
4520 var v_mtd = result_element( "mtd" ,0) ;
4521 var v_token = tokens.list[tokens.index] ;
4522 result_element_append( v_mtable , v_mtr );
4523 result_element_append( v_mtr , v_mtd );
4524 while( ( ( v_token != null ) && ( v_token != "\\end" ) ) ) {
4525 if( ( v_token == "\\\\" ) ) {
4526 v_mtr = result_element( "mtr" ,0) ;
4527 v_mtd = result_element( "mtd" ,0) ;
4528 result_element_append( v_mtable , v_mtr );
4529 result_element_append( v_mtr , v_mtd );
4532 else if( ( v_token == "&" ) ) {
4533 v_mtd = result_element( "mtd" ,0) ;
4534 result_element_append( v_mtr , v_mtd );
4538 result_element_append( v_mtd , v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4541 v_token = tokens.list[tokens.index] ;
4543 v_finish_latex_block (tokens );
4546 function v_over_to_mathml (tokens , v_char ) {
4547 return result_element( "mover" ,0 , v_piece_to_mathml (tokens ) , result_element( "mo" ,0 , v_char ) ) ;
4549 function v_under_to_mathml (tokens , v_char ) {
4550 return result_element( "munder" ,0 , v_piece_to_mathml (tokens ) , result_element( "mo" ,0 , v_char ) ) ;
4552 function v_delimiter_to_mathml (tokens , v_end_command , v_min_size , v_max_size ) {
4553 var v_mrow = result_element( "mrow" ,0) ;
4554 result_element_append( v_mrow , result_element( "mo" , 2
4555 , "minsize" , v_min_size , "maxsize" , v_max_size , v_read_delimiter (tokens ) ) );
4556 result_element_append( v_mrow , v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4558 if( ( tokens.list[tokens.index] != v_end_command ) ) {
4562 result_element_append( v_mrow , result_element( "mo" , 2
4563 , "minsize" , v_min_size , "maxsize" , v_max_size , v_read_delimiter (tokens ) ) );
4566 function v_read_delimiter (tokens ) {
4567 var v_token = tokens.list[tokens.index] ;
4568 if( ( v_token == null ) ) {
4569 throw "unexpected eof" ;
4571 else if( ( v_token == "." ) ) {
4575 else if( ( v_token == "<" ) ) {
4579 else if( ( v_token == ">" ) ) {
4583 else if( ( v_token in g_punct_and_space
4586 return g_punct_and_space
4589 else if( ( v_token in g_left_delimiters
4592 return g_left_delimiters
4595 else if( ( v_token in g_right_delimiters
4598 return g_right_delimiters
4601 else if( ( v_token in g_operator_symbols
4604 return g_operator_symbols
4608 throw "invalid delimiter" ;
4611 function v_latex_block_to_mathml (tokens ) {
4612 v_cmd = tokens.list[tokens.index] ;
4613 if( ( v_cmd in g_tex_environments
4616 return g_tex_environments
4617 [ v_cmd ] (tokens ) ;
4620 throw "unknown command" ;
4623 function v_finish_latex_block (tokens ) {
4624 if( ( tokens.list[tokens.index] == null ) ) {
4625 throw "unexpected eof" ;
4630 function v_combining_to_mathml (tokens , v_char ) {
4631 var v_base = tokens.list[tokens.index] ;
4633 return result_element( "mo" ,0 , v_base , v_char ) ;
4635 var g_char_escape_codes
4639 function v_char_escape_to_mathml (tokens ) {
4640 var v_result = null ;
4641 if( ( tokens.list[tokens.index] in g_char_escape_codes
4643 v_result = result_element( "mtext" ,0 , g_char_escape_codes
4644 [ tokens.list[tokens.index] ] ) ;
4647 v_result = result_element( "merror" ,0 , "\\char" , tokens.list[tokens.index] ) ;
4652 function v_text_to_mathml (tokens ) {
4653 if( ( tokens.list[tokens.index] != "{" ) ) {
4654 var v_result = result_element( "mtext" ,0 , tokens.list[tokens.index] ) ;
4659 var v_result = null ;
4662 while( ( tokens.list[tokens.index] != null ) ) {
4663 if( ( tokens.list[tokens.index] == "}" ) ) {
4667 else if( ( tokens.list[tokens.index] == "$" ) ) {
4669 v_node = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4674 v_node = result_element( "mtext" ,0 , tokens.list[tokens.index] ) ;
4677 if( ( v_mrow != null ) ) {
4678 result_element_append( v_mrow , v_node );
4680 else if( ( v_result != null ) ) {
4681 v_mrow = result_element( "mrow" ,0 , v_result , v_node ) ;
4692 "\\frac" : v_fraction_to_mathml ,
4693 "\\dfrac" : v_fraction_to_mathml ,
4694 "\\tfrac" : v_fraction_to_mathml ,
4695 "\\binom" : v_binom_to_mathml ,
4696 "\\sqrt" : v_sqrt_to_mathml ,
4697 "\\operatorname" : v_operatorname_to_mathml ,
4698 "\\displaystyle" : v_displaystyle_to_mathml ,
4699 "\\pod" : function(tokens ) {return v_parenthesized_operator (tokens , null ) ;} ,
4700 "\\pmod" : function(tokens ) {return v_parenthesized_operator (tokens , "mod" ) ;} ,
4701 "\\boldsymbol" : function(tokens ) {return v_font_to_mathml (tokens , "bold" ) ;} ,
4702 "\\bold" : function(tokens ) {return v_font_to_mathml (tokens , "bold" ) ;} ,
4703 "\\Bbb" : function(tokens ) {return v_font_to_mathml (tokens , "double-struck" ) ;} ,
4704 "\\mathbb" : function(tokens ) {return v_font_to_mathml (tokens , "double-struck" ) ;} ,
4705 "\\mathbbmss" : function(tokens ) {return v_font_to_mathml (tokens , "double-struck" ) ;} ,
4706 "\\mathbf" : function(tokens ) {return v_font_to_mathml (tokens , "bold" ) ;} ,
4707 "\\mathop" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4708 "\\mathopen" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4709 "\\mathclose" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4710 "\\mathrm" : function(tokens ) {return v_font_to_mathml (tokens , "normal" ) ;} ,
4711 "\\mathfrak" : function(tokens ) {return v_font_to_mathml (tokens , "fraktur" ) ;} ,
4712 "\\germ" : function(tokens ) {return v_font_to_mathml (tokens , "fraktur" ) ;} ,
4713 "\\mathit" : function(tokens ) {return v_font_to_mathml (tokens , "italic" ) ;} ,
4714 "\\mathscr" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4715 "\\scr" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4716 "\\mathcal" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4717 "\\mathsf" : function(tokens ) {return v_font_to_mathml (tokens , "sans-serif" ) ;} ,
4718 "\\mathtt" : function(tokens ) {return v_font_to_mathml (tokens , "monospace" ) ;} ,
4719 "\\EuScript" : function(tokens ) {return v_font_to_mathml (tokens , "script" ) ;} ,
4720 "\\bf" : function(tokens ) {return v_old_font_to_mathml (tokens , "bold" ) ;} ,
4721 "\\rm" : function(tokens ) {return v_old_font_to_mathml (tokens , "normal" ) ;} ,
4722 "\\roman" : function(tokens ) {return v_old_font_to_mathml (tokens , "normal" ) ;} ,
4723 "\\tag" : function(tokens ) {return v_old_font_to_mathml (tokens , "bold" ) ;} ,
4724 "\\big" : function(tokens ) {return v_size_to_mathml (tokens , "2" , "2" ) ;} ,
4725 "\\Big" : function(tokens ) {return v_size_to_mathml (tokens , "3" , "3" ) ;} ,
4726 "\\bigg" : function(tokens ) {return v_size_to_mathml (tokens , "4" , "4" ) ;} ,
4727 "\\Bigg" : function(tokens ) {return v_size_to_mathml (tokens , "5" , "5" ) ;} ,
4728 "\\acute" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0301" ) ;} ,
4729 "\\grave" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0300" ) ;} ,
4730 "\\tilde" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0303" ) ;} ,
4731 "\\bar" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0304" ) ;} ,
4732 "\\breve" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0306" ) ;} ,
4733 "\\check" : function(tokens ) {return v_accent_to_mathml (tokens , "\u030c" ) ;} ,
4734 "\\hat" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0302" ) ;} ,
4735 "\\vec" : function(tokens ) {return v_accent_to_mathml (tokens , "\u20d7" ) ;} ,
4736 "\\dot" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0307" ) ;} ,
4737 "\\ddot" : function(tokens ) {return v_accent_to_mathml (tokens , "\u0308" ) ;} ,
4738 "\\dddot" : function(tokens ) {return v_accent_to_mathml (tokens , "\u20db" ) ;} ,
4739 "\\underbrace" : function(tokens ) {return v_under_to_mathml (tokens , "\ufe38" ) ;} ,
4740 "\\overbrace" : function(tokens ) {return v_over_to_mathml (tokens , "\ufe37" ) ;} ,
4741 "\\underline" : function(tokens ) {return v_under_to_mathml (tokens , "\u0332" ) ;} ,
4742 "\\overline" : function(tokens ) {return v_over_to_mathml (tokens , "\u00af" ) ;} ,
4743 "\\widetilde" : function(tokens ) {return v_over_to_mathml (tokens , "\u0303" ) ;} ,
4744 "\\widehat" : function(tokens ) {return v_over_to_mathml (tokens , "\u0302" ) ;} ,
4745 "\\not" : function(tokens ) {return v_combining_to_mathml (tokens , "\u0338" ) ;} ,
4746 "\\left" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\right" , "1" , null ) ;} ,
4747 "\\bigl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\bigr" , "2" , "2" ) ;} ,
4748 "\\Bigl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\Bigr" , "3" , "3" ) ;} ,
4749 "\\biggl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\biggr" , "4" , "4" ) ;} ,
4750 "\\Biggl" : function(tokens ) {return v_delimiter_to_mathml (tokens , "\\Biggr" , "5" , "5" ) ;} ,
4751 "\\char" : v_char_escape_to_mathml ,
4752 "\\!" : function(tokens ) {return null ;} ,
4753 "\\text" : v_text_to_mathml ,
4754 "\\textnormal" : v_text_to_mathml ,
4755 "\\textrm" : v_text_to_mathml ,
4756 "\\textsl" : v_text_to_mathml ,
4757 "\\textit" : v_text_to_mathml ,
4758 "\\texttt" : v_text_to_mathml ,
4759 "\\textbf" : v_text_to_mathml ,
4760 "\\hbox" : v_text_to_mathml ,
4761 "\\mbox" : v_text_to_mathml ,
4762 "\\begin" : v_latex_block_to_mathml ,
4765 var g_tex_environments
4766 = {"smallmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "(" , ")" ) ;} ,
4767 "pmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "(" , ")" ) ;} ,
4768 "bmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "[" , "]" ) ;} ,
4769 "Bmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "{" , "}" ) ;} ,
4770 "vmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "|" , "|" ) ;} ,
4771 "Vmatrix" : function(tokens ) {return v_matrix_to_mathml (tokens , "\u2016" , "\u2016" ) ;} ,
4772 "cases" : function(tokens ) {return v_matrix_to_mathml (tokens , "{" , null ) ;} ,
4773 "array" : v_array_to_mathml ,
4774 "displaymath" : v_displaymath_to_mathml ,
4777 var g_limit_commands
4778 = {"\\bigcap" : "\u22c2" ,
4779 "\\bigcup" : "\u22c3" ,
4780 "\\bigodot" : "\u2a00" ,
4781 "\\bigoplus" : "\u2a01" ,
4782 "\\bigotimes" : "\u2a02" ,
4783 "\\bigsqcup" : "\u2a06" ,
4784 "\\biguplus" : "\u2a04" ,
4785 "\\bigvee" : "\u22c1" ,
4786 "\\bigwedge" : "\u22c0" ,
4787 "\\coprod" : "\u2210" ,
4788 "\\prod" : "\u220f" ,
4789 "\\sum" : "\u2211" ,
4791 "\\injlim" : "inj lim" ,
4793 "\\liminf" : "lim inf" ,
4794 "\\limsup" : "lum sup" ,
4797 "\\projlim" : "proj lim" ,
4799 "\\underbrace" : null ,
4800 "\\overbrace" : null ,
4801 "\\underline" : null ,
4802 "\\overline" : null ,
4805 function v_piece_to_mathml (tokens ) {
4806 var v_token = tokens.list[tokens.index] ;
4807 var v_result = null ;
4808 if( ( v_token == "{" ) ) {
4810 v_result = v_subexpr_chain_to_mathml (tokens , g_hard_stop_tokens
4812 if( ( tokens.list[tokens.index] == "}" ) ) {
4816 else if( ( v_token in g_relation_symbols
4818 v_result = result_element( "mo" ,0 , g_relation_symbols
4822 else if( ( v_token in g_operator_symbols
4824 v_result = result_element( "mo" ,0 , g_operator_symbols
4828 else if( ( v_token in g_left_delimiters
4830 v_result = result_element( "mo" ,0 , g_left_delimiters
4834 else if( ( v_token in g_right_delimiters
4836 v_result = result_element( "mo" ,0 , g_right_delimiters
4840 else if( ( v_token in g_word_operators
4842 v_result = result_element( "mi" , 1
4843 , "mathvariant" , "normal" , g_word_operators
4847 else if( ( v_token in g_greek_letters
4849 v_result = result_element( "mi" , 1
4850 , "fontstyle" , "normal" , g_greek_letters
4854 else if( ( v_token in g_named_identifiers
4856 v_result = result_element( "mi" ,0 , g_named_identifiers
4860 else if( ( v_token in g_punct_and_space
4862 v_result = result_element( "mtext" ,0 , g_punct_and_space
4866 else if( ( v_token in g_tex_commands
4869 v_result = g_tex_commands
4870 [ v_token ] (tokens ) ;
4873 v_result = result_element( "mn" ,0 , v_token ) ;
4878 function v_subexpr_to_mathml (tokens ) {
4879 var v_result = null ;
4880 var v_mmultiscripts = null ;
4881 var v_mprescripts = null ;
4882 if( ( ( tokens.list[tokens.length<=tokens.index+ 0 ? tokens.length-1 : tokens.index+ 0 ]
4883 == "{" ) && ( tokens.list[tokens.length<=tokens.index+ 1 ? tokens.length-1 : tokens.index+ 1 ]
4884 == "}" ) && ( ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4885 == "_" ) || ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4887 v_mmultiscripts = result_element( "mmultiscripts" ,0) ;
4888 v_mprescripts = result_element( "mprescripts" ,0) ;
4889 result_element_append( v_mmultiscripts , v_mprescripts );
4890 while( ( ( tokens.list[tokens.length<=tokens.index+ 0 ? tokens.length-1 : tokens.index+ 0 ]
4891 == "{" ) && ( tokens.list[tokens.length<=tokens.index+ 1 ? tokens.length-1 : tokens.index+ 1 ]
4892 == "}" ) && ( ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4893 == "_" ) || ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4895 var v_subscript = null ;
4896 var v_superscript = null ;
4899 if( ( tokens.list[tokens.index] == "_" ) ) {
4901 v_subscript = v_piece_to_mathml (tokens ) ;
4903 else if( ( tokens.list[tokens.index] == "^" ) ) {
4905 v_superscript = v_piece_to_mathml (tokens ) ;
4907 if( ( tokens.list[tokens.index] == "_" ) ) {
4909 v_subscript = v_piece_to_mathml (tokens ) ;
4911 else if( ( tokens.list[tokens.index] == "^" ) ) {
4913 v_superscript = v_piece_to_mathml (tokens ) ;
4915 result_element_append( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) );
4916 result_element_append( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) );
4919 var v_limit_style = ( tokens.list[tokens.index] in g_limit_commands
4921 if( ( tokens.list[tokens.index] == null ) ) {
4922 if( ( v_mmultiscripts != null ) ) {
4923 result_element_prepend( v_mmultiscripts , result_element( "mrow" ,0) , v_mprescripts );
4924 return v_mmultiscripts ;
4927 return result_element( "mrow" ,0) ;
4930 else if( ( tokens.list[tokens.index] in g_left_delimiters
4932 v_result = v_heuristic_subexpression (tokens ) ;
4935 v_result = v_piece_to_mathml (tokens ) ;
4937 var v_base = v_result ;
4938 var v_subscript = null ;
4939 var v_superscript = null ;
4940 if( ( tokens.list[tokens.index] == "_" ) ) {
4942 v_subscript = v_piece_to_mathml (tokens ) ;
4944 else if( ( tokens.list[tokens.index] == "^" ) ) {
4946 v_superscript = v_piece_to_mathml (tokens ) ;
4948 if( ( tokens.list[tokens.index] == "_" ) ) {
4950 v_subscript = v_piece_to_mathml (tokens ) ;
4952 else if( ( tokens.list[tokens.index] == "^" ) ) {
4954 v_superscript = v_piece_to_mathml (tokens ) ;
4956 if( ( v_mmultiscripts != null ) ) {
4957 result_element_prepend( v_mmultiscripts , v_base , v_mprescripts );
4958 result_element_prepend( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) , v_mprescripts );
4959 result_element_prepend( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) , v_mprescripts );
4961 while( ( ( tokens.list[tokens.length<=tokens.index+ 0 ? tokens.length-1 : tokens.index+ 0 ]
4962 == "{" ) && ( tokens.list[tokens.length<=tokens.index+ 1 ? tokens.length-1 : tokens.index+ 1 ]
4963 == "}" ) && ( ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4964 == "_" ) || ( tokens.list[tokens.length<=tokens.index+ 2 ? tokens.length-1 : tokens.index+ 2 ]
4966 if( ( v_mmultiscripts == null ) ) {
4967 v_mmultiscripts = result_element( "mmultiscripts" ,0 , v_base ) ;
4968 v_mprescripts = null ;
4969 if( ( ( v_superscript != null ) || ( v_subscript != null ) ) ) {
4970 result_element_append( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) );
4971 result_element_append( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) );
4974 var v_subscript = null ;
4975 var v_superscript = null ;
4978 if( ( tokens.list[tokens.index] == "_" ) ) {
4980 v_subscript = v_piece_to_mathml (tokens ) ;
4982 else if( ( tokens.list[tokens.index] == "^" ) ) {
4984 v_superscript = v_piece_to_mathml (tokens ) ;
4986 if( ( tokens.list[tokens.index] == "_" ) ) {
4988 v_subscript = v_piece_to_mathml (tokens ) ;
4990 else if( ( tokens.list[tokens.index] == "^" ) ) {
4992 v_superscript = v_piece_to_mathml (tokens ) ;
4994 result_element_prepend( v_mmultiscripts , ( ( v_subscript != null ) ? v_subscript : result_element( "none" ,0) ) , v_mprescripts );
4995 result_element_prepend( v_mmultiscripts , ( ( v_superscript != null ) ? v_superscript : result_element( "none" ,0) ) , v_mprescripts );
4997 if( ( v_mmultiscripts != null ) ) {
4998 v_result = v_mmultiscripts ;
5000 else if( ( ( v_subscript != null ) && ( v_superscript != null ) ) ) {
5001 v_result = result_element( ( v_limit_style ? "munderover" : "msubsup" ) ,0 , v_base , v_subscript , v_superscript ) ;
5003 else if( ( v_subscript != null ) ) {
5004 v_result = result_element( ( v_limit_style ? "munder" : "msub" ) ,0 , v_base , v_subscript ) ;
5006 else if( ( v_superscript != null ) ) {
5007 v_result = result_element( ( v_limit_style ? "mover" : "msup" ) ,0 , v_base , v_superscript ) ;
5011 function v_subexpr_chain_to_mathml (tokens , v_stop_tokens ) {
5012 var v_result = null ;
5014 var v_mfrac = null ;
5015 var v_wrapped_result = null ;
5016 while( ( ( tokens.list[tokens.index] != null ) && !( ( tokens.list[tokens.index] in v_stop_tokens ) ) ) ) {
5017 if( ( tokens.list[tokens.index] == "\\over" ) ) {
5019 v_mfrac = result_element( "mfrac" ,0 , v_result ) ;
5020 v_wrapped_result = v_mfrac ;
5024 else if( ( tokens.list[tokens.index] == "\\choose" ) ) {
5026 v_mfrac = result_element( "mfrac" , 1
5027 , "linethickness" , "0" , v_result ) ;
5028 v_wrapped_result = result_element( "mrow" ,0 , result_element( "mo" ,0 , "(" ) , v_mfrac , result_element( "mo" ,0 , ")" ) ) ;
5033 var v_node = v_collect_precedence_group (tokens , g_relations_precedence_group
5034 , v_stop_tokens , function(tokens , v_stop_tokens ) {return v_collect_precedence_group (tokens , g_addition_precedence_group
5035 , v_stop_tokens , function(tokens , v_stop_tokens ) {return v_collect_precedence_group (tokens , g_multiplication_precedence_group
5036 , v_stop_tokens , v_collect_invisible_group ) ;} ) ;} ) ;
5037 if( ( v_mrow != null ) ) {
5038 result_element_append( v_mrow , v_node );
5040 else if( ( v_result != null ) ) {
5041 v_mrow = result_element( "mrow" ,0 , v_result , v_node ) ;
5049 if( ( v_mfrac != null ) ) {
5050 result_element_append( v_mfrac , v_result );
5051 return v_wrapped_result ;
5057 var g_optional_arg_stop_tokens
5073 function v_optional_arg_to_mathml (tokens ) {
5074 if( ( tokens.list[tokens.index] != "[" ) ) {
5078 var v_result = v_subexpr_chain_to_mathml (tokens , g_optional_arg_stop_tokens
5080 if( ( tokens.list[tokens.index] == "]" ) ) {
5085 var g_hard_stop_tokens
5100 var g_right_delimiter_stop_tokens
5119 "\\rVert" : "\u2016" ,
5120 "\\rceil" : "\u2309" ,
5121 "\\rfloor" : "\u230b" ,
5122 "\\rmoustache" : "\u23b1" ,
5123 "\\rangle" : "\u232a" ,
5126 function v_heuristic_subexpression (tokens ) {
5127 var v_result = result_element( "mrow" ,0) ;
5128 result_element_append( v_result , v_piece_to_mathml (tokens ) );
5129 result_element_append( v_result , v_subexpr_chain_to_mathml (tokens , g_right_delimiter_stop_tokens
5131 if( ( ( tokens.list[tokens.index] != null ) && !( ( tokens.list[tokens.index] in g_hard_stop_tokens
5133 result_element_append( v_result , v_piece_to_mathml (tokens ) );
5137 var g_relations_precedence_group
5138 = g_relation_symbols
5140 var g_addition_precedence_group
5146 var g_multiplication_precedence_group
5153 function v_collect_precedence_group (tokens , v_operators , v_stop_tokens , v_reader ) {
5154 var v_result = v_reader (tokens , v_stop_tokens ) ;
5156 while( ( ( tokens.list[tokens.index] != null ) && !( ( tokens.list[tokens.index] in v_stop_tokens ) ) && ( tokens.list[tokens.index] in v_operators ) ) ) {
5157 if( ( v_mrow == null ) ) {
5158 v_mrow = result_element( "mrow" ,0 , v_result ) ;
5161 result_element_append( v_mrow , v_piece_to_mathml (tokens ) );
5162 if( ( ( tokens.list[tokens.index] != null ) && ( tokens.list[tokens.index] in v_stop_tokens ) ) ) {
5166 result_element_append( v_mrow , v_reader (tokens , v_stop_tokens ) );
5171 function v_collect_invisible_group (tokens , v_stop_tokens ) {
5172 var v_result = v_subexpr_to_mathml (tokens ) ;
5174 while( ( ( tokens.list[tokens.index] != null ) && !( ( tokens.list[tokens.index] in v_stop_tokens ) ) && ( ( tokens.list[tokens.index] in g_named_identifiers
5175 ) || ( tokens.list[tokens.index] in g_left_delimiters
5177 if( ( v_mrow == null ) ) {
5178 v_mrow = result_element( "mrow" ,0 , v_result ) ;
5181 result_element_append( v_mrow , result_element( "mo" ,0 , "\u2062" ) );
5182 if( ( ( tokens.list[tokens.index] != null ) && ( tokens.list[tokens.index] in v_stop_tokens ) ) ) {
5186 result_element_append( v_mrow , v_subexpr_to_mathml (tokens ) );
5193 var/*const*/ tokenize_re = /(\\begin|\\operatorname|\\mathrm|\\mathop|\\end)\s*\{\s*([A-Z a-z]+)\s*\}|(\\[a-zA-Z]+|\\[\\#\{\},:;!])|(\s+)|([0-9\.]+)|([\$!"#%&'()*+,-.\/:;<=>?\[\]^_`\{\|\}~])|([a-zA-Z])/g;
5195 var/*const*/ tokenize_text_re = /[\${}\\]|\\[a-zA-Z]+|[^{}\$]+/g;
5197 var/*const*/ tokenize_text_commands = {
5209 function tokenize_latex_math(input)
5211 var result = new Array();
5212 var in_text_mode = 0;
5213 var brace_level = [];
5216 if(input.charAt(0) == '$' &&
5217 input.charAt(input.length-1) == '$')
5218 input = input.slice(1, input.length-1);
5222 tokenize_re.lastIndex = pos;
5223 var m = tokenize_re.exec(input);
5224 pos = tokenize_re.lastIndex;
5228 } else if(m[1] != null) {
5229 result.push(m[1], m[2]);
5230 } else if(m[3] == '\\sp') {
5232 } else if(m[3] == '\\sb') {
5237 } else if(m[4] != null) {
5239 } else if(m[3] != null && m[3] in tokenize_text_commands) {
5241 brace_level.push(0);
5247 tokenize_text_re.lastIndex = pos;
5248 var m = tokenize_text_re.exec(input);
5249 pos = tokenize_text_re.lastIndex;
5253 } else if(m[0] == '$') {
5255 } else if(m[0] == '{') {
5256 brace_level[brace_level.length-1]++;
5257 } else if(m[0] == '}') {
5258 if(--brace_level[brace_level.length-1] <= 0) {
5269 function post_process_mathml(event)
5271 var url = GM_getValue('click-post-url', null);
5275 var ser = new XMLSerializer();
5276 var xhr = GM_xmlhttpRequest({
5279 headers: { 'Content-Type': 'text/xml; charset=utf-8',
5280 'Content-Location': document.location },
5281 data: ser.serializeToString(event.currentTarget),
5282 onerror: function(details) {
5283 alert("There was an error processing the request. " +
5284 "HTTP status code " + details.status + ' ' + details.statusText);
5286 onload: function(details) {
5287 window.status = "Successfully posted MathML. Status: "
5288 + details.status + ' ' + details.statusText;
5291 window.status = "Posting MathML to " + url + "...";
5295 function patch_img(node)
5298 if(node.currentTarget)
5299 node = node.currentTarget;
5301 var alt = node.getAttribute('alt');
5304 /^\\includegraphics|^\$\\displaystyle \\xymatrix/.test(alt))
5307 var latex_string = null;
5312 if((node.parentNode.tagName == 'DIV' &&
5313 node.parentNode.getAttribute('CLASS') == 'mathdisplay')
5314 || (node.parentNode.tagName == 'SPAN' &&
5315 node.parentNode.getAttribute('CLASS') == 'MATH'))
5317 var parent = node.parentNode;
5318 var previous = parent.previousSibling;
5319 var/*const*/ non_whitespace = /[^\s]/;
5322 previous.nodeType == node.TEXT_NODE &&
5323 !non_whitespace.test(previous.data))
5324 previous = previous.previousSibling;
5327 previous.nodeType == node.ELEMENT_NODE &&
5328 previous.tagName == 'P' &&
5331 previous = previous.lastChild;
5333 previous.nodeType == node.TEXT_NODE &&
5334 !non_whitespace.test(previous.data))
5335 previous = previous.previousSibling;
5339 previous.nodeType == node.COMMENT_NODE) {
5340 latex_string = previous.data.replace(/^\s*MATH\s*/, '')
5341 .replace(/\s+$/, '');
5346 if(!latex_string && /^\$.+\$$/.test(alt)
5347 && !(/\.{3} \.{3}/.test(alt)))
5352 if(latex_string == null)
5356 tokens = new Object();
5357 tokens.list = tokenize_latex_math(latex_string);
5358 tokens.list.push(null);
5363 var mrow = v_subexpr_chain_to_mathml(tokens, {});
5364 fix_mathvariant(mrow, null);
5366 mathml = document.createElementNS(mmlns, 'math');
5367 mathml.setAttribute("latex", latex_string);
5368 mathml.setAttribute("mathvariant", "normal");
5369 mathml.appendChild(mrow);
5371 mathml.addEventListener("click", post_process_mathml, false);
5374 GM_log("Display LaTeX failed with error " + e + " on " + latex_string);
5381 node.parentNode.replaceChild(mathml, node);
5385 function patch_text(node0)
5387 var text = node0.nodeValue;
5388 var results = /\$[^$]+\$|\[tex\](.+?)\[\/tex\]/.exec(text);
5391 var latex_string = (results[1] == null ? results[0] : '$'+results[1]+'$');
5394 tokens = new Object();
5395 tokens.list = tokenize_latex_math(latex_string);
5396 tokens.list.push(null);
5401 var mrow = v_subexpr_chain_to_mathml(tokens, {});
5402 fix_mathvariant(mrow, null);
5404 mathml = document.createElementNS(mmlns, 'math');
5405 mathml.setAttribute("latex", latex_string);
5406 mathml.setAttribute("mathvariant", "normal");
5407 mathml.appendChild(mrow);
5409 mathml.addEventListener("click", post_process_mathml, false);
5412 GM_log("Display LaTeX failed with error " + e + " on " + latex_string);
5419 var node2 = node0.splitText(results.index);
5420 node2.deleteData(0, results[0].length);
5422 node2.parentNode.insertBefore(mathml, node2);
5431 function patch_element(node)
5433 if(node.nodeType == node.TEXT_NODE)
5435 else if(node.nodeType == node.ELEMENT_NODE) {if(node.tagName == 'TEXTAREA' || node.tagName == 'textarea' ||
5436 node.tagName == 'INPUT' || node.tagName == 'input' ||
5437 node.tagName == 'SCRIPT' || node.tagName == 'script')
5441 if(do_patch_images && (node.tagName == 'IMG' || node.tagName == 'img')) {
5445 node.addEventListener("click", patch_img, false);
5450 var child = node.firstChild;
5452 var next = child.nextSibling;
5453 if (child.className == 'stopLatex2mml') {
5456 patch_element(child);
5461 this.patch_element = patch_element;
5464 var do_patch_images = GM_getValue("patch-images", false);
5465 var delayed_patch = GM_getValue("delayed-patch", false);
5467 var do_patch_images = true;
5468 var delayed_patch = false;
5471 if( va_view == 'web' ){
5472 patch_element(document.documentElement);
5480 Deck JS - deck.simplemath
5481 Copyright (c) 2012 RĂ©mi Emonet,
5482 using a modified version of the script from http://gold-saucer.afraid.org/mathml/greasemonkey/ by Steve Cheng
5486 This module provides a support for latex equation syntax.
5489 (function($, deck, undefined) {
5490 var $d = $(document);
5491 var may = function(f) {return f ? f : function() {}};
5493 $d.bind('deck.init', function() {
5494 var container = $[deck]('getContainer');
5495 $('.latex', container).each(function() {
5497 var v = $(it).text();
5498 it.innerHTML = "$\\displaystyle "+v+"$";
5499 new latex2mml().patch_element(it);
5506 Deck JS - deck.clone
5507 Copyright (c) 2011-2014 RĂ©mi Emonet, original version from RĂ©mi BARRAQUAND
5508 Licensed under the MIT license.
5509 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
5513 This module provides a support for cloning the deck and enabling a presenter view.
5514 It also provides the behavior that copies the current "notes" to a "notes-target", to be used in the presenter view.
5517 (function($, deck, undefined) {
5518 var $d = $(document);
5519 var clones = new Array();
5521 $.extend(true, $[deck].defaults, {
5523 clonepointer: '.clonepointer',
5524 cloneNotes: '.notes',
5525 cloneNotesTarget: '.notes-target'
5528 isClone: 'is-clone',
5529 hasClones: 'has-clones',
5530 pointerClick: 'pointer-click'
5538 fitFollowsClone: true
5541 var hadClones = false;
5542 var cleanClones = function() {
5543 var opts = $[deck]('getOptions');
5544 // remove closed windows
5545 $.each(clones, function(index, clone) {
5546 if (clone.closed()) {
5547 clones.splice(index, 1); // remove element "index"
5550 // tag/untag the current container depending on the presence of clones
5551 if (clones.length > 0) {
5552 $("body").addClass(opts.classes.hasClones);
5553 if (opts.fitFollowsClone && !hadClones) $[deck]('disableScale');
5556 $("body").removeClass(opts.classes.hasClones);
5557 if (opts.fitFollowsClone && hadClones) $[deck]('enableScale');
5563 jQuery.deck('addClone')
5564 Create a clone of this window and add it to the clones list.
5566 $[deck]('extend', 'addClone', function() {
5567 clone = new DeckClone();
5572 $[deck]('extend', 'cleanClones', function() { // to be triggered by the closing of a clone window
5573 setTimeout(cleanClones, 1);
5575 $[deck]('extend', 'pointerAt', function(rx, ry) {
5576 var pos = {left: (rx*100)+"%", top: (ry*100)+"%"};
5577 var opts = $[deck]('getOptions');
5578 var current = $[deck]('getToplevelSlideOf', $[deck]('getSlide')).node; // actually uses the step extension
5579 var pointers = $(opts.selectors.clonepointer);
5580 if (!current.is(pointers.parent())) { // move them within the new slide if it changed
5581 pointers.show().appendTo(current);
5584 // using % position instead of ".offset" as there are jitter/glitches with it
5586 $[deck]('extend', 'pointerDown', function() {
5587 var opts = $[deck]('getOptions');
5588 var pointers = $(opts.selectors.clonepointer);
5589 pointers.addClass(opts.classes.pointerClick);
5591 $[deck]('extend', 'pointerUp', function() {
5592 var opts = $[deck]('getOptions');
5593 var pointers = $(opts.selectors.clonepointer);
5594 pointers.removeClass(opts.classes.pointerClick);
5597 var isClone = false;
5598 var parentDeck = null;
5602 $d.bind('deck.init', function() {
5603 var opts = $[deck]('getOptions');
5604 var container = $[deck]('getContainer');
5606 if (opts.snippets.clone) {
5607 var d = function() {return $('<div/>');}
5608 d().addClass("clonepointer scale-on-click").append(
5609 d().attr("style", "border: 2px solid red; border-radius: 50%; z-index:10;"
5610 +"margin: -11px 0 0 -11px; width:20px; height:20px; opacity: .5;")
5611 ).appendTo(container);
5612 d().addClass("clonepointer scale-on-click").append(
5613 d().attr("style", "border: 2px solid red; border-radius: 50%; z-index:10;"
5614 +"margin: -16px 0 0 -16px; width:30px; height:30px;")
5615 ).appendTo(container);
5616 d().addClass(opts.selectors.cloneNotesTarget.replace(/\./, ''))
5617 .appendTo(container);
5620 $(opts.selectors.clonepointer).hide();
5622 function safeIsClone(w) {
5624 return w.opener && w.opener.___iscloner___;
5626 // when linked from another origin, there is an opener
5627 // but accessing its properties throws a security exception
5632 isClone = safeIsClone(window);
5634 if (isClone) { // it's a clone!
5635 $("body").addClass(opts.classes.isClone);
5636 $(".anim-continue", container).removeClass("anim-continue"); // friend with anim extension
5637 window.___fromparent___ = false;
5638 parentDeck = function() {
5639 if (! window.___fromparent___) {
5640 window.opener.$.deck.apply(window.opener.$, arguments);
5643 $(window).on('unload', function() {
5644 parentDeck('cleanClones');
5646 } else { // it is a normal window
5647 /* bind clone key events */
5648 $d.unbind('keydown.deckclone').bind('keydown.deckclone', function(e) {
5649 if (e.which === opts.keys.clone || $.inArray(e.which, opts.keys.clone) > -1) {
5650 if (e.ctrlKey) return; // do not trigger on Ctrl+C (by default)
5651 $[deck]('addClone');
5652 window.___iscloner___ = true;
5658 /* Update current slide number with each change event */
5659 .bind('deck.change', function(e, from, to) {
5661 parentDeck('go', to);
5664 $.each(clones, function(index, clone) {
5665 clone.deck('go', to);
5668 var opts = $[deck]('getOptions');
5669 var currentTopLevel = $[deck]('getToplevelSlideOf', $[deck]('getSlide', to)).node;
5670 var notes = $(opts.selectors.cloneNotes, currentTopLevel).html();
5671 if (notes === undefined) {
5672 $(opts.selectors.cloneNotesTarget).html("");
5674 $(opts.selectors.cloneNotesTarget).html(notes);
5678 /* Replicate mouse cursor */
5679 .bind('mousemove', function(e) {
5680 if (isClone) return;
5681 var current = $[deck]('getToplevelSlideOf', $[deck]('getSlide')).node; // actually uses the step extension (dependency can be removed if needed)
5682 var r = current.get(0).getBoundingClientRect();
5683 var x = (e.clientX - r.left) / r.width;
5684 var y = (e.clientY - r.top) / r.height;
5686 if (x < 0 || y < 0 || x > 1 || y > 1) return;
5687 $.each(clones, function(index, clone) {
5688 clone.deck('pointerAt', x, y);
5691 .bind('mousedown', function(e) {
5692 if (isClone) return;
5694 $.each(clones, function(index, clone) {
5695 clone.deck('pointerDown');
5698 .bind('mouseup', function(e) {
5699 if (isClone) return;
5701 $.each(clones, function(index, clone) {
5702 clone.deck('pointerUp');
5707 Simple Clone manager (must be improved, by for instance adding cloning
5708 option e.g. propagate change, etc.)
5710 var DeckClone = function() {
5711 var clone = window.open(window.location);
5712 this.closed = function() {return clone.closed;}
5713 this.deck = function() {
5714 if (clone.closed) return;
5716 clone.___fromparent___ = true;
5717 clone.$.deck.apply(clone.$, arguments);
5718 clone.___fromparent___ = false;
5727 Copyright (c) 2011-2014 Caleb Troughton
5728 Dual licensed under the MIT license.
5729 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
5733 This module adds the necessary methods and key bindings to show and hide a form
5734 for jumping to any slide number/id in the deck (and processes that form
5735 accordingly). The form-showing state is indicated by the presence of a class on
5738 (function($, undefined) {
5739 var $document = $(document);
5742 var maybeAddSnippet = function() {
5743 var options = $.deck('getOptions');
5744 if (options.snippets.goto) {
5745 if ($(options.selectors.gotoForm).size() > 0 && options.alert.goto) {
5746 alert("'options.snippets.goto' is true but a "+options.selectors.gotoForm+" has been found."
5747 +"\nThis might cause interaction glitches."
5749 +"\nSuggestion: remove your html snippet or pass the {snippets: {goto: false}} option."
5752 $('<form/>').addClass('goto-form').attr('action', '.').attr('method', 'get')
5753 .append($('<label/>').attr('for', 'goto-slide').text('Go to slide:'))
5754 .append($('<input/>').attr('type', 'text').attr('id', 'goto-slide').attr('name', 'slidenum').attr('list', 'goto-datalist'))
5755 .append($('<datalist/>').attr('id', 'goto-datalist'))
5756 .append($('<input/>').attr('type', 'submit').attr('value', 'Go'))
5757 .appendTo($.deck('getContainer'));
5761 var bindKeyEvents = function() {
5762 $document.unbind('keydown.deckgoto');
5763 $document.bind('keydown.deckgoto', function(event) {
5764 var key = $.deck('getOptions').keys.goto;
5765 if (event.which === key || $.inArray(event.which, key) > -1) {
5766 event.preventDefault();
5767 $.deck('toggleGoTo');
5772 var populateDatalist = function() {
5773 var options = $.deck('getOptions');
5774 var $datalist = $(options.selectors.gotoDatalist);
5776 $.each($.deck('getSlides'), function(i, $slide) {
5777 var id = $slide.attr('id');
5779 $datalist.append('<option value="' + id + '">');
5784 var markRootSlides = function() {
5785 var options = $.deck('getOptions');
5786 var slideTest = $.map([
5787 options.classes.before,
5788 options.classes.previous,
5789 options.classes.current,
5790 options.classes.next,
5791 options.classes.after
5792 ], function(el, i) {
5797 $.each($.deck('getSlides'), function(i, $slide) {
5798 var $parentSlides = $slide.parentsUntil(
5799 options.selectors.container,
5803 if ($parentSlides.length) {
5804 $slide.removeData('rootIndex');
5806 else if (!options.countNested) {
5808 $slide.data('rootIndex', rootCounter);
5813 var handleFormSubmit = function() {
5814 var options = $.deck('getOptions');
5815 var $form = $(options.selectors.gotoForm);
5817 $form.unbind('submit.deckgoto');
5818 $form.bind('submit.deckgoto', function(event) {
5819 var $field = $(options.selectors.gotoInput);
5820 var indexOrId = $field.val();
5821 var index = parseInt(indexOrId, 10);
5823 if (!options.countNested) {
5824 if (!isNaN(index) && (index > rootCounter || index <= 0)) {
5827 $.each($.deck('getSlides'), function(i, $slide) {
5828 if ($slide.data('rootIndex') === index) {
5835 $.deck('go', isNaN(index) ? indexOrId : index - 1);
5838 event.preventDefault();
5843 Extends defaults/options.
5845 options.classes.goto
5846 This class is added to the deck container when showing the Go To Slide
5849 options.selectors.gotoDatalist
5850 The element that matches this selector is the datalist element that will
5851 be populated with options for each of the slide ids. In browsers that
5852 support the datalist element, this provides a drop list of slide ids to
5853 aid the user in selecting a slide.
5855 options.selectors.gotoForm
5856 The element that matches this selector is the form that is submitted
5857 when a user hits enter after typing a slide number/id in the gotoInput
5860 options.selectors.gotoInput
5861 The element that matches this selector is the text input field for
5862 entering a slide number/id in the Go To Slide form.
5865 The numeric keycode used to show the Go To Slide form.
5868 If false, only top level slides will be counted when entering a
5871 $.extend(true, $.deck.defaults, {
5877 gotoDatalist: '#goto-datalist',
5878 gotoForm: '.goto-form',
5879 gotoInput: '#goto-slide'
5898 jQuery.deck('showGoTo')
5900 Shows the Go To Slide form by adding the class specified by the goto class
5901 option to the deck container.
5903 $.deck('extend', 'showGoTo', function() {
5904 var options = $.deck('getOptions');
5905 $.deck('getContainer').addClass(options.classes.goto);
5906 $(options.selectors.gotoForm).attr('aria-hidden', false);
5907 $(options.selectors.gotoInput).focus();
5911 jQuery.deck('hideGoTo')
5913 Hides the Go To Slide form by removing the class specified by the goto class
5914 option from the deck container.
5916 $.deck('extend', 'hideGoTo', function() {
5917 var options = $.deck('getOptions');
5918 $(options.selectors.gotoInput).blur();
5919 $.deck('getContainer').removeClass(options.classes.goto);
5920 $(options.selectors.gotoForm).attr('aria-hidden', true);
5924 jQuery.deck('toggleGoTo')
5926 Toggles between showing and hiding the Go To Slide form.
5928 $.deck('extend', 'toggleGoTo', function() {
5929 var options = $.deck('getOptions');
5930 var hasGotoClass = $.deck('getContainer').hasClass(options.classes.goto);
5931 $.deck(hasGotoClass ? 'hideGoTo' : 'showGoTo');
5934 $document.bind('deck.init', function() {
5945 Deck JS - deck.progress
5946 Copyright (c) 2014 RĂ©mi Emonet
5947 Dual licensed under the MIT license.
5948 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
5952 This module adds a (current)/(total) style status indicator to the deck.
5954 It is designed to be a drop-in replacement of deck.status, but on steroĂ¯ds.
5955 Note however, that it does not handle the countNested=true case.
5957 (function($, undefined) {
5958 var $document = $(document);
5960 var INITEVENT = "dummyinit";
5961 var SIZEEVENT = "dummysize";
5963 var updateCurrent = function(event, from, to) {
5964 var opts = $.deck('getOptions');
5965 var currentSlideNumber = to + 1;
5966 var $container = $.deck('getContainer');
5967 currentSlideNumber = $.deck('getSlide', to).data('rootSlide');
5968 $(opts.selectors.statusCurrent).text(currentSlideNumber);
5971 for (; icur < $.deck('getSlides').length; icur++) {
5972 var top = $.deck('getSlide', icur).data('rootSlide');
5973 if (top == currentSlideNumber) {
5978 var currentDetail = to;
5979 var lastDetail = icur;
5980 for (; icur < $.deck('getSlides').length; icur++) {
5981 last = $.deck('getSlide', icur).data('rootSlide');
5982 lastDetail = icur+1;
5983 if ($.deck('getSlide', icur).filter(opts.selectors.statusFakeEnd).size() > 0) break;
5985 $(opts.selectors.statusTotal).text(last);
5987 // handle the data-progress
5988 var progresses = $('*['+opts.dataProgress+'], *['+opts.dataProgressOnce+'], *['+opts.dataProgressSize+']');
5989 if (progresses.size() > 0) {
5990 var visibleSlide = $.deck('getSlide').parentsUntil(opts.selectors.container).addBack().filter(opts.selectors.slides);
5992 var slide = visibleSlide.get(0).getBoundingClientRect();
5993 var screen = {width: $container.innerWidth(), height: $container.innerHeight()};
5994 var n = currentSlideNumber;
5996 var fullTotal = $.deck('getTopLevelSlides').length;
5997 var detail = {n: currentDetail+1, N: lastDetail, fullTotal: $.deck('getSlides').length};
5998 var designRatio = Math.max(slide.width / opts.designWidth, slide.height / opts.designHeight);
6001 var pFull = n/fullTotal;
6002 detail.p = detail.n/detail.N;
6003 detail.pFull = detail.n/detail.fullTotal;
6005 progresses.each(function(i, el) {
6007 bottom: function(fontSize, botByRatio, botFixed) {
6008 botFixed = botFixed || 0;
6009 $(el).css('font-size', (fontSize * designRatio)+"px");
6010 $(el).css('top', (slide.bottom - botFixed - botByRatio*designRatio)+'px');
6012 top: function(fontSize, topByRatio, topFixed) {
6013 topFixed = topFixed || 0;
6014 $(el).css('font-size', (fontSize * designRatio)+"px");
6015 $(el).css('top', (slide.top + topFixed + topByRatio*designRatio)+'px');
6018 var att = $(el).attr(event == INITEVENT ? opts.dataProgressOnce : event == SIZEEVENT ? opts.dataProgressSize : opts.dataProgress);
6019 if (att == null || att.length == 0) return;
6020 var tasks = att.split(/ *; */);
6022 var parts = tasks[t].split(/ *: */);
6023 if (parts.length != 2) {
6024 if (opts.alert.wrongDataProgress) alert(
6025 "There seem to be a problem with the following data-progress of\n '" +tasks[t]+ "'\n");
6027 var what = parts[0];
6028 var expr = parts[1];
6029 var val = eval(expr);
6031 // skip: expected to be some "magic", e.g. custom code or call to helpers
6032 } else if (what.substring(0,1) == "@") {
6033 // special attribute setting, not css
6034 what = what.substring(1);
6035 $(el).attr(what, val);
6036 } else if (what == "$text") {
6038 } else if (what == "$html") {
6041 $(el).css(what, val);
6049 var markRootSlides = function() {
6050 var opts = $.deck('getOptions');
6051 var slideTest = $.map([
6052 opts.classes.before,
6053 opts.classes.previous,
6054 opts.classes.current,
6057 ], function(el, i) {
6062 $.each($.deck('getSlides'), function(i, $slide) {
6063 var $parentSlides = $slide.parentsUntil(
6064 opts.selectors.container,
6068 if ($parentSlides.length) {
6069 $slide.data('rootSlide', $parentSlides.last().data('rootSlide'));
6073 $slide.data('rootSlide', rootCounter);
6078 var fireEventOnCurrentSlide = function(ev) {
6079 var slides = $.deck('getSlides');
6080 var $currentSlide = $.deck('getSlide');
6083 $.each(slides, function(i, $slide) {
6084 if ($slide === $currentSlide) {
6089 updateCurrent(ev, index, index);
6092 var setTotalSlideNumber = function() {
6093 var opts = $.deck('getOptions');
6094 var slides = $.deck('getSlides');
6096 var nSlides = $.deck('getTopLevelSlides').length;
6097 $(opts.selectors.statusFullTotal).text(nSlides);
6102 Extends defaults/options.
6104 opts.selectors.statusCurrent
6105 The element matching this selector displays the current slide number.
6107 opts.selectors.statusTotal
6108 The element matching this selector displays the total number of slides.
6111 If false, only top level slides will be counted in the current and
6114 $.extend(true, $.deck.defaults, {
6116 statusCurrent: '.deck-status-current',
6117 statusTotal: '.deck-status-total',
6118 statusFakeEnd: '.deck-status-fake-end',
6119 statusFullTotal: '.deck-status-full-total',
6120 progress10: '.deck-progress-10'
6123 wrongDataProgress: true,
6124 possibleDebounceProblem: true
6126 dataProgress: "data-progress",
6127 dataProgressOnce: "data-progress-once",
6128 dataProgressSize: "data-progress-size",
6129 progressSizeDebounce: 201 /* somewhat, it should be bigger that the fit debounce */
6132 $document.bind('deck.init', function() {
6133 var opts = $.deck('getOptions');
6134 $(opts.selectors.progress10).attr(opts.dataProgressSize, ':spe.bottom(10, 12)')
6136 fireEventOnCurrentSlide(INITEVENT);
6137 fireEventOnCurrentSlide(SIZEEVENT);
6138 setTotalSlideNumber();
6141 $(window).unbind('resize.deckprogress').bind('resize.deckprogress', function() {
6142 var opts = $.deck('getOptions');
6143 if (opts.alert.possibleDebounceProblem && opts.progressSizeDebounce < opts.scaleDebounce + 1) {
6145 "There might be a problem with the respective debounce value:\n progressSizeDebounce: "+opts.progressSizeDebounce+"\n scaleDebounce: "+opts.scaleDebounce);
6148 window.clearTimeout(timer);
6149 timer = window.setTimeout( function() {
6150 fireEventOnCurrentSlide(SIZEEVENT);
6151 fireEventOnCurrentSlide("fire also the update event as some things might also need resizing");
6152 }, opts.progressSizeDebounce);
6154 $document.bind('deck.change', updateCurrent);
6159 Deck JS - deck.navigation
6160 Copyright (c) 2011-2014 Caleb Troughton
6161 Dual licensed under the MIT license.
6162 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6166 This module adds clickable previous and next links to the deck.
6168 (function($, undefined) {
6169 var $document = $(document);
6171 /* Updates link hrefs, and disabled states if last/first slide */
6172 var updateButtons = function(event, from, to) {
6173 var options = $.deck('getOptions');
6174 var lastIndex = $.deck('getSlides').length - 1;
6175 var $prevSlide = $.deck('getSlide', to - 1);
6176 var $nextSlide = $.deck('getSlide', to + 1);
6177 var hrefBase = window.location.href.replace(/#.*/, '');
6178 var prevId = $prevSlide ? $prevSlide.attr('id') : undefined;
6179 var nextId = $nextSlide ? $nextSlide.attr('id') : undefined;
6180 var $prevButton = $(options.selectors.previousLink);
6181 var $nextButton = $(options.selectors.nextLink);
6183 $prevButton.toggleClass(options.classes.navDisabled, to === 0);
6184 $prevButton.attr('aria-disabled', to === 0);
6185 $prevButton.attr('href', hrefBase + '#' + (prevId ? prevId : ''));
6186 $nextButton.toggleClass(options.classes.navDisabled, to === lastIndex);
6187 $nextButton.attr('aria-disabled', to === lastIndex);
6188 $nextButton.attr('href', hrefBase + '#' + (nextId ? nextId : ''));
6192 Extends defaults/options.
6194 options.classes.navDisabled
6195 This class is added to a navigation link when that action is disabled.
6196 It is added to the previous link when on the first slide, and to the
6197 next link when on the last slide.
6199 options.selectors.nextLink
6200 The elements that match this selector will move the deck to the next
6203 options.selectors.previousLink
6204 The elements that match this selector will move to deck to the previous
6207 $.extend(true, $.deck.defaults, {
6209 navDisabled: 'deck-nav-disabled'
6213 nextLink: '.deck-next-link',
6214 previousLink: '.deck-prev-link'
6218 $document.bind('deck.init', function() {
6219 var options = $.deck('getOptions');
6220 var slides = $.deck('getSlides');
6221 var $current = $.deck('getSlide');
6222 var $prevButton = $(options.selectors.previousLink);
6223 var $nextButton = $(options.selectors.nextLink);
6226 // Setup prev/next link events
6227 $prevButton.unbind('click.decknavigation');
6228 $prevButton.bind('click.decknavigation', function(event) {
6230 event.preventDefault();
6233 $nextButton.unbind('click.decknavigation');
6234 $nextButton.bind('click.decknavigation', function(event) {
6236 event.preventDefault();
6239 // Find where we started in the deck and set initial states
6240 $.each(slides, function(i, $slide) {
6241 if ($slide === $current) {
6246 updateButtons(null, index, index);
6249 $document.bind('deck.change', updateButtons);
6255 Copyright (c) 2011-2014 Caleb Troughton
6256 Dual licensed under the MIT license.
6257 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6261 This module adds the methods and key binding to show and hide a menu of all
6262 slides in the deck. The deck menu state is indicated by the presence of a class
6263 on the deck container.
6265 (function($, undefined) {
6266 var $document = $(document);
6267 var $html = $('html');
6270 var populateRootSlidesArray = function() {
6271 var options = $.deck('getOptions');
6272 var slideTest = $.map([
6273 options.classes.before,
6274 options.classes.previous,
6275 options.classes.current,
6276 options.classes.next,
6277 options.classes.after
6278 ], function(el, i) {
6283 $.each($.deck('getSlides'), function(i, $slide) {
6284 var $parentSlides = $slide.parentsUntil(
6285 options.selectors.container,
6288 if (!$parentSlides.length) {
6289 rootSlides.push($slide);
6294 var bindKeyEvents = function() {
6295 var options = $.deck('getOptions');
6296 $document.unbind('keydown.deckmenu');
6297 $document.bind('keydown.deckmenu', function(event) {
6298 var isMenuKey = event.which === options.keys.menu;
6299 isMenuKey = isMenuKey || $.inArray(event.which, options.keys.menu) > -1;
6300 if (isMenuKey && !event.ctrlKey) {
6301 $.deck('toggleMenu');
6302 event.preventDefault();
6307 var bindTouchEvents = function() {
6308 var $container = $.deck('getContainer');
6309 var options = $.deck('getOptions');
6310 var touchEndTime = 0;
6313 $container.unbind('touchstart.deckmenu');
6314 $container.bind('touchstart.deckmenu', function() {
6315 currentSlide = $.deck('getSlide');
6317 $container.unbind('touchend.deckmenu');
6318 $container.bind('touchend.deckmenu', function(event) {
6319 var now = Date.now();
6320 var isDoubletap = now - touchEndTime < options.touch.doubletapWindow;
6322 // Ignore this touch event if it caused a nav change (swipe)
6323 if (currentSlide !== $.deck('getSlide')) {
6327 $.deck('toggleMenu');
6328 event.preventDefault();
6334 var setupMenuSlideSelection = function() {
6335 var options = $.deck('getOptions');
6337 $.each($.deck('getSlides'), function(i, $slide) {
6338 $slide.unbind('click.deckmenu');
6339 $slide.bind('click.deckmenu', function(event) {
6340 if (!$.deck('getContainer').hasClass(options.classes.menu)) {
6345 event.stopPropagation();
6346 event.preventDefault();
6352 Extends defaults/options.
6354 options.classes.menu
6355 This class is added to the deck container when showing the slide menu.
6358 The numeric keycode used to toggle between showing and hiding the slide
6361 options.touch.doubletapWindow
6362 Two consecutive touch events within this number of milliseconds will
6363 be considered a double tap, and will toggle the menu on touch devices.
6365 $.extend(true, $.deck.defaults, {
6375 doubletapWindow: 400
6380 jQuery.deck('showMenu')
6382 Shows the slide menu by adding the class specified by the menu class option
6383 to the deck container.
6385 $.deck('extend', 'showMenu', function() {
6386 var $container = $.deck('getContainer');
6387 var options = $.deck('getOptions');
6389 if ($container.hasClass(options.classes.menu)) {
6393 // Hide through loading class to short-circuit transitions (perf)
6394 $container.addClass([
6395 options.classes.loading,
6396 options.classes.menu
6399 /* Forced to do this in JS until CSS learns second-grade math. Save old
6400 style value for restoration when menu is hidden. */
6401 if (Modernizr.csstransforms) {
6402 $.each(rootSlides, function(i, $slide) {
6403 $slide.data('oldStyle', $slide.attr('style'));
6405 'position': 'absolute',
6406 'left': ((i % 4) * 25) + '%',
6407 'top': (Math.floor(i / 4) * 25) + '%'
6412 // Need to ensure the loading class renders first, then remove
6413 window.setTimeout(function() {
6414 $container.removeClass(options.classes.loading);
6415 $container.scrollTop($.deck('getSlide').position().top);
6420 jQuery.deck('hideMenu')
6422 Hides the slide menu by removing the class specified by the menu class
6423 option from the deck container.
6425 $.deck('extend', 'hideMenu', function() {
6426 var $container = $.deck('getContainer');
6427 var options = $.deck('getOptions');
6429 if (!$container.hasClass(options.classes.menu)) {
6433 $container.removeClass(options.classes.menu);
6434 $container.addClass(options.classes.loading);
6436 /* Restore old style value */
6437 if (Modernizr.csstransforms) {
6438 $.each(rootSlides, function(i, $slide) {
6439 var oldStyle = $slide.data('oldStyle');
6440 $slide.attr('style', oldStyle ? oldStyle : '');
6444 window.setTimeout(function() {
6445 $container.removeClass(options.classes.loading);
6446 $container.scrollTop(0);
6451 jQuery.deck('toggleMenu')
6453 Toggles between showing and hiding the slide menu.
6455 $.deck('extend', 'toggleMenu', function() {
6456 $.deck('getContainer').hasClass($.deck('getOptions').classes.menu) ?
6457 $.deck('hideMenu') : $.deck('showMenu');
6460 $document.bind('deck.init', function() {
6461 populateRootSlidesArray();
6464 setupMenuSlideSelection();
6467 $document.bind('deck.change', function(event, from, to) {
6468 var $container = $.deck('getContainer');
6469 var containerScroll, slideTop;
6471 if ($container.hasClass($.deck('getOptions').classes.menu)) {
6472 containerScroll = $container.scrollTop();
6473 slideTop = $.deck('getSlide', to).position().top;
6474 $container.scrollTop(containerScroll + slideTop);
6481 Copyright (c) 2011-2014 RĂ©mi Emonet
6482 Licensed under the MIT license.
6483 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6487 This module provides new methods for stepping without considering sub-slides, together with tools for finding toplevel slides etc.
6488 It also overrides the defaults keybinding and countNested value (so it is better to include it after "goto" and "status" extensions).
6491 (function($, deck, undefined) {
6492 var $d = $(document);
6493 // undo the defaults (to be sure jquery behaves properly when overriding it)
6494 $.extend(true, $[deck].defaults, { keys: {next:null, previous:null}});
6496 $.extend(true, $[deck].defaults, {
6498 subslidesToNotify: ".slide,.onshowtoplevel"
6500 // Here we redefined the defaults:
6501 // - we avoid counting nested slides
6502 // - we keep up/down for top-level slides
6503 // - we still use pgup/pgdown for inner slides as they are sent by some pluggable remote controls
6505 // backspace, left arrow, page down
6506 previous: [8, 37, 33],
6507 // enter, space, right arrow, page up
6508 next: [13, 32, 39, 34],
6510 previousTopLevel: [38],
6514 nextEndOfTopLevel: [90],
6516 previousEndOfTopLevel: [65]
6520 var myInArray = function(el, arr) {
6521 for (i in arr) if (arr[i].is(el)) return i*1; // cast to int
6524 $[deck]('extend', 'getSlideIndex', function(node) {
6525 var slides = $[deck]('getSlides');
6526 var ind = myInArray(node, slides);
6529 $[deck]('extend', 'getToplevelSlideOf', function(node) {
6530 var opts = $[deck]('getOptions');
6531 var slides = $[deck]('getSlides');
6532 var last = {node: $(node), index: myInArray(node, slides)};
6533 $(node).parentsUntil(opts.selectors.container).each( function(ii, v) {
6534 var ind = myInArray(v, slides);
6536 last = {node: $(v), index: ind};
6541 $[deck]('extend', 'getToplevelSlideOfIndex', function(ind) {
6542 return $[deck]('getToplevelSlideOf', $[deck]('getSlide', ind));
6544 $[deck]('extend', 'previousTopLevelSlide', function() {
6545 /* Find the real previous parent */
6546 var current = $[deck]('getSlide');
6547 var currentParent = $[deck]('getToplevelSlideOf', current);
6548 var toGo = currentParent.index;
6549 if (current.is(currentParent.node) && toGo > 0) {
6550 // This is already toplevel slide, just go to the previous toplevel one (parent of the previous one)
6551 toGo = $[deck]('getToplevelSlideOfIndex', toGo-1).index;
6553 $[deck]('go', toGo);
6556 $[deck]('extend', 'nextTopLevelSlide', function() {
6557 /* Find the real next parent */
6558 var current = $[deck]('getSlide');
6559 var currentParent = $[deck]('getToplevelSlideOf', current);
6560 var icur = currentParent.index;
6561 for (; icur < $[deck]('getSlides').length; icur++) {
6562 var cursorParent = $[deck]('getToplevelSlideOfIndex', icur).node;
6563 if (!cursorParent.is(currentParent.node)) {
6564 $[deck]('go', icur);
6569 $[deck]('extend', 'nextEndOfTopLevelSlide', function() {
6570 /* Find the real next parent */
6571 var current = $[deck]('getSlideIndex', $[deck]('getSlide'));
6572 var nextParent = $[deck]('getToplevelSlideOfIndex', current + 1);
6573 var icur = nextParent.index;
6574 for (; icur < $[deck]('getSlides').length; icur++) {
6575 var cursorParent = $[deck]('getToplevelSlideOfIndex', icur).node;
6576 if (!cursorParent.is(nextParent.node)) {
6577 $[deck]('go', icur-1);
6581 if (icur == $[deck]('getSlides').length) {
6582 $[deck]('go', icur-1);
6585 $[deck]('extend', 'previousEndOfTopLevelSlide', function() {
6586 /* Find the current parent and take the previous slide (last of previous top level) */
6587 var current = $[deck]('getSlideIndex', $[deck]('getSlide'));
6588 var currentParent = $[deck]('getToplevelSlideOfIndex', current).index;
6589 if (currentParent > 0) {
6590 $[deck]('go', currentParent - 1);
6593 $d.bind('deck.init', function() {
6594 $d.unbind('keydown.decknexttoplevel').bind('keydown.decknexttoplevel', function(e) {
6595 var $opts = $[deck]('getOptions');
6596 var key = $opts.keys.nextTopLevel;
6597 if (e.which === key || $.inArray(e.which, key) > -1) {
6599 $[deck]('nextTopLevelSlide');
6602 $d.unbind('keydown.decknextendoftoplevel').bind('keydown.decknextendoftoplevel', function(e) {
6603 var $opts = $[deck]('getOptions');
6604 var key = $opts.keys.nextEndOfTopLevel;
6605 if (e.which === key || $.inArray(e.which, key) > -1) {
6607 $[deck]('nextEndOfTopLevelSlide');
6610 $d.unbind('keydown.deckprevioustoplevel').bind('keydown.deckprevioustoplevel', function(e) {
6611 var $opts = $[deck]('getOptions');
6612 var key = $opts.keys.previousTopLevel;
6613 if (e.which === key || $.inArray(e.which, key) > -1) {
6615 $[deck]('previousTopLevelSlide');
6618 $d.unbind('keydown.deckpreviousendoftoplevel').bind('keydown.deckpreviousendoftoplevel', function(e) {
6619 var $opts = $[deck]('getOptions');
6620 var key = $opts.keys.previousEndOfTopLevel;
6621 if (e.which === key || $.inArray(e.which, key) > -1) {
6623 $[deck]('previousEndOfTopLevelSlide');
6627 // When jumping (not steping), we will init the subslides (in case they are animations), in a backward order, and then fast forward necessary animations
6628 var bigJump = function(from, to) {
6629 var direction = "forward";
6631 direction = "reverse";
6633 var opts = $[deck]('getOptions');
6634 $($[deck]('getToplevelSlideOfIndex', to).node.find(opts.selectors.subslidesToNotify).get().reverse()).each(function(ind, el) {$(el).triggerHandler('deck.toplevelBecameCurrent', direction)});
6635 for (icur = $[deck]('getToplevelSlideOfIndex', to).index + 1; icur < to+1; icur++) {
6636 $[deck]('getSlides')[icur].triggerHandler('deck.afterToplevelBecameCurrent', 'forward');
6639 $d.bind('deck.change', function(e, from, to) {
6640 if ( Math.abs(from - to) > 1 || ! $[deck]('getToplevelSlideOfIndex', to).node.is($[deck]('getToplevelSlideOfIndex', from).node)) {
6641 // consider natural jumps and the case where we actually changed (top level) slide (even with a step)
6647 (function($, deck, undefined) {
6648 $(document).bind('deck.change', function(e, from, to) {
6649 var $prev = $[deck]('getSlide', to-1),
6650 $next = $[deck]('getSlide', to+1),
6651 $oldprev = $[deck]('getSlide', from-1),
6652 $oldnext = $[deck]('getSlide', from+1);
6654 var direction = "forward";
6656 direction = "reverse";
6659 $[deck]('getSlide', from).triggerHandler('deck.lostCurrent', [direction, from, to]);
6660 $[deck]('getSlide', to).triggerHandler('deck.becameCurrent', [direction, from, to]);
6662 $oldprev && $oldprev.triggerHandler('deck.lostPrevious', [direction, from, to]);
6663 $oldnext && $oldnext.triggerHandler('deck.lostNext', [direction, from, to]);
6665 $prev && $prev.triggerHandler('deck.becamePrevious', [direction, from, to]);
6666 $next && $next.triggerHandler('deck.becameNext', [direction, from, to]);
6673 Copyright (c) 2012-2014 RĂ©mi Emonet
6674 Licensed under the MIT license.
6675 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6679 (function($, deck, undefined) {
6680 // The next two lines are the color plugin from jquery
6681 /*! jQuery Color v@2.1.2 http://github.com/jquery/jquery-color | jquery.org/license */
6682 (function(a,b){function m(a,b,c){var d=h[b.type]||{};return a==null?c||!b.def?null:b.def:(a=d.floor?~~a:parseFloat(a),isNaN(a)?b.def:d.mod?(a+d.mod)%d.mod:0>a?0:d.max<a?d.max:a)}function n(b){var c=f(),d=c._rgba=[];return b=b.toLowerCase(),l(e,function(a,e){var f,h=e.re.exec(b),i=h&&e.parse(h),j=e.space||"rgba";if(i)return f=c[j](i),c[g[j].cache]=f[g[j].cache],d=c._rgba=f._rgba,!1}),d.length?(d.join()==="0,0,0,0"&&a.extend(d,k.transparent),c):k[b]}function o(a,b,c){return c=(c+1)%1,c*6<1?a+(b-a)*c*6:c*2<1?b:c*3<2?a+(b-a)*(2/3-c)*6:a}var c="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",d=/^([\-+])=\s*(\d+\.?\d*)/,e=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(a){return[a[1],a[2],a[3],a[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(a){return[a[1]*2.55,a[2]*2.55,a[3]*2.55,a[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(a){return[parseInt(a[1],16),parseInt(a[2],16),parseInt(a[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(a){return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(a){return[a[1],a[2]/100,a[3]/100,a[4]]}}],f=a.Color=function(b,c,d,e){return new a.Color.fn.parse(b,c,d,e)},g={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},h={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},i=f.support={},j=a("<p>")[0],k,l=a.each;j.style.cssText="background-color:rgba(1,1,1,.5)",i.rgba=j.style.backgroundColor.indexOf("rgba")>-1,l(g,function(a,b){b.cache="_"+a,b.props.alpha={idx:3,type:"percent",def:1}}),f.fn=a.extend(f.prototype,{parse:function(c,d,e,h){if(c===b)return this._rgba=[null,null,null,null],this;if(c.jquery||c.nodeType)c=a(c).css(d),d=b;var i=this,j=a.type(c),o=this._rgba=[];d!==b&&(c=[c,d,e,h],j="array");if(j==="string")return this.parse(n(c)||k._default);if(j==="array")return l(g.rgba.props,function(a,b){o[b.idx]=m(c[b.idx],b)}),this;if(j==="object")return c instanceof f?l(g,function(a,b){c[b.cache]&&(i[b.cache]=c[b.cache].slice())}):l(g,function(b,d){var e=d.cache;l(d.props,function(a,b){if(!i[e]&&d.to){if(a==="alpha"||c[a]==null)return;i[e]=d.to(i._rgba)}i[e][b.idx]=m(c[a],b,!0)}),i[e]&&a.inArray(null,i[e].slice(0,3))<0&&(i[e][3]=1,d.from&&(i._rgba=d.from(i[e])))}),this},is:function(a){var b=f(a),c=!0,d=this;return l(g,function(a,e){var f,g=b[e.cache];return g&&(f=d[e.cache]||e.to&&e.to(d._rgba)||[],l(e.props,function(a,b){if(g[b.idx]!=null)return c=g[b.idx]===f[b.idx],c})),c}),c},_space:function(){var a=[],b=this;return l(g,function(c,d){b[d.cache]&&a.push(c)}),a.pop()},transition:function(a,b){var c=f(a),d=c._space(),e=g[d],i=this.alpha()===0?f("transparent"):this,j=i[e.cache]||e.to(i._rgba),k=j.slice();return c=c[e.cache],l(e.props,function(a,d){var e=d.idx,f=j[e],g=c[e],i=h[d.type]||{};if(g===null)return;f===null?k[e]=g:(i.mod&&(g-f>i.mod/2?f+=i.mod:f-g>i.mod/2&&(f-=i.mod)),k[e]=m((g-f)*b+f,d))}),this[d](k)},blend:function(b){if(this._rgba[3]===1)return this;var c=this._rgba.slice(),d=c.pop(),e=f(b)._rgba;return f(a.map(c,function(a,b){return(1-d)*e[b]+d*a}))},toRgbaString:function(){var b="rgba(",c=a.map(this._rgba,function(a,b){return a==null?b>2?1:0:a});return c[3]===1&&(c.pop(),b="rgb("),b+c.join()+")"},toHslaString:function(){var b="hsla(",c=a.map(this.hsla(),function(a,b){return a==null&&(a=b>2?1:0),b&&b<3&&(a=Math.round(a*100)+"%"),a});return c[3]===1&&(c.pop(),b="hsl("),b+c.join()+")"},toHexString:function(b){var c=this._rgba.slice(),d=c.pop();return b&&c.push(~~(d*255)),"#"+a.map(c,function(a){return a=(a||0).toString(16),a.length===1?"0"+a:a}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),f.fn.parse.prototype=f.fn,g.hsla.to=function(a){if(a[0]==null||a[1]==null||a[2]==null)return[null,null,null,a[3]];var b=a[0]/255,c=a[1]/255,d=a[2]/255,e=a[3],f=Math.max(b,c,d),g=Math.min(b,c,d),h=f-g,i=f+g,j=i*.5,k,l;return g===f?k=0:b===f?k=60*(c-d)/h+360:c===f?k=60*(d-b)/h+120:k=60*(b-c)/h+240,h===0?l=0:j<=.5?l=h/i:l=h/(2-i),[Math.round(k)%360,l,j,e==null?1:e]},g.hsla.from=function(a){if(a[0]==null||a[1]==null||a[2]==null)return[null,null,null,a[3]];var b=a[0]/360,c=a[1],d=a[2],e=a[3],f=d<=.5?d*(1+c):d+c-d*c,g=2*d-f;return[Math.round(o(g,f,b+1/3)*255),Math.round(o(g,f,b)*255),Math.round(o(g,f,b-1/3)*255),e]},l(g,function(c,e){var g=e.props,h=e.cache,i=e.to,j=e.from;f.fn[c]=function(c){i&&!this[h]&&(this[h]=i(this._rgba));if(c===b)return this[h].slice();var d,e=a.type(c),k=e==="array"||e==="object"?c:arguments,n=this[h].slice();return l(g,function(a,b){var c=k[e==="object"?a:b.idx];c==null&&(c=n[b.idx]),n[b.idx]=m(c,b)}),j?(d=f(j(n)),d[h]=n,d):f(n)},l(g,function(b,e){if(f.fn[b])return;f.fn[b]=function(f){var g=a.type(f),h=b==="alpha"?this._hsla?"hsla":"rgba":c,i=this[h](),j=i[e.idx],k;return g==="undefined"?j:(g==="function"&&(f=f.call(this,j),g=a.type(f)),f==null&&e.empty?this:(g==="string"&&(k=d.exec(f),k&&(f=j+parseFloat(k[2])*(k[1]==="+"?1:-1))),i[e.idx]=f,this[h](i)))}})}),f.hook=function(b){var c=b.split(" ");l(c,function(b,c){a.cssHooks[c]={set:function(b,d){var e,g,h="";if(d!=="transparent"&&(a.type(d)!=="string"||(e=n(d)))){d=f(e||d);if(!i.rgba&&d._rgba[3]!==1){g=c==="backgroundColor"?b.parentNode:b;while((h===""||h==="transparent")&&g&&g.style)try{h=a.css(g,"backgroundColor"),g=g.parentNode}catch(j){}d=d.blend(h&&h!=="transparent"?h:"_default")}d=d.toRgbaString()}try{b.style[c]=d}catch(j){}}},a.fx.step[c]=function(b){b.colorInit||(b.start=f(b.elem,c),b.end=f(b.end),b.colorInit=!0),a.cssHooks[c].set(b.elem,b.start.transition(b.end,b.pos))}})},f.hook(c),a.cssHooks.borderColor={expand:function(a){var b={};return l(["Top","Right","Bottom","Left"],function(c,d){b["border"+d+"Color"]=a}),b}},k=a.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}})(jQuery);
6684 var $d = $(document);
6685 var may = function(o,f) {return f ? f.bind(o) : function() {}};
6687 $.extend(true, $[deck].defaults, {
6689 animShow: ".anim-show",
6690 animHide: ".anim-hide",
6691 animAddClass: ".anim-addclass",
6692 animRemoveClass: ".anim-removeclass",
6693 animAttribute: ".anim-attribute",
6694 animWait: ".anim-wait",
6696 animPlay: ".anim-play",
6697 animPause: ".anim-pause",
6698 animViewboxAs: ".anim-viewboxas",
6699 animAlong: ".anim-along",
6701 animContinue: ".anim-continue"
6704 animReady: "deck-anim-ready"
6711 var doInit = function() {
6712 // first we define some tools and grab some info from deck.js
6713 var o = $[deck]('getOptions');
6714 var context = function(el) {
6716 what: function() {return $(el).attr("data-what")},
6717 dur: function() {return $(el).attr("data-dur")*1 || o.anim.duration},
6718 delay: function() {return $(el).attr("data-delay")*1 || 0},
6719 classs: function() {return $(el).attr("data-class")},
6720 attribute: function() {return $(el).attr("data-attr").split(':')[0]},
6721 as: function() {return $(el).attr("data-as")},
6722 path: function() {return $(el).attr("data-path")},
6723 reverse: function() {var r = $(el).attr("data-reverse"); return r && r.toUpperCase() == "TRUE";},
6724 value: function() {return $(el).attr("data-attr").split(':')[1]},
6725 toplevel: function() {return $[deck]('getToplevelSlideOf', el).node},
6726 all: function() {return $(this.what(),this.toplevel())}
6729 var globalHasAnimContinue = false;
6730 var classical = function(selector, methods) {
6731 $(selector).each(function(i, el) {
6732 var c = context(el);
6733 may(methods, methods.create)(c);
6734 $(el).bind('deck.toplevelBecameCurrent', function(_, direction) {
6735 may(methods, methods.init)(c);
6736 }).bind('deck.afterToplevelBecameCurrent', function(_, direction) {
6737 may(methods, methods.fast)(c);
6738 }).bind('deck.lostCurrent', function(_, direction, from, to) {
6739 if (direction == 'forward' || Math.abs(from - to)>1 ) return; // if a big step, let the "step" extension do its job
6740 may(methods, methods.undo)(c);
6741 }).bind('deck.becameCurrent', function(_, direction, from, to) {
6742 if (direction == 'reverse' || Math.abs(from - to)>1 ) return; // if a big step, let the "step" extension do its job
6744 setTimeout(function() {
6745 may(methods, methods.doit)(c);
6748 may(methods, methods.doit)(c);
6754 // here come the real animations
6755 classical(o.selectors.animShow, {
6756 init: function(c) {c.all().animate({'opacity': 0.}, 0)},
6757 undo: function(c) {c.all().animate({'opacity': 0.}, c.dur()/100)},
6758 doit: function(c) {c.all().animate({'opacity': 1.}, c.dur())},
6759 fast: function(c) {c.all().animate({'opacity': 1.}, 0)}
6761 classical(o.selectors.animHide, {
6762 init: function(c) {c.all().animate({'opacity': 1.}, 0)},
6763 undo: function(c) {c.all().animate({'opacity': 1.}, c.dur()/100)},
6764 doit: function(c) {c.all().animate({'opacity': 0.}, c.dur())},
6765 fast: function(c) {c.all().animate({'opacity': 0.}, 0)}
6767 classical(o.selectors.animAddClass, {
6768 init: function(c) {c.all().each(function() { this.classList.remove(c.classs()) })},
6769 undo: function(c) {c.all().each(function() { this.classList.remove(c.classs()) })},
6770 doit: function(c) {c.all().each(function() { this.classList.add(c.classs()) })},
6771 fast: function(c) {c.all().each(function() { this.classList.add(c.classs()) })}
6773 classical(o.selectors.animRemoveClass, {
6774 init: function(c) {c.all().each(function() { this.classList.add(c.classs()) })},
6775 undo: function(c) {c.all().each(function() { this.classList.add(c.classs()) })},
6776 doit: function(c) {c.all().each(function() { this.classList.remove(c.classs()) })},
6777 fast: function(c) {c.all().each(function() { this.classList.remove(c.classs()) })}
6779 function svgRealAttrName(a) {
6780 if (startsWith(a, "svg")) {
6781 return REST.substr(0, 1).toLowerCase() + REST.slice(1);
6785 function startsWith(longStr, part) {
6786 var res = longStr.substr(0, part.length) == part;
6787 REST = res ? longStr.slice(part.length) : null;
6790 classical(o.selectors.animAttribute, {
6795 // TODO: [feature] could allow multiple attributes to be passed and animated simultaneously
6796 var k = c.attribute()
6797 for (i in c.previousElement) { // use the saved list of elements and values
6799 whatTo[k] = c.previousCss[i];
6800 $(c.previousElement[i]).finish();
6801 if (c.previousElement[i] instanceof SVGElement) {
6802 if (whatTo[k] != null) {
6803 var realAttrName = svgRealAttrName(k) || k;
6804 c.previousElement[i].attributes.getNamedItem(realAttrName).value = whatTo[k];
6806 var realAttrName = svgRealAttrName(k) || k;
6807 c.previousElement[i].attributes.removeNamedItem(realAttrName);
6810 $(c.previousElement[i]).animate(whatTo, 0);
6814 doit: function(c, factor) {
6815 if (factor === undefined) factor = 1
6816 c.all().each( function() {
6817 // finish all previous animations
6818 if (!globalHasAnimContinue && $(this).queue().length) {
6822 var k = c.attribute()
6824 c.previousElement = []
6825 c.all().each( function(){
6826 c.previousElement.push(this);
6827 var v = $(this).css(k);
6828 if (v == null && this instanceof SVGElement) {
6829 var realAttrName = svgRealAttrName(k) || k;
6830 var attr = this.attributes.getNamedItem(realAttrName);
6831 c.previousCss.push(attr ? attr.value : null);
6833 c.previousCss.push(v);
6835 }); // save a list of elements and values
6837 whatTo[c.attribute()] = c.value()
6838 c.all().animate(whatTo, c.dur()*factor)
6840 fast: function(c) {this.doit(c,0)}
6842 classical(o.selectors.animViewboxAs, {
6843 create: function(c) {
6844 c.attribute = function() {return "svgViewBox"};
6845 c.value = function() {
6846 var asWhat = $(c.as());
6847 var a = function (i) {return asWhat.attr(i)}
6848 var toViewBox = a('x')+" "+a('y')+" "+a('width')+" "+a('height');
6852 init: function(c) {this.undo(c)},
6854 var k = c.attribute()
6855 for (i in c.previousElement) { // use the saved list of elements and values
6857 whatTo[k] = c.previousValue[i]
6858 $(c.previousElement[i]).finish();
6859 $(c.previousElement[i]).animate(whatTo, 0)
6862 doit: function(c, factor) {
6863 if (factor === undefined) factor = 1
6864 c.all().each( function() {
6865 // finish all previous animations
6866 if (!globalHasAnimContinue && $(this).queue().length) {
6870 var k = c.attribute()
6871 c.previousValue = []
6872 c.previousElement = []
6873 c.all().each( function() {
6874 c.previousElement.push(this);
6875 c.previousValue.push(this.attributes.getNamedItem('viewBox').value);
6876 }); // save a list of elements and values
6878 whatTo[k] = c.value()
6879 c.all().animate(whatTo, c.dur()*factor)
6881 fast: function(c) {this.doit(c,0)}
6883 classical(o.selectors.animAlong, {
6884 init: function(c) {this.undo(c)},
6886 for (i in c.previousElement) { // use the saved list of elements and values
6887 var prev = c.previousValue[i];
6888 $(c.previousElement[i]).finish();
6889 $(c.previousElement[i]).attr("transform", prev);
6892 doit: function(c, factor) {
6893 if (factor === undefined) factor = 1;
6894 c.all().each( function() {
6895 // finish all previous animations
6896 if (!globalHasAnimContinue && $(this).queue().length) {
6900 var path = $(c.path()).get(0);
6901 var rev = c.reverse();
6902 var len = path.getTotalLength()
6903 var s = path.getPointAtLength(rev?len:0);
6904 c.previousValue = [];
6905 c.previousElement = [];
6906 c.all().each( function() {
6908 if ($(this).attr("transform") != null) {
6909 base = $(this).attr("transform"); // TODO maybe can use attr also above (anim-attr)
6910 c.previousValue.push(base);
6912 c.previousValue.push(null);
6914 c.previousElement.push(this);
6915 $(this).css({svgDeckAnim: 0.});
6916 $(this).animate({svgDeckAnim: 1.}, {
6917 duration: c.dur()*factor,
6920 var p = path.getPointAtLength(v * len);
6921 $(this).attr("transform", 'translate('+(p.x-s.x)+','+(p.y-s.y)+')' + base);
6926 fast: function(c) {this.doit(c, 0);}
6928 classical(o.selectors.animPlay, {
6929 init: function(c) {c.all().each(function(){this.pause(); try{this.currentTime=0}catch(e){} })},
6930 undo: function(c) {c.all().each(function(){this.pause()})},
6931 doit: function(c) {c.all().each(function(){this.play()})},
6932 fast: function(c) {c.all().each(function(){this.play()})}
6934 classical(o.selectors.animPause, {
6935 undo: function(c) {c.all().each(function(){this.play()})},
6936 doit: function(c) {c.all().each(function(){this.pause()})},
6937 fast: function(c) {c.all().each(function(){this.pause()})}
6939 classical(o.selectors.animContinue, {
6940 doit: function(c) {setTimeout(function(){ globalHasAnimContinue = true; $[deck]('next') ; globalHasAnimContinue = false; }, 1)}
6941 // do not do it in fast mode
6943 classical(o.selectors.animWait, {
6944 doit: function(c) {setTimeout(function(){ globalHasAnimContinue = true; $[deck]('next') ; globalHasAnimContinue = false; }, c.dur())}
6946 // handle the chained undo for "anim-continue"
6947 $(o.selectors.animContinue + "," + o.selectors.animWait).each(function(i, curSlide) {
6948 $(curSlide).bind('deck.becameCurrent', function(_, direction) {
6949 if (direction == 'forward') return;
6950 setTimeout(function(){$[deck]('prev')}, 1)
6955 // finally force "refresh" (notification of slide change)
6956 var current = $[deck]('getSlide')
6958 for (; icur < $[deck]('getSlides').length; icur++) {
6959 if ($[deck]('getSlides')[icur] == current) break;
6961 $d.trigger("deck.change", [icur, 0]);
6962 $d.trigger("deck.change", [0, icur]);
6964 var container = $[deck]('getContainer');
6965 $(container).addClass(o.classes.animReady)
6967 $(document).bind('deck.init', function() {
6974 (function(e){function d(){this._settings=[];this._extensions=[];this.regional=[];this.regional[""]={errorLoadingText:"Error loading",notSupportedText:"This browser does not support SVG"};this.local=this.regional[""];this._uuid=new Date().getTime();this._renesis=c("RenesisX.RenesisCtrl")}function c(i){try{return !!(window.ActiveXObject&&new ActiveXObject(i))}catch(j){return false}}var g="svgwrapper";e.extend(d.prototype,{markerClassName:"hasSVG",svgNS:"http://www.w3.org/2000/svg",xlinkNS:"http://www.w3.org/1999/xlink",_wrapperClass:b,_attrNames:{class_:"class",in_:"in",alignmentBaseline:"alignment-baseline",baselineShift:"baseline-shift",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorRendering:"color-rendering",dominantBaseline:"dominant-baseline",enableBackground:"enable-background",fillOpacity:"fill-opacity",fillRule:"fill-rule",floodColor:"flood-color",floodOpacity:"flood-opacity",fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",imageRendering:"image-rendering",letterSpacing:"letter-spacing",lightingColor:"lighting-color",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",strokeDashArray:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeLineCap:"stroke-linecap",strokeLineJoin:"stroke-linejoin",strokeMiterLimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",underlinePosition:"underline-position",underlineThickness:"underline-thickness",vertAdvY:"vert-adv-y",vertOriginY:"vert-origin-y",wordSpacing:"word-spacing",writingMode:"writing-mode"},_attachSVG:function(i,k){var j=(i.namespaceURI==this.svgNS?i:null);var i=(j?null:i);if(e(i||j).hasClass(this.markerClassName)){return}if(typeof k=="string"){k={loadURL:k}}else{if(typeof k=="function"){k={onLoad:k}}}e(i||j).addClass(this.markerClassName);try{if(!j){j=document.createElementNS(this.svgNS,"svg");j.setAttribute("version","1.1");if(i.clientWidth>0){j.setAttribute("width",i.clientWidth)}if(i.clientHeight>0){j.setAttribute("height",i.clientHeight)}i.appendChild(j)}this._afterLoad(i,j,k||{})}catch(l){if(!e.support.noCloneChecked){if(!i.id){i.id="svg"+(this._uuid++)}this._settings[i.id]=k;i.innerHTML='<embed type="image/svg+xml" width="100%" height="100%" src="'+(k.initPath||"")+'blank.svg" pluginspage="http://www.adobe.com/svg/viewer/install/main.html"/>'}else{i.innerHTML='<p class="svg_error">'+this.local.notSupportedText+"</p>"}}},_registerSVG:function(){for(var l=0;l<document.embeds.length;l++){var j=document.embeds[l].parentNode;if(!e(j).hasClass(e.svg.markerClassName)||e.data(j,g)){continue}var k=null;try{k=document.embeds[l].getSVGDocument()}catch(m){setTimeout(e.svg._registerSVG,250);return}k=(k?k.documentElement:null);if(k){e.svg._afterLoad(j,k)}}},_afterLoad:function(i,j,k){var k=k||this._settings[i.id];this._settings[i?i.id:""]=null;var m=new this._wrapperClass(j,i);e.data(i||j,g,m);try{if(k.loadURL){m.load(k.loadURL,k)}if(k.settings){m.configure(k.settings)}if(k.onLoad&&!k.loadURL){k.onLoad.apply(i||j,[m])}}catch(l){alert(l)}},_getSVG:function(i){i=(typeof i=="string"?e(i)[0]:(i.jquery?i[0]:i));return e.data(i,g)},_destroySVG:function(i){var j=e(i);if(!j.hasClass(this.markerClassName)){return}j.removeClass(this.markerClassName);if(i.namespaceURI!=this.svgNS){j.empty()}e.removeData(i,g)},addExtension:function(j,i){this._extensions.push([j,i])},isSVGElem:function(i){return(i.nodeType==1&&i.namespaceURI==e.svg.svgNS)}});function b(k,j){this._svg=k;this._container=j;for(var l=0;l<e.svg._extensions.length;l++){var m=e.svg._extensions[l];this[m[0]]=new m[1](this)}}e.extend(b.prototype,{_width:function(){return(this._container?this._container.clientWidth:this._svg.width)},_height:function(){return(this._container?this._container.clientHeight:this._svg.height)},root:function(){return this._svg},configure:function(o,n,k){if(!o.nodeName){k=n;n=o;o=this._svg}if(k){for(var m=o.attributes.length-1;m>=0;m--){var j=o.attributes.item(m);if(!(j.nodeName=="onload"||j.nodeName=="version"||j.nodeName.substring(0,5)=="xmlns")){o.attributes.removeNamedItem(j.nodeName)}}}for(var l in n){o.setAttribute(e.svg._attrNames[l]||l,n[l])}return this},getElementById:function(i){return this._svg.ownerDocument.getElementById(i)},change:function(j,k){if(j){for(var i in k){if(k[i]==null){j.removeAttribute(e.svg._attrNames[i]||i)}else{j.setAttribute(e.svg._attrNames[i]||i,k[i])}}}return this},_args:function(k,n,j){n.splice(0,0,"parent");n.splice(n.length,0,"settings");var l={};var o=0;if(k[0]!=null&&k[0].jquery){k[0]=k[0][0]}if(k[0]!=null&&!(typeof k[0]=="object"&&k[0].nodeName)){l.parent=null;o=1}for(var m=0;m<k.length;m++){l[n[m+o]]=k[m]}if(j){e.each(j,function(p,q){if(typeof l[q]=="object"){l.settings=l[q];l[q]=null}})}return l},title:function(k,m,j){var i=this._args(arguments,["text"]);var l=this._makeNode(i.parent,"title",i.settings||{});l.appendChild(this._svg.ownerDocument.createTextNode(i.text));return l},describe:function(k,m,j){var i=this._args(arguments,["text"]);var l=this._makeNode(i.parent,"desc",i.settings||{});l.appendChild(this._svg.ownerDocument.createTextNode(i.text));return l},defs:function(k,l,j){var i=this._args(arguments,["id"],["id"]);return this._makeNode(i.parent,"defs",e.extend((i.id?{id:i.id}:{}),i.settings||{}))},symbol:function(o,p,k,n,m,i,l){var j=this._args(arguments,["id","x1","y1","width","height"]);return this._makeNode(j.parent,"symbol",e.extend({id:j.id,viewBox:j.x1+" "+j.y1+" "+j.width+" "+j.height},j.settings||{}))},marker:function(o,i,q,p,l,j,m,k){var n=this._args(arguments,["id","refX","refY","mWidth","mHeight","orient"],["orient"]);return this._makeNode(n.parent,"marker",e.extend({id:n.id,refX:n.refX,refY:n.refY,markerWidth:n.mWidth,markerHeight:n.mHeight,orient:n.orient||"auto"},n.settings||{}))},style:function(k,m,j){var i=this._args(arguments,["styles"]);var l=this._makeNode(i.parent,"style",e.extend({type:"text/css"},i.settings||{}));l.appendChild(this._svg.ownerDocument.createTextNode(i.styles));return l},script:function(m,i,l,k){var j=this._args(arguments,["script","type"],["type"]);var n=this._makeNode(j.parent,"script",e.extend({type:j.type||"text/javascript"},j.settings||{}));n.appendChild(this._svg.ownerDocument.createTextNode(j.script));return n},linearGradient:function(q,j,r,k,p,i,o,l){var n=this._args(arguments,["id","stops","x1","y1","x2","y2"],["x1"]);var m=e.extend({id:n.id},(n.x1!=null?{x1:n.x1,y1:n.y1,x2:n.x2,y2:n.y2}:{}));return this._gradient(n.parent,"linearGradient",e.extend(m,n.settings||{}),n.stops)},radialGradient:function(s,j,t,o,m,i,n,k,l){var q=this._args(arguments,["id","stops","cx","cy","r","fx","fy"],["cx"]);var p=e.extend({id:q.id},(q.cx!=null?{cx:q.cx,cy:q.cy,r:q.r,fx:q.fx,fy:q.fy}:{}));return this._gradient(q.parent,"radialGradient",e.extend(p,q.settings||{}),q.stops)},_gradient:function(n,j,m,p){var o=this._makeNode(n,j,m);for(var l=0;l<p.length;l++){var k=p[l];this._makeNode(o,"stop",e.extend({offset:k[0],stopColor:k[1]},(k[2]!=null?{stopOpacity:k[2]}:{})))}return o},pattern:function(s,i,r,p,j,t,q,o,l,u,k){var n=this._args(arguments,["id","x","y","width","height","vx","vy","vwidth","vheight"],["vx"]);var m=e.extend({id:n.id,x:n.x,y:n.y,width:n.width,height:n.height},(n.vx!=null?{viewBox:n.vx+" "+n.vy+" "+n.vwidth+" "+n.vheight}:{}));return this._makeNode(n.parent,"pattern",e.extend(m,n.settings||{}))},clipPath:function(l,m,i,k){var j=this._args(arguments,["id","units"]);j.units=j.units||"userSpaceOnUse";return this._makeNode(j.parent,"clipPath",e.extend({id:j.id,clipPathUnits:j.units},j.settings||{}))},mask:function(n,p,j,o,m,i,l){var k=this._args(arguments,["id","x","y","width","height"]);return this._makeNode(k.parent,"mask",e.extend({id:k.id,x:k.x,y:k.y,width:k.width,height:k.height},k.settings||{}))},createPath:function(){return new f()},createText:function(){return new h()},svg:function(r,q,o,i,s,p,n,k,t,j){var m=this._args(arguments,["x","y","width","height","vx","vy","vwidth","vheight"],["vx"]);var l=e.extend({x:m.x,y:m.y,width:m.width,height:m.height},(m.vx!=null?{viewBox:m.vx+" "+m.vy+" "+m.vwidth+" "+m.vheight}:{}));return this._makeNode(m.parent,"svg",e.extend(l,m.settings||{}))},group:function(k,l,j){var i=this._args(arguments,["id"],["id"]);return this._makeNode(i.parent,"g",e.extend({id:i.id},i.settings||{}))},use:function(p,o,n,i,q,j,l){var m=this._args(arguments,["x","y","width","height","ref"]);if(typeof m.x=="string"){m.ref=m.x;m.settings=m.y;m.x=m.y=m.width=m.height=null}var k=this._makeNode(m.parent,"use",e.extend({x:m.x,y:m.y,width:m.width,height:m.height},m.settings||{}));k.setAttributeNS(e.svg.xlinkNS,"href",m.ref);return k},link:function(k,m,j){var i=this._args(arguments,["ref"]);var l=this._makeNode(i.parent,"a",i.settings);l.setAttributeNS(e.svg.xlinkNS,"href",i.ref);return l},image:function(p,o,n,i,q,j,l){var m=this._args(arguments,["x","y","width","height","ref"]);var k=this._makeNode(m.parent,"image",e.extend({x:m.x,y:m.y,width:m.width,height:m.height},m.settings||{}));k.setAttributeNS(e.svg.xlinkNS,"href",m.ref);return k},path:function(k,l,j){var i=this._args(arguments,["path"]);return this._makeNode(i.parent,"path",e.extend({d:(i.path.path?i.path.path():i.path)},i.settings||{}))},rect:function(p,o,n,k,q,j,i,l){var m=this._args(arguments,["x","y","width","height","rx","ry"],["rx"]);return this._makeNode(m.parent,"rect",e.extend({x:m.x,y:m.y,width:m.width,height:m.height},(m.rx?{rx:m.rx,ry:m.ry}:{}),m.settings||{}))},circle:function(l,i,n,m,k){var j=this._args(arguments,["cx","cy","r"]);return this._makeNode(j.parent,"circle",e.extend({cx:j.cx,cy:j.cy,r:j.r},j.settings||{}))},ellipse:function(l,i,o,n,m,k){var j=this._args(arguments,["cx","cy","rx","ry"]);return this._makeNode(j.parent,"ellipse",e.extend({cx:j.cx,cy:j.cy,rx:j.rx,ry:j.ry},j.settings||{}))},line:function(o,k,n,i,l,m){var j=this._args(arguments,["x1","y1","x2","y2"]);return this._makeNode(j.parent,"line",e.extend({x1:j.x1,y1:j.y1,x2:j.x2,y2:j.y2},j.settings||{}))},polyline:function(l,k,j){var i=this._args(arguments,["points"]);return this._poly(i.parent,"polyline",i.points,i.settings)},polygon:function(l,k,j){var i=this._args(arguments,["points"]);return this._poly(i.parent,"polygon",i.points,i.settings)},_poly:function(n,j,m,l){var o="";for(var k=0;k<m.length;k++){o+=m[k].join()+" "}return this._makeNode(n,j,e.extend({points:e.trim(o)},l||{}))},text:function(l,i,n,m,k){var j=this._args(arguments,["x","y","value"]);if(typeof j.x=="string"&&arguments.length<4){j.value=j.x;j.settings=j.y;j.x=j.y=null}return this._text(j.parent,"text",j.value,e.extend({x:(j.x&&a(j.x)?j.x.join(" "):j.x),y:(j.y&&a(j.y)?j.y.join(" "):j.y)},j.settings||{}))},textpath:function(k,n,m,j){var i=this._args(arguments,["path","value"]);var l=this._text(i.parent,"textPath",i.value,i.settings||{});l.setAttributeNS(e.svg.xlinkNS,"href",i.path);return l},_text:function(r,j,q,n){var m=this._makeNode(r,j,n);if(typeof q=="string"){m.appendChild(m.ownerDocument.createTextNode(q))}else{for(var o=0;o<q._parts.length;o++){var l=q._parts[o];if(l[0]=="tspan"){var k=this._makeNode(m,l[0],l[2]);k.appendChild(m.ownerDocument.createTextNode(l[1]));m.appendChild(k)}else{if(l[0]=="tref"){var k=this._makeNode(m,l[0],l[2]);k.setAttributeNS(e.svg.xlinkNS,"href",l[1]);m.appendChild(k)}else{if(l[0]=="textpath"){var p=e.extend({},l[2]);p.href=null;var k=this._makeNode(m,l[0],p);k.setAttributeNS(e.svg.xlinkNS,"href",l[2].href);k.appendChild(m.ownerDocument.createTextNode(l[1]));m.appendChild(k)}else{m.appendChild(m.ownerDocument.createTextNode(l[1]))}}}}}return m},other:function(l,j,k){var i=this._args(arguments,["name"]);return this._makeNode(i.parent,i.name,i.settings||{})},_makeNode:function(k,i,j){k=k||this._svg;var l=this._svg.ownerDocument.createElementNS(e.svg.svgNS,i);for(var i in j){var m=j[i];if(m!=null&&m!=null&&(typeof m!="string"||m!="")){l.setAttribute(e.svg._attrNames[i]||i,m)}}k.appendChild(l);return l},add:function(k,l){var j=this._args((arguments.length==1?[null,k]:arguments),["node"]);var i=this;j.parent=j.parent||this._svg;j.node=(j.node.jquery?j.node:e(j.node));try{if(e.svg._renesis){throw"Force traversal"}j.parent.appendChild(j.node.cloneNode(true))}catch(m){j.node.each(function(){var n=i._cloneAsSVG(this);if(n){j.parent.appendChild(n)}})}return this},clone:function(l,m){var i=this;var k=this._args((arguments.length==1?[null,l]:arguments),["node"]);k.parent=k.parent||this._svg;k.node=(k.node.jquery?k.node:e(k.node));var j=[];k.node.each(function(){var n=i._cloneAsSVG(this);if(n){n.id="";k.parent.appendChild(n);j.push(n)}});return j},_cloneAsSVG:function(m){var l=null;if(m.nodeType==1){l=this._svg.ownerDocument.createElementNS(e.svg.svgNS,this._checkName(m.nodeName));for(var k=0;k<m.attributes.length;k++){var j=m.attributes.item(k);if(j.nodeName!="xmlns"&&j.nodeValue){if(j.prefix=="xlink"){l.setAttributeNS(e.svg.xlinkNS,j.localName||j.baseName,j.nodeValue)}else{l.setAttribute(this._checkName(j.nodeName),j.nodeValue)}}}for(var k=0;k<m.childNodes.length;k++){var o=this._cloneAsSVG(m.childNodes[k]);if(o){l.appendChild(o)}}}else{if(m.nodeType==3){if(e.trim(m.nodeValue)){l=this._svg.ownerDocument.createTextNode(m.nodeValue)}}else{if(m.nodeType==4){if(e.trim(m.nodeValue)){try{l=this._svg.ownerDocument.createCDATASection(m.nodeValue)}catch(n){l=this._svg.ownerDocument.createTextNode(m.nodeValue.replace(/&/g,"&").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);
6975 (function(a){a.each(["x","y","width","height","rx","ry","cx","cy","r","x1","y1","x2","y2","stroke-width","strokeWidth","opacity","fill-opacity","fillOpacity","stroke-opacity","strokeOpacity","stroke-dashoffset","strokeDashOffset","font-size","fontSize","font-weight","fontWeight","letter-spacing","letterSpacing","word-spacing","wordSpacing"],function(h,g){var f=g.charAt(0).toUpperCase()+g.substr(1);if(a.cssProps){a.cssProps["svg"+f]=a.cssProps["svg-"+g]=g}a.fx.step["svg"+f]=a.fx.step["svg-"+g]=function(k){var j=a.svg._attrNames[g]||g;var i=k.elem.attributes.getNamedItem(j);if(!k.set){k.start=(i?parseFloat(i.value):0);var m="";if(/^[+-]=/.exec(m)){k.end=k.start+parseFloat(m.replace(/=/,""))}a(k.elem).css(j,"");k.set=true}var l=(k.pos*(k.end-k.start)+k.start)+(k.unit=="%"?"%":"");(i?i.value=l:k.elem.setAttribute(j,l))}});a.fx.step.svgStrokeDashArray=a.fx.step["svg-strokeDashArray"]=a.fx.step["svgStroke-dasharray"]=a.fx.step["svg-stroke-dasharray"]=function(j){var g=j.elem.attributes.getNamedItem("stroke-dasharray");if(!j.set){j.start=c(g?g.value:"");var l=j.end;j.end=c(l);if(/^[+-]=/.exec(l)){l=l.split(/[, ]+/);if(l.length%2==1){var f=l.length;for(var h=0;h<f;h++){l.push(l[h])}}for(var h=0;h<l.length;h++){if(/^[+-]=/.exec(l[h])){j.end[h]=j.start[h]+parseFloat(l[h].replace(/=/,""))}}}j.set=true}var k=a.map(j.start,function(o,m){return(j.pos*(j.end[m]-o)+o)}).join(",");(g?g.value=k:j.elem.setAttribute("stroke-dasharray",k))};function c(j){var g=j.split(/[, ]+/);for(var h=0;h<g.length;h++){g[h]=parseFloat(g[h]);if(isNaN(g[h])){g[h]=0}}if(g.length%2==1){var f=g.length;for(var h=0;h<f;h++){g.push(g[h])}}return g}a.fx.step.svgViewBox=a.fx.step["svg-viewBox"]=function(h){var f=h.elem.attributes.getNamedItem("viewBox");if(!h.set){h.start=b(f?f.value:"");var k=h.end;h.end=b(k);if(/^[+-]=/.exec(k)){k=k.split(/[, ]+/);while(k.length<4){k.push("0")}for(var g=0;g<4;g++){if(/^[+-]=/.exec(k[g])){h.end[g]=h.start[g]+parseFloat(k[g].replace(/=/,""))}}}h.set=true}var j=a.map(h.start,function(m,l){return(h.pos*(h.end[l]-m)+m)}).join(" ");(f?f.value=j:h.elem.setAttribute("viewBox",j))};function b(g){var h=g.split(/[, ]+/);for(var f=0;f<h.length;f++){h[f]=parseFloat(h[f]);if(isNaN(h[f])){h[f]=0}}while(h.length<4){h.push(0)}return h}a.fx.step.svgTransform=a.fx.step["svg-transform"]=function(m){var f=m.elem.attributes.getNamedItem("transform");if(!m.set){m.start=e(f?f.value:"");m.end=e(m.end,m.start);m.set=true}var k="";for(var l=0;l<m.end.order.length;l++){switch(m.end.order.charAt(l)){case"t":k+=" translate("+(m.pos*(m.end.translateX-m.start.translateX)+m.start.translateX)+","+(m.pos*(m.end.translateY-m.start.translateY)+m.start.translateY)+")";break;case"s":k+=" scale("+(m.pos*(m.end.scaleX-m.start.scaleX)+m.start.scaleX)+","+(m.pos*(m.end.scaleY-m.start.scaleY)+m.start.scaleY)+")";break;case"r":k+=" rotate("+(m.pos*(m.end.rotateA-m.start.rotateA)+m.start.rotateA)+","+(m.pos*(m.end.rotateX-m.start.rotateX)+m.start.rotateX)+","+(m.pos*(m.end.rotateY-m.start.rotateY)+m.start.rotateY)+")";break;case"x":k+=" skewX("+(m.pos*(m.end.skewX-m.start.skewX)+m.start.skewX)+")";case"y":k+=" skewY("+(m.pos*(m.end.skewY-m.start.skewY)+m.start.skewY)+")";break;case"m":var g="";for(var h=0;h<6;h++){g+=","+(m.pos*(m.end.matrix[h]-m.start.matrix[h])+m.start.matrix[h])}k+=" matrix("+g.substr(1)+")";break}}(f?f.value=k:m.elem.setAttribute("transform",k))};function e(j,h){j=j||"";if(typeof j=="object"){j=j.value}var g=a.extend({translateX:0,translateY:0,scaleX:0,scaleY:0,rotateA:0,rotateX:0,rotateY:0,skewX:0,skewY:0,matrix:[0,0,0,0,0,0]},h||{});g.order="";var i=/([a-zA-Z]+)\(\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*(?:[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*[\s,]\s*([+-]?[\d\.]+)\s*)?)?)?\)/g;var f=i.exec(j);while(f){switch(f[1]){case"translate":g.order+="t";g.translateX=parseFloat(f[2]);g.translateY=(f[3]?parseFloat(f[3]):0);break;case"scale":g.order+="s";g.scaleX=parseFloat(f[2]);g.scaleY=(f[3]?parseFloat(f[3]):g.scaleX);break;case"rotate":g.order+="r";g.rotateA=parseFloat(f[2]);g.rotateX=(f[3]?parseFloat(f[3]):0);g.rotateY=(f[4]?parseFloat(f[4]):0);break;case"skewX":g.order+="x";g.skewX=parseFloat(f[2]);break;case"skewY":g.order+="y";g.skewY=parseFloat(f[2]);break;case"matrix":g.order+="m";g.matrix=[parseFloat(f[2]),parseFloat(f[3]),parseFloat(f[4]),parseFloat(f[5]),parseFloat(f[6]),parseFloat(f[7])];break}f=i.exec(j)}if(g.order=="m"&&Math.abs(g.matrix[0])==Math.abs(g.matrix[3])&&g.matrix[1]!=0&&Math.abs(g.matrix[1])==Math.abs(g.matrix[2])){var k=Math.acos(g.matrix[0])*180/Math.PI;k=(g.matrix[1]<0?360-k:k);g.order="rt";g.rotateA=k;g.rotateX=g.rotateY=0;g.translateX=g.matrix[4];g.translateY=g.matrix[5]}return g}a.each(["fill","stroke"],function(h,g){var f=g.charAt(0).toUpperCase()+g.substr(1);a.fx.step["svg"+f]=a.fx.step["svg-"+g]=function(k){if(!k.set){k.start=a.svg._getColour(k.elem,g);var j=(k.end=="none");k.end=(j?a.svg._getColour(k.elem.parentNode,g):a.svg._getRGB(k.end));k.end[3]=j;a(k.elem).css(g,"");k.set=true}var i=k.elem.attributes.getNamedItem(g);var l="rgb("+[Math.min(Math.max(parseInt((k.pos*(k.end[0]-k.start[0]))+k.start[0],10),0),255),Math.min(Math.max(parseInt((k.pos*(k.end[1]-k.start[1]))+k.start[1],10),0),255),Math.min(Math.max(parseInt((k.pos*(k.end[2]-k.start[2]))+k.start[2],10),0),255)].join(",")+")";l=(k.end[3]&&k.state==1?"none":l);(i?i.value=l:k.elem.setAttribute(g,l))}});a.svg._getColour=function(g,f){g=a(g);var h;do{h=g.attr(f)||g.css(f);if((h!=""&&h!="none")||g.hasClass(a.svg.markerClassName)){break}}while(g=g.parent());return a.svg._getRGB(h)};a.svg._getRGB=function(g){var f;if(g&&g.constructor==Array){return(g.length==3||g.length==4?g:d.none)}if(f=/^rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)$/.exec(g)){return[parseInt(f[1],10),parseInt(f[2],10),parseInt(f[3],10)]}if(f=/^rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)$/.exec(g)){return[parseFloat(f[1])*2.55,parseFloat(f[2])*2.55,parseFloat(f[3])*2.55]}if(f=/^#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(g)){return[parseInt(f[1],16),parseInt(f[2],16),parseInt(f[3],16)]}if(f=/^#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(g)){return[parseInt(f[1]+f[1],16),parseInt(f[2]+f[2],16),parseInt(f[3]+f[3],16)]}return d[a.trim(g).toLowerCase()]||d.none};var d={"":[255,255,255,1],none:[255,255,255,1],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}})(jQuery);
6978 Copyright (c) 2012-2014 RĂ©mi Emonet, as a major refactor from an early version from RĂ©mi Barraquand.
6979 Licensed under the MIT license.
6980 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
6984 This module provides a support for managed svg inclusion (allowing proper DOM access subsequently for animations, etc.).
6987 (function($, deck, undefined) {
6988 var $d = $(document);
6989 var may = function(f) {return f ? f : function() {}};
6991 $.extend(true, $[deck].defaults, {
6993 svgPlaceholder: 'deck-svg'
6996 svgObject: "object[type='deckjs/svg'], div.svg-object",
6998 idrewrite: ".no-idrewrite",
6999 stylerewrite: ".no-stylerewrite"
7007 function walk(node, fn) {
7009 if (node.nodeType === 1) {
7011 walk(node.firstChild, fn);
7013 } while (node = node.nextSibling);
7016 styleToAttributes: function(root, svgfile) {
7017 walk(root, function() {
7019 if ($n.attr("style")) {
7020 $($n.attr("style").trim().split(/ *; */)).each(function(index, style) {
7021 if (style && style.substring(0,1) != "-") {
7022 var s = style.trim().split(/ *: */);
7023 $n.attr(s[0], s[1]);
7027 $n.attr("style", null);
7030 referencingAttributes: ["clip-path", "color-profile", "fill", "filter", "marker-start", "marker-mid", "marker-end", "mask", "stroke"],
7032 generateId: function(oldId) {
7033 var id = "uniquesvg"+svgPatcher.nextId;
7034 svgPatcher.nextId++;
7037 makeReferencedIdsUnique: function(root, svgfile, continuation) {
7038 var andThen = continuation || function(){}
7040 var referencersIds = {};
7041 var pushAdd = function(k, o) {
7042 if (referencersIds[k]) {
7043 referencersIds[k].push(o);
7045 referencersIds[k] = [ o ];
7048 // gather all ids and references
7049 walk(root, function() {
7056 $(svgPatcher.referencingAttributes).each(function(i,attr) {
7057 var val = $n.attr(attr);
7059 var groups = val.trim().match(/^url\(#(.+?)\)$/)
7060 if (groups) pushAdd(groups[1], {o:that, a:attr})
7063 var xlink = $n.attr("xlink:href");
7065 var groups = xlink.trim().match(/^#(.+?)$/)
7066 if (groups) pushAdd(groups[1], {o:that, a:"xlink:href"})
7069 // patch used ids and references (keep unreferenced ids fixed (to allow for identification from the editor to the css, even if classes should be preferred))
7071 for (id in referencersIds) {
7072 var newId = svgPatcher.generateId(id);
7073 byId[id].id = newId;
7077 setTimeout( // to help firefox in having updated ids
7079 for (id in referencersIds) {
7080 var newId = newIds[id];
7081 var refs = referencersIds[id];
7082 $(refs).each(function(i,pair){
7083 var prev = $(pair.o).attr(pair.a);
7084 if (pair.a == "xlink:href") {
7085 pair.o.setAttributeNS($.svg.xlinkNS, "href", prev.replace("#" + id, "#" + newId));
7087 $(pair.o).attr(pair.a, prev.replace("#" + id, "#" + newId));
7098 $d.bind('deck.beforeInit', function (event) {
7100 var opts = $[deck]('getOptions');
7101 var container = $[deck]('getContainer');
7104 Load parameters from an Object element
7106 var loadObjectParams = function(objectElement) {
7107 var attributes = {};
7108 $(objectElement).children("param").each(function(index){
7109 attributes[$(this).attr("name")] = $(this).attr("value");
7111 $.each(objectElement.attributes, function (index, attr) {
7112 if ("data-" == attr.name.substr(0, 5)) {
7113 attributes[attr.name.substr(5)] = attr.value;
7120 Return true if default params are set.
7122 var validateParams = function(params) {
7123 return params['src'];// && params['width'] && params['height'];// && params['animator'];
7127 Create SVG placeholder
7129 var createSVG = function(object, attributes) {
7130 var $canvas, $control, $next, $reload, $placeholder;
7131 /* Create svg canvas */
7132 $canvas = $("<div />").attr({
7133 'id': $(object).attr('id'),
7134 'data-src': attributes['src'],
7135 'class': opts.classes.svgPlaceholder + " " + $(object).attr('class')
7137 'height': attributes['height'],
7138 'width': attributes['width']
7144 /* Go through all toplevel slides */
7145 $($[deck]('getTopLevelSlides')).each( function(i, $slide) {
7147 /* Find all the object of type deckjs/svg */
7148 $slide.find(opts.selectors.svgObject).each(function(index, obj) {
7149 /* Load attributes and validate them */
7150 var attributes = loadObjectParams(obj);
7151 if (!validateParams(attributes) ) {
7152 throw "Error while initializing "+$(obj).attr('id')+", please ensure you have setup the required parameters."
7156 /* Create SVG placeholder */
7157 var SVG = createSVG(obj, attributes);
7158 $(obj).replaceWith(SVG);
7160 // Finaly load the SVG data
7163 var notDisabled = function(k) {
7165 var disabled = (attributes[kk] && attributes[kk] == "true") || $(obj).filter(opts.selectors.svgObjectDisable[k]).length > 0
7170 loadURL: attributes['src'],
7171 onLoad: function($svg, w, h) {
7172 var px = function (str) {return str.replace("px", "")}
7173 var aa = $($svg.root());
7174 aa.attr('width', '100%');
7175 aa.attr('height', '100%');
7176 if (aa.attr('viewBox') == undefined) {
7177 if (w==undefined || h==undefined) {
7178 if (opts.alert.missingSVG) alert(
7179 "There seem to be a problem with the loading of\n '"+attributes['src'] + "'\n"
7180 +"\nMaybe the file does not exist?"
7182 +"\n - it has no w or h attribute?"
7183 +"\n - you're using a file that is within a symbolic-link folder?"
7184 +"\n - you're using chrome with local files?"
7185 +"\n ⇒ try to restart chrome with '--disable-web-security'");
7186 event.releaseInit();
7188 var to = "0 0 " + px(w) + " " + px(h);
7189 $svg.root().setAttribute("viewBox", to);
7190 aa.attr("svgViewBox", to);
7191 if (attributes['stretch'] == 'true') $svg.root().setAttribute('preserveAspectRatio', "none");
7192 if (notDisabled('stylerewrite')) {
7193 svgPatcher.styleToAttributes($svg.root(), attributes['src']);
7195 if (notDisabled('idrewrite')) {
7196 svgPatcher.makeReferencedIdsUnique($svg.root(), attributes['src'], function() {
7197 event.releaseInit();
7200 event.releaseInit();
7208 event.releaseInit();
7216 Deck JS - deck.metadata
7217 Copyright (c) 2014 RĂ©mi Emonet
7218 Licensed under the MIT license.
7219 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7223 This module automatically takes each meta tag (e.g., author, date, ...) and the page title.
7224 It then replaces the content of all elements having a var-... class by the value of the metadata.
7226 This is very useful for example to repeat the date, title, venue name, author name, etc… in a title page, in the footer and in a closing page (without copy pasting).
7229 (function($, deck, undefined) {
7230 $.extend(true, $.deck.defaults, {
7232 metadataPrefix: '.var-',
7233 metadataBrSuffix: '-br',
7234 metadataFullSuffix: '-full'
7236 metadataSeparator: /( |Â )/gi /* we need to handle ' ' and 'Â ' because in the title, 'Â ' becomes ' ' */
7239 var $d = $(document);
7240 $d.bind('deck.init', function() {
7241 var o = $.deck('getOptions');
7242 var app = function(_sel, v) {
7243 var sel = o.selectors.metadataPrefix + _sel;
7244 var sep = o.metadataSeparator;
7245 $(sel).html(v.replace(sep, ""));
7246 $(sel+o.selectors.metadataFullSuffix).html(v);
7247 $(sel+o.selectors.metadataBrSuffix).html(v.replace(sep, "<br/>"));
7249 app("title", $("html>head>title").html());
7250 $("html>head>meta[name]").each(function(i,e) {
7251 app($(e).attr('name'), $(e).attr('content'))
7257 Deck JS - deck.attribution
7258 Copyright (c) 2014 RĂ©mi Emonet
7259 Licensed under the MIT license.
7260 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7264 This module automatically adds some text and a link for elements having a "data-attribution" attributes.
7267 (function($, deck, undefined) {
7268 $.extend(true, $.deck.defaults, {
7270 attributionWrapper: 'attribution-wrap',
7271 attributionLink: 'attribution-link'
7273 dataAttribution: "data-attribution",
7274 dataAttributionContent: "data-attribution-content",
7275 dataAttributionClass: "data-attribution-class"
7278 var $d = $(document);
7279 $d.bind('deck.init', function() {
7280 var o = $.deck('getOptions');
7281 $('*['+o.dataAttribution+']').each(function(i, el){
7282 var c = $(el).attr(o.dataAttributionContent);
7283 var cc = $(el).attr(o.dataAttributionClass);
7284 var a = $(el).attr(o.dataAttribution);
7286 w.addClass(o.classes.attributionWrapper);
7287 var link = $("<a>");
7288 link.addClass(o.classes.attributionLink);
7289 if (!! cc) link.addClass(cc);
7290 link.attr("href", a);
7291 link.attr("target", "_blank");
7304 Deck JS - deck.container-styling
7305 Copyright (c) 2014 RĂ©mi Emonet
7306 Licensed under the MIT license.
7307 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7311 This module automatically adds/removes to the container the class specified in data-container-class (for toplevel slides).
7313 This extension relies on the events extension.
7316 (function($, deck, undefined) {
7317 var $d = $(document);
7318 $d.bind('deck.init', function() {
7319 $('*[data-container-class]').each(function(i, el) {
7320 var toRemove = ""; // one 'toRemove' per element (that's why we do .each
7321 $(el).bind('deck.becameCurrent', function(_, direction) {
7322 var target = $(_.target);
7323 var toAdd = target.attr('data-container-class');
7324 $[deck]('getContainer').addClass(toAdd);
7326 }).bind('deck.lostCurrent', function(_, direction) {
7327 $[deck]('getContainer').removeClass(toRemove);
7332 $(document).bind('deck.init', function() { // force trigger even if no #slide-... is provided
7333 var current = $[deck]('getSlide')
7335 for (; icur < $[deck]('getSlides').length; icur++) {
7336 if ($[deck]('getSlides')[icur] == current) break;
7338 $(document).trigger("deck.change", [icur, icur]);
7343 Deck JS - deck.timekeeper
7344 Copyright (c) 2013-2014 RĂ©mi Emonet
7345 Licensed under the MIT license.
7346 https://github.com/imakewebthings/deck.js/blob/master/MIT-license.txt
7350 This module provides a support for displaying current time, time from start and logging the time spent on each slide etc.
7351 It also injects some default html for it if none is found (and styles it for the presenter/clone view).
7354 (function($, deck, undefined) {
7355 var $d = $(document);
7357 $.extend(true, $[deck].defaults, {
7359 timekeeper: ".timekeeper", /* inject if this is not present */ // TODO inject
7360 timekeeperTime: ".timekeeper-time",
7361 timekeeperRelativeTime: ".timekeeper-relative-time",
7362 timekeeperLocalRelativeTime: ".timekeeper-local-relative-time",
7363 timekeeperLogs: ".timekeeper-logs",
7364 timekeeperLogsPre: ".timekeeper-logs pre",
7365 timekeeperLogsToggle: ".timekeeper-logs-toggle",
7366 timekeeperBang: ".timekeeper-bang",
7367 timekeeperClear: ".timekeeper-clear"
7370 timekeeperNotification: "timekeeper-notification",
7371 timekeeperLogsVisible: "timekeeper-logs-visible"
7377 localStorageUnsupported: true
7380 timekeeperArchivesMaxSize: 500*1000,
7381 timekeeperArchives: 'deckjs-timekeeper-archives',
7382 timekeeperLogs: 'deckjs-timekeeper-logs',
7383 timekeeperBase: 'deckjs-timekeeper-base',
7384 timekeeperLocalBase: 'deckjs-timekeeper-local-base'
7386 timekeeperPeriod: 1000,
7387 timekeeperNotificationPeriod: 100,
7389 timekeeper: [27, 75] // escape, k (combine with SHIFT to reset the counter (when starting presenting))
7393 $d.bind('deck.init', function() {
7394 var opts = $[deck]('getOptions');
7395 var container = $[deck]('getContainer');
7397 // sligthly edited from
7398 var selectText = function(text) {
7402 if (doc.body.createTextRange) { //ms
7403 range = doc.body.createTextRange();
7404 range.moveToElementText(text);
7406 } else if (window.getSelection) { //all others
7407 selection = window.getSelection();
7408 range = doc.createRange();
7409 range.selectNodeContents(text);
7410 selection.removeAllRanges();
7411 selection.addRange(range);
7415 if (opts.snippets.timekeeper) {
7416 var d = function() {return $('<div/>');}
7417 var divTK = d().addClass("timekeeper timekeeper-logs-toggle");
7418 divTK.append(d().addClass("timekeeper-local-relative-time"));
7419 divTK.append(d().addClass("timekeeper-time"));
7420 divTK.append(d().addClass("timekeeper-relative-time"));
7421 divTK.append(d().addClass("timekeeper-clear"));
7422 divTK.append(d().addClass("timekeeper-bang"));
7423 divTK.appendTo(container);
7424 var divLog = d().addClass("timekeeper-logs");
7425 var pre = $('<pre/>').appendTo(divLog);
7426 divLog.append(d().addClass("button").click(function() { doBang() }).html("Bang!"));
7427 divLog.append(d().addClass("button").click(function() { selectText(pre.get(0)) }).html("select all"));
7428 divLog.append(d().addClass("button").click(function() { clearStorage() }).html("Clear").css({color:'#f44', marginLeft: '2em'}));
7429 divLog.append(d().addClass("button").addClass("timekeeper-logs-toggle").css({position:'float', float:'right', color:'#0f0'}).html("X"));
7430 divLog.appendTo(container);
7433 if (!window.localStorage && opts.alert.localStorageUnsupported) { alert(
7434 "LocalStorage is unsupported in your browser, timing features are disabled (timekeeper extension).");
7438 var pad = function(base, right) {
7440 if (s.length >= base.length) return s;
7441 else return base.substring(0, base.length - s.length) + s
7443 var formatTime = function(t) {
7444 var min = parseInt(t / 1000 / 60);
7445 var sec = parseInt(t / 1000 - 60 * min);
7447 var hours = parseInt(t / 1000 / 60 / 60);
7448 min = parseInt(t / 1000 / 60 - 60 * hours);
7449 return pad("00", hours) +":"+ pad("00", min) + ":" + pad("00", sec)
7451 return pad("00", min) + ":" + pad("00", sec)
7454 var clearStorage = function(what) {
7456 localStorage.setItem(opts.localStorage.timekeeperLogs, null);
7457 log("CLEARED BY USER");
7458 localStorage.setItem(opts.localStorage.timekeeperBase, JSON.stringify(new Date()));
7459 $(opts.selectors.timekeeperClear).addClass(opts.classes.timekeeperNotification);
7460 setTimeout(function() {
7461 $(opts.selectors.timekeeperClear).removeClass(opts.classes.timekeeperNotification);
7462 }, opts.timekeeperNotificationPeriod);
7464 var reset = function() {
7465 localStorage.setItem(opts.localStorage.timekeeperLocalBase, JSON.stringify(new Date()));
7467 var getDateOrSet = function(k, or) {
7468 var res = localStorage.getItem(k);
7470 res = JSON.stringify(or);
7471 localStorage.setItem(k, res);
7473 res = new Date(JSON.parse(res));
7477 var log = function(what) {
7478 var now = new Date();
7479 var time = now.toString()
7480 var localBase = getDateOrSet(opts.localStorage.timekeeperLocalBase, now);
7481 var base = getDateOrSet(opts.localStorage.timekeeperBase, now);
7482 var db = (now - localBase)/1000;
7483 var dcb = (now - base)/1000;
7484 var dbtime = formatTime(now - localBase);
7485 var dcbtime = formatTime(now - base);
7486 var log = time.replace(/GMT.*/, "") + " " + what + " " + dcb + " " + db + " " + dcbtime + " " + dbtime;
7488 var data = localStorage.getItem(opts.localStorage.timekeeperLogs);
7489 data = log + "\n" + data;
7490 localStorage.setItem(opts.localStorage.timekeeperLogs, data);
7491 $(opts.selectors.timekeeperLogsPre).html(data);
7495 var saveCurrent = -1;
7496 $(document).bind('deck.change', function(e, from, to) {
7497 log(from + " " + to);
7501 // Bind key event to add a marker in the logs
7502 var $d = $(document);
7503 var doBang = function() {
7504 log("BANG " + saveCurrent);
7505 $(opts.selectors.timekeeperBang).addClass(opts.classes.timekeeperNotification);
7506 setTimeout(function() {
7507 $(opts.selectors.timekeeperBang).removeClass(opts.classes.timekeeperNotification);
7508 }, opts.timekeeperNotificationPeriod);
7511 $d.unbind('keydown.logbang').bind('keydown.logbang', function(e) {
7512 if (e.ctrlKey) return;
7513 var K = opts.keys.timekeeper;
7514 if (e.which === K || $.inArray(e.which, K) > -1) {
7521 $(opts.selectors.timekeeperLogsToggle).unbind('click.timekeeper').bind('click.timekeeper', function(e) {
7522 $(opts.selectors.timekeeperLogs).toggleClass(opts.classes.timekeeperLogsVisible);
7527 var period = opts.timekeeperPeriod;
7528 setInterval(function() {
7529 var today = new Date();
7530 today.setMinutes(0);
7532 today.setSeconds(0);
7533 var now = new Date();
7534 $(opts.selectors.timekeeperTime).html(formatTime(now - today));
7535 var v = localStorage.getItem(opts.localStorage.timekeeperBase);
7537 var t = now - new Date(JSON.parse(v));
7538 var time = formatTime(t);
7539 $(opts.selectors.timekeeperRelativeTime).html(time);
7541 var v2 = localStorage.getItem(opts.localStorage.timekeeperLocalBase);
7543 var t = now - new Date(JSON.parse(v2));
7544 var time = formatTime(t);
7545 $(opts.selectors.timekeeperLocalRelativeTime).html(time);
7554 (function(global, document) {
7556 // Popcorn.js does not support archaic browsers
7557 if ( !document.addEventListener ) {
7562 var methods = ( "byId forEach extend effects error guid sizeOf isArray nop position disable enable destroy" +
7563 "addTrackEvent removeTrackEvent getTrackEvents getTrackEvent getLastTrackEventId " +
7564 "timeUpdate plugin removePlugin compose effect xhr getJSONP getScript" ).split(/\s+/);
7566 while ( methods.length ) {
7567 global.Popcorn[ methods.shift() ] = function() {};
7574 AP = Array.prototype,
7575 OP = Object.prototype,
7577 forEach = AP.forEach,
7579 hasOwn = OP.hasOwnProperty,
7580 toString = OP.toString,
7582 // Copy global Popcorn (may not exist)
7583 _Popcorn = global.Popcorn,
7590 // Non-public internal data object
7598 // Non-public `requestAnimFrame`
7599 // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
7600 requestAnimFrame = (function(){
7601 return global.requestAnimationFrame ||
7602 global.webkitRequestAnimationFrame ||
7603 global.mozRequestAnimationFrame ||
7604 global.oRequestAnimationFrame ||
7605 global.msRequestAnimationFrame ||
7606 function( callback, element ) {
7607 global.setTimeout( callback, 16 );
7611 // Non-public `getKeys`, return an object's keys as an array
7612 getKeys = function( obj ) {
7613 return Object.keys ? Object.keys( obj ) : (function( obj ) {
7617 for ( item in obj ) {
7618 if ( hasOwn.call( obj, item ) ) {
7627 // [[Put]] props from dictionary onto |this|
7628 // MUST BE CALLED FROM WITHIN A CONSTRUCTOR:
7629 // Abstract.put.call( this, dictionary );
7630 put: function( dictionary ) {
7631 // For each own property of src, let key be the property key
7632 // and desc be the property descriptor of the property.
7633 Object.getOwnPropertyNames( dictionary ).forEach(function( key ) {
7634 this[ key ] = dictionary[ key ];
7640 // Declare constructor
7641 // Returns an instance object.
7642 Popcorn = function( entity, options ) {
7643 // Return new Popcorn object
7644 return new Popcorn.p.init( entity, options || null );
7647 // Popcorn API version, automatically inserted via build system.
7648 Popcorn.version = "@VERSION";
7650 // Boolean flag allowing a client to determine if Popcorn can be supported
7651 Popcorn.isSupported = true;
7654 Popcorn.instances = [];
7656 // Declare a shortcut (Popcorn.p) to and a definition of
7657 // the new prototype for our Popcorn constructor
7658 Popcorn.p = Popcorn.prototype = {
7660 init: function( entity, options ) {
7662 var matches, nodeName,
7665 // Supports Popcorn(function () { /../ })
7666 // Originally proposed by Daniel Brooks
7668 if ( typeof entity === "function" ) {
7670 // If document ready has already fired
7671 if ( document.readyState === "complete" ) {
7673 entity( document, Popcorn );
7677 // Add `entity` fn to ready stack
7678 readyStack.push( entity );
7680 // This process should happen once per page load
7681 if ( !readyBound ) {
7683 // set readyBound flag
7686 var DOMContentLoaded = function() {
7690 // Remove global DOM ready listener
7691 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
7693 // Execute all ready function in the stack
7694 for ( var i = 0, readyStackLength = readyStack.length; i < readyStackLength; i++ ) {
7696 readyStack[ i ].call( document, Popcorn );
7703 // Register global DOM ready listener
7704 document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
7710 if ( typeof entity === "string" ) {
7712 matches = document.querySelector( entity );
7714 throw new Error( "Popcorn.js Error: Invalid media element selector: " + entity );
7718 // Get media element by id or object reference
7719 this.media = matches || entity;
7721 // inner reference to this media element's nodeName string value
7722 nodeName = ( this.media.nodeName && this.media.nodeName.toLowerCase() ) || "video";
7724 // Create an audio or video element property reference
7725 this[ nodeName ] = this.media;
7727 this.options = Popcorn.extend( {}, options ) || {};
7729 // Resolve custom ID or default prefixed ID
7730 this.id = this.options.id || Popcorn.guid( nodeName );
7732 // Throw if an attempt is made to use an ID that already exists
7733 if ( Popcorn.byId( this.id ) ) {
7734 throw new Error( "Popcorn.js Error: Cannot use duplicate ID (" + this.id + ")" );
7737 this.isDestroyed = false;
7741 // data structure of all
7746 // Executed by either timeupdate event or in rAF loop
7747 timeUpdate: Popcorn.nop,
7749 // Allows disabling a plugin per instance
7752 // Stores DOM event queues by type
7755 // Stores Special event hooks data
7758 // Store track event history data
7761 // Stores ad-hoc state related data]
7763 volume: this.media.volume
7766 // Store track event object references by trackId
7769 // Playback track event queues
7770 trackEvents: new TrackEvents( this )
7773 // Register new instance
7774 Popcorn.instances.push( this );
7776 // function to fire when video is ready
7777 var isReady = function() {
7779 // chrome bug: http://code.google.com/p/chromium/issues/detail?id=119598
7780 // it is possible the video's time is less than 0
7781 // this has the potential to call track events more than once, when they should not
7782 // start: 0, end: 1 will start, end, start again, when it should just start
7783 // just setting it to 0 if it is below 0 fixes this issue
7784 if ( self.media.currentTime < 0 ) {
7786 self.media.currentTime = 0;
7789 self.media.removeEventListener( "loadedmetadata", isReady, false );
7791 var duration, videoDurationPlus,
7792 runningPlugins, runningPlugin, rpLength, rpNatives;
7794 // Adding padding to the front and end of the arrays
7795 // this is so we do not fall off either end
7796 duration = self.media.duration;
7798 // Check for no duration info (NaN)
7799 videoDurationPlus = duration != duration ? Number.MAX_VALUE : duration + 1;
7801 Popcorn.addTrackEvent( self, {
7802 start: videoDurationPlus,
7803 end: videoDurationPlus
7806 if ( !self.isDestroyed ) {
7807 self.data.durationChange = function() {
7808 var newDuration = self.media.duration,
7809 newDurationPlus = newDuration + 1,
7810 byStart = self.data.trackEvents.byStart,
7811 byEnd = self.data.trackEvents.byEnd;
7813 // Remove old padding events
7817 // Remove any internal tracking of events that have end times greater than duration
7818 // otherwise their end events will never be hit.
7819 for ( var k = byEnd.length - 1; k > 0; k-- ) {
7820 if ( byEnd[ k ].end > newDuration ) {
7821 self.removeTrackEvent( byEnd[ k ]._id );
7825 // Remove any internal tracking of events that have end times greater than duration
7826 // otherwise their end events will never be hit.
7827 for ( var i = 0; i < byStart.length; i++ ) {
7828 if ( byStart[ i ].end > newDuration ) {
7829 self.removeTrackEvent( byStart[ i ]._id );
7833 // References to byEnd/byStart are reset, so accessing it this way is
7835 self.data.trackEvents.byEnd.push({
7836 start: newDurationPlus,
7837 end: newDurationPlus
7840 self.data.trackEvents.byStart.push({
7841 start: newDurationPlus,
7842 end: newDurationPlus
7846 // Listen for duration changes and adjust internal tracking of event timings
7847 self.media.addEventListener( "durationchange", self.data.durationChange, false );
7850 if ( self.options.frameAnimation ) {
7852 // if Popcorn is created with frameAnimation option set to true,
7853 // requestAnimFrame is used instead of "timeupdate" media event.
7854 // This is for greater frame time accuracy, theoretically up to
7855 // 60 frames per second as opposed to ~4 ( ~every 15-250ms)
7856 self.data.timeUpdate = function () {
7858 Popcorn.timeUpdate( self, {} );
7860 // fire frame for each enabled active plugin of every type
7861 Popcorn.forEach( Popcorn.manifest, function( key, val ) {
7863 runningPlugins = self.data.running[ val ];
7865 // ensure there are running plugins on this type on this instance
7866 if ( runningPlugins ) {
7868 rpLength = runningPlugins.length;
7869 for ( var i = 0; i < rpLength; i++ ) {
7871 runningPlugin = runningPlugins[ i ];
7872 rpNatives = runningPlugin._natives;
7873 rpNatives && rpNatives.frame &&
7874 rpNatives.frame.call( self, {}, runningPlugin, self.currentTime() );
7879 self.emit( "timeupdate" );
7881 !self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
7884 !self.isDestroyed && requestAnimFrame( self.data.timeUpdate );
7888 self.data.timeUpdate = function( event ) {
7889 Popcorn.timeUpdate( self, event );
7892 if ( !self.isDestroyed ) {
7893 self.media.addEventListener( "timeupdate", self.data.timeUpdate, false );
7898 Object.defineProperty( this, "error", {
7901 return self.media.error;
7905 // http://www.whatwg.org/specs/web-apps/current-work/#dom-media-readystate
7907 // If media is in readyState (rS) >= 1, we know the media's duration,
7908 // which is required before running the isReady function.
7909 // If rS is 0, attach a listener for "loadedmetadata",
7910 // ( Which indicates that the media has moved from rS 0 to 1 )
7912 // This has been changed from a check for rS 2 because
7913 // in certain conditions, Firefox can enter this code after dropping
7914 // to rS 1 from a higher state such as 2 or 3. This caused a "loadeddata"
7915 // listener to be attached to the media object, an event that had
7916 // already triggered and would not trigger again. This left Popcorn with an
7917 // instance that could never start a timeUpdate loop.
7918 if ( self.media.readyState >= 1 ) {
7923 self.media.addEventListener( "loadedmetadata", isReady, false );
7930 // Extend constructor prototype to instance prototype
7931 // Allows chaining methods to instances
7932 Popcorn.p.init.prototype = Popcorn.p;
7934 Popcorn.byId = function( str ) {
7935 var instances = Popcorn.instances,
7936 length = instances.length,
7939 for ( ; i < length; i++ ) {
7940 if ( instances[ i ].id === str ) {
7941 return instances[ i ];
7948 Popcorn.forEach = function( obj, fn, context ) {
7950 if ( !obj || !fn ) {
7954 context = context || this;
7958 // Use native whenever possible
7959 if ( forEach && obj.forEach === forEach ) {
7960 return obj.forEach( fn, context );
7963 if ( toString.call( obj ) === "[object NodeList]" ) {
7964 for ( key = 0, len = obj.length; key < len; key++ ) {
7965 fn.call( context, obj[ key ], key, obj );
7970 for ( key in obj ) {
7971 if ( hasOwn.call( obj, key ) ) {
7972 fn.call( context, obj[ key ], key, obj );
7978 Popcorn.extend = function( obj ) {
7979 var dest = obj, src = slice.call( arguments, 1 );
7981 Popcorn.forEach( src, function( copy ) {
7982 for ( var prop in copy ) {
7983 dest[ prop ] = copy[ prop ];
7991 // A Few reusable utils, memoized onto Popcorn
7992 Popcorn.extend( Popcorn, {
7993 noConflict: function( deep ) {
7996 global.Popcorn = _Popcorn;
8001 error: function( msg ) {
8002 throw new Error( msg );
8004 guid: function( prefix ) {
8005 Popcorn.guid.counter++;
8006 return ( prefix ? prefix : "" ) + ( +new Date() + Popcorn.guid.counter );
8008 sizeOf: function( obj ) {
8011 for ( var prop in obj ) {
8017 isArray: Array.isArray || function( array ) {
8018 return toString.call( array ) === "[object Array]";
8023 position: function( elem ) {
8025 if ( !elem.parentNode ) {
8029 var clientRect = elem.getBoundingClientRect(),
8031 doc = elem.ownerDocument,
8032 docElem = document.documentElement,
8033 body = document.body,
8034 clientTop, clientLeft, scrollTop, scrollLeft, top, left;
8036 // Determine correct clientTop/Left
8037 clientTop = docElem.clientTop || body.clientTop || 0;
8038 clientLeft = docElem.clientLeft || body.clientLeft || 0;
8040 // Determine correct scrollTop/Left
8041 scrollTop = ( global.pageYOffset && docElem.scrollTop || body.scrollTop );
8042 scrollLeft = ( global.pageXOffset && docElem.scrollLeft || body.scrollLeft );
8045 top = Math.ceil( clientRect.top + scrollTop - clientTop );
8046 left = Math.ceil( clientRect.left + scrollLeft - clientLeft );
8048 for ( var p in clientRect ) {
8049 bounds[ p ] = Math.round( clientRect[ p ] );
8052 return Popcorn.extend({}, bounds, { top: top, left: left });
8055 disable: function( instance, plugin ) {
8057 if ( instance.data.disabled[ plugin ] ) {
8061 instance.data.disabled[ plugin ] = true;
8063 if ( plugin in Popcorn.registryByName &&
8064 instance.data.running[ plugin ] ) {
8066 for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) {
8068 event = instance.data.running[ plugin ][ i ];
8069 event._natives.end.call( instance, null, event );
8071 instance.emit( "trackend",
8072 Popcorn.extend({}, event, {
8082 enable: function( instance, plugin ) {
8084 if ( !instance.data.disabled[ plugin ] ) {
8088 instance.data.disabled[ plugin ] = false;
8090 if ( plugin in Popcorn.registryByName &&
8091 instance.data.running[ plugin ] ) {
8093 for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) {
8095 event = instance.data.running[ plugin ][ i ];
8096 event._natives.start.call( instance, null, event );
8098 instance.emit( "trackstart",
8099 Popcorn.extend({}, event, {
8110 destroy: function( instance ) {
8111 var events = instance.data.events,
8112 trackEvents = instance.data.trackEvents,
8113 singleEvent, item, fn, plugin;
8115 // Iterate through all events and remove them
8116 for ( item in events ) {
8117 singleEvent = events[ item ];
8118 for ( fn in singleEvent ) {
8119 delete singleEvent[ fn ];
8121 events[ item ] = null;
8124 // remove all plugins off the given instance
8125 for ( plugin in Popcorn.registryByName ) {
8126 Popcorn.removePlugin( instance, plugin );
8129 // Remove all data.trackEvents #1178
8130 trackEvents.byStart.length = 0;
8131 trackEvents.byEnd.length = 0;
8133 if ( !instance.isDestroyed ) {
8134 instance.data.timeUpdate && instance.media.removeEventListener( "timeupdate", instance.data.timeUpdate, false );
8135 instance.isDestroyed = true;
8138 Popcorn.instances.splice( Popcorn.instances.indexOf( instance ), 1 );
8142 // Memoized GUID Counter
8143 Popcorn.guid.counter = 1;
8145 // Factory to implement getters, setters and controllers
8146 // as Popcorn instance methods. The IIFE will create and return
8147 // an object with defined methods
8148 Popcorn.extend(Popcorn.p, (function() {
8150 var methods = "load play pause currentTime playbackRate volume duration preload playbackRate " +
8151 "autoplay loop controls muted buffered readyState seeking paused played seekable ended",
8155 // Build methods, store in object that is returned and passed to extend
8156 Popcorn.forEach( methods.split( /\s+/g ), function( name ) {
8158 ret[ name ] = function( arg ) {
8161 if ( typeof this.media[ name ] === "function" ) {
8163 // Support for shorthanded play(n)/pause(n) jump to currentTime
8164 // If arg is not null or undefined and called by one of the
8165 // allowed shorthandable methods, then set the currentTime
8166 // Supports time as seconds or SMPTE
8167 if ( arg != null && /play|pause/.test( name ) ) {
8168 this.media.currentTime = Popcorn.util.toSeconds( arg );
8171 this.media[ name ]();
8176 if ( arg != null ) {
8177 // Capture the current value of the attribute property
8178 previous = this.media[ name ];
8180 // Set the attribute property with the new value
8181 this.media[ name ] = arg;
8183 // If the new value is not the same as the old value
8184 // emit an "attrchanged event"
8185 if ( previous !== arg ) {
8186 this.emit( "attrchange", {
8188 previousValue: previous,
8195 return this.media[ name ];
8204 Popcorn.forEach( "enable disable".split(" "), function( method ) {
8205 Popcorn.p[ method ] = function( plugin ) {
8206 return Popcorn[ method ]( this, plugin );
8210 Popcorn.extend(Popcorn.p, {
8212 // Rounded currentTime
8213 roundTime: function() {
8214 return Math.round( this.media.currentTime );
8217 // Attach an event to a single point in time
8218 exec: function( id, time, fn ) {
8219 var length = arguments.length,
8220 eventType = "trackadded",
8221 trackEvent, sec, options;
8223 // Check if first could possibly be a SMPTE string
8224 // p.cue( "smpte string", fn );
8225 // try/catch avoid awful throw in Popcorn.util.toSeconds
8226 // TODO: Get rid of that, replace with NaN return?
8228 sec = Popcorn.util.toSeconds( id );
8231 // If it can be converted into a number then
8232 // it's safe to assume that the string was SMPTE
8233 if ( typeof sec === "number" ) {
8237 // Shift arguments based on use case
8240 // p.cue( time, fn );
8241 if ( typeof id === "number" && length === 2 ) {
8244 id = Popcorn.guid( "cue" );
8246 // Support for new forms
8248 // p.cue( "empty-cue" );
8249 if ( length === 1 ) {
8250 // Set a time for an empty cue. It's not important what
8251 // the time actually is, because the cue is a no-op
8256 // Get the TrackEvent that matches the given id.
8257 trackEvent = this.getTrackEvent( id );
8261 // remove existing cue so a new one can be added via trackEvents.add
8262 this.data.trackEvents.remove( id );
8263 TrackEvent.end( this, trackEvent );
8264 // Update track event references
8265 Popcorn.removeTrackEvent.ref( this, id );
8267 eventType = "cuechange";
8269 // p.cue( "my-id", 12 );
8270 // p.cue( "my-id", function() { ... });
8271 if ( typeof id === "string" && length === 2 ) {
8273 // p.cue( "my-id", 12 );
8274 // The path will update the cue time.
8275 if ( typeof time === "number" ) {
8276 // Re-use existing TrackEvent start callback
8277 fn = trackEvent._natives.start;
8280 // p.cue( "my-id", function() { ... });
8281 // The path will update the cue function
8282 if ( typeof time === "function" ) {
8284 // Re-use existing TrackEvent start time
8285 time = trackEvent.start;
8290 if ( length >= 2 ) {
8292 // p.cue( "a", "00:00:00");
8293 if ( typeof time === "string" ) {
8295 sec = Popcorn.util.toSeconds( time );
8301 // p.cue( "b", 11 );
8302 // p.cue( "b", 11, function() {} );
8303 if ( typeof time === "number" ) {
8304 fn = fn || Popcorn.nop();
8307 // p.cue( "c", function() {});
8308 if ( typeof time === "function" ) {
8323 start: fn || Popcorn.nop,
8330 options = Popcorn.extend( trackEvent, options );
8333 if ( eventType === "cuechange" ) {
8335 // Supports user defined track event id
8336 options._id = options.id || options._id || Popcorn.guid( options._natives.type );
8338 this.data.trackEvents.add( options );
8339 TrackEvent.start( this, options );
8341 this.timeUpdate( this, null, true );
8343 // Store references to user added trackevents in ref table
8344 Popcorn.addTrackEvent.ref( this, options );
8346 this.emit( eventType, Popcorn.extend({}, options, {
8350 time: trackEvent.start,
8351 fn: trackEvent._natives.start
8355 fn: fn || Popcorn.nop
8360 // Creating a one second track event with an empty end
8361 Popcorn.addTrackEvent( this, options );
8367 // Mute the calling media, optionally toggle
8368 mute: function( toggle ) {
8370 var event = toggle == null || toggle === true ? "muted" : "unmuted";
8372 // If `toggle` is explicitly `false`,
8373 // unmute the media and restore the volume level
8374 if ( event === "unmuted" ) {
8375 this.media.muted = false;
8376 this.media.volume = this.data.state.volume;
8379 // If `toggle` is either null or undefined,
8380 // save the current volume and mute the media element
8381 if ( event === "muted" ) {
8382 this.data.state.volume = this.media.volume;
8383 this.media.muted = true;
8386 // Trigger either muted|unmuted event
8392 // Convenience method, unmute the calling media
8393 unmute: function( toggle ) {
8395 return this.mute( toggle == null ? false : !toggle );
8398 // Get the client bounding box of an instance element
8399 position: function() {
8400 return Popcorn.position( this.media );
8403 // Toggle a plugin's playback behaviour (on or off) per instance
8404 toggle: function( plugin ) {
8405 return Popcorn[ this.data.disabled[ plugin ] ? "enable" : "disable" ]( this, plugin );
8408 // Set default values for plugin options objects per instance
8409 defaults: function( plugin, defaults ) {
8411 // If an array of default configurations is provided,
8412 // iterate and apply each to this instance
8413 if ( Popcorn.isArray( plugin ) ) {
8415 Popcorn.forEach( plugin, function( obj ) {
8416 for ( var name in obj ) {
8417 this.defaults( name, obj[ name ] );
8424 if ( !this.options.defaults ) {
8425 this.options.defaults = {};
8428 if ( !this.options.defaults[ plugin ] ) {
8429 this.options.defaults[ plugin ] = {};
8432 Popcorn.extend( this.options.defaults[ plugin ], defaults );
8439 UIEvents: "blur focus focusin focusout load resize scroll unload",
8440 MouseEvents: "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave click dblclick",
8441 Events: "loadstart progress suspend emptied stalled play pause error " +
8442 "loadedmetadata loadeddata waiting playing canplay canplaythrough " +
8443 "seeking seeked timeupdate ended ratechange durationchange volumechange"
8446 Popcorn.Events.Natives = Popcorn.Events.UIEvents + " " +
8447 Popcorn.Events.MouseEvents + " " +
8448 Popcorn.Events.Events;
8450 internal.events.apiTypes = [ "UIEvents", "MouseEvents", "Events" ];
8452 // Privately compile events table at load time
8453 (function( events, data ) {
8455 var apis = internal.events.apiTypes,
8456 eventsList = events.Natives.split( /\s+/g ),
8457 idx = 0, len = eventsList.length, prop;
8459 for( ; idx < len; idx++ ) {
8460 data.hash[ eventsList[idx] ] = true;
8463 apis.forEach(function( val, idx ) {
8465 data.apis[ val ] = {};
8467 var apiEvents = events[ val ].split( /\s+/g ),
8468 len = apiEvents.length,
8471 for ( ; k < len; k++ ) {
8472 data.apis[ val ][ apiEvents[ k ] ] = true;
8475 })( Popcorn.Events, internal.events );
8479 isNative: function( type ) {
8480 return !!internal.events.hash[ type ];
8482 getInterface: function( type ) {
8484 if ( !Popcorn.events.isNative( type ) ) {
8488 var eventApi = internal.events,
8489 apis = eventApi.apiTypes,
8490 apihash = eventApi.apis,
8491 idx = 0, len = apis.length, api, tmp;
8493 for ( ; idx < len; idx++ ) {
8496 if ( apihash[ tmp ][ type ] ) {
8503 // Compile all native events to single array
8504 all: Popcorn.Events.Natives.split( /\s+/g ),
8505 // Defines all Event handling static functions
8507 trigger: function( type, data ) {
8508 var eventInterface, evt, clonedEvents,
8509 events = this.data.events[ type ];
8511 // setup checks for custom event system
8513 eventInterface = Popcorn.events.getInterface( type );
8515 if ( eventInterface ) {
8516 evt = document.createEvent( eventInterface );
8517 evt.initEvent( type, true, true, global, 1 );
8519 this.media.dispatchEvent( evt );
8524 // clone events in case callbacks remove callbacks themselves
8525 clonedEvents = events.slice();
8527 // iterate through all callbacks
8528 while ( clonedEvents.length ) {
8529 clonedEvents.shift().call( this, data );
8535 listen: function( type, fn ) {
8538 eventHook = Popcorn.events.hooks[ type ],
8543 if ( typeof fn !== "function" ) {
8544 throw new Error( "Popcorn.js Error: Listener is not a function" );
8547 // Setup event registry entry
8548 if ( !this.data.events[ type ] ) {
8549 this.data.events[ type ] = [];
8550 // Toggle if the previous assumption was untrue
8554 // Check and setup event hooks
8556 // Execute hook add method if defined
8557 if ( eventHook.add ) {
8558 eventHook.add.call( this, {}, fn );
8561 // Reassign event type to our piggyback event type if defined
8562 if ( eventHook.bind ) {
8563 type = eventHook.bind;
8566 // Reassign handler if defined
8567 if ( eventHook.handler ) {
8570 fn = function wrapper( event ) {
8571 eventHook.handler.call( self, event, tmp );
8575 // assume the piggy back event is registered
8578 // Setup event registry entry
8579 if ( !this.data.events[ type ] ) {
8580 this.data.events[ type ] = [];
8581 // Toggle if the previous assumption was untrue
8586 // Register event and handler
8587 this.data.events[ type ].push( fn );
8589 // only attach one event of any type
8590 if ( !hasEvents && Popcorn.events.all.indexOf( type ) > -1 ) {
8591 this.media.addEventListener( type, function( event ) {
8592 if ( self.data.events[ type ] ) {
8593 // clone events in case callbacks remove callbacks themselves
8594 clonedEvents = self.data.events[ type ].slice();
8596 // iterate through all callbacks
8597 while ( clonedEvents.length ) {
8598 clonedEvents.shift().call( self, event );
8605 unlisten: function( type, fn ) {
8607 events = this.data.events[ type ];
8610 return; // no listeners = nothing to do
8613 if ( typeof fn === "string" ) {
8614 // legacy support for string-based removal -- not recommended
8615 for ( var i = 0; i < events.length; i++ ) {
8616 if ( events[ i ].name === fn ) {
8617 // decrement i because array length just got smaller
8618 events.splice( i--, 1 );
8623 } else if ( typeof fn === "function" ) {
8624 while( ind !== -1 ) {
8625 ind = events.indexOf( fn );
8627 events.splice( ind, 1 );
8634 // if we got to this point, we are deleting all functions of this type
8635 this.data.events[ type ] = null;
8642 bind: "canplaythrough",
8643 add: function( event, callback ) {
8647 if ( this.media.readyState ) {
8649 // always call canplayall asynchronously
8650 setTimeout(function() {
8651 callback.call( this, event );
8657 this.data.hooks.canplayall = {
8661 // declare special handling instructions
8662 handler: function canplayall( event, callback ) {
8664 if ( !this.data.hooks.canplayall.fired ) {
8665 // trigger original user callback once
8666 callback.call( this, event );
8668 this.data.hooks.canplayall.fired = true;
8675 // Extend Popcorn.events.fns (listen, unlisten, trigger) to all Popcorn instances
8676 // Extend aliases (on, off, emit)
8677 Popcorn.forEach( [ [ "trigger", "emit" ], [ "listen", "on" ], [ "unlisten", "off" ] ], function( key ) {
8678 Popcorn.p[ key[ 0 ] ] = Popcorn.p[ key[ 1 ] ] = Popcorn.events.fn[ key[ 0 ] ];
8681 // Internal Only - construct simple "TrackEvent"
8682 // data type objects
8683 function TrackEvent( track ) {
8684 Abstract.put.call( this, track );
8687 // Determine if a TrackEvent's "start" and "trackstart" must be called.
8688 TrackEvent.start = function( instance, track ) {
8690 if ( track.end > instance.media.currentTime &&
8691 track.start <= instance.media.currentTime && !track._running ) {
8693 track._running = true;
8694 instance.data.running[ track._natives.type ].push( track );
8696 if ( !instance.data.disabled[ track._natives.type ] ) {
8698 track._natives.start.call( instance, null, track );
8700 instance.emit( "trackstart",
8701 Popcorn.extend( {}, track, {
8702 plugin: track._natives.type,
8711 // Determine if a TrackEvent's "end" and "trackend" must be called.
8712 TrackEvent.end = function( instance, track ) {
8716 if ( ( track.end <= instance.media.currentTime ||
8717 track.start > instance.media.currentTime ) && track._running ) {
8719 runningPlugins = instance.data.running[ track._natives.type ];
8721 track._running = false;
8722 runningPlugins.splice( runningPlugins.indexOf( track ), 1 );
8724 if ( !instance.data.disabled[ track._natives.type ] ) {
8726 track._natives.end.call( instance, null, track );
8728 instance.emit( "trackend",
8729 Popcorn.extend( {}, track, {
8730 plugin: track._natives.type,
8739 // Internal Only - construct "TrackEvents"
8740 // data type objects that are used by the Popcorn
8741 // instance, stored at p.data.trackEvents
8742 function TrackEvents( parent ) {
8743 this.parent = parent;
8754 this.animating = [];
8755 this.startIndex = 0;
8757 this.previousUpdateTime = -1;
8759 Object.defineProperty( this, "count", {
8761 return this.byStart.length;
8766 function isMatch( obj, key, value ) {
8767 return obj[ key ] && obj[ key ] === value;
8770 TrackEvents.prototype.where = function( params ) {
8771 return ( this.parent.getTrackEvents() || [] ).filter(function( event ) {
8774 // If no explicit params, match all TrackEvents
8779 // Filter keys in params against both the top level properties
8780 // and the _natives properties
8781 for ( key in params ) {
8782 value = params[ key ];
8783 if ( isMatch( event, key, value ) || isMatch( event._natives, key, value ) ) {
8791 TrackEvents.prototype.add = function( track ) {
8793 // Store this definition in an array sorted by times
8794 var byStart = this.byStart,
8796 startIndex, endIndex;
8798 // Push track event ids into the history
8799 if ( track && track._id ) {
8800 this.parent.data.history.push( track._id );
8803 track.start = Popcorn.util.toSeconds( track.start, this.parent.options.framerate );
8804 track.end = Popcorn.util.toSeconds( track.end, this.parent.options.framerate );
8806 for ( startIndex = byStart.length - 1; startIndex >= 0; startIndex-- ) {
8808 if ( track.start >= byStart[ startIndex ].start ) {
8809 byStart.splice( startIndex + 1, 0, track );
8814 for ( endIndex = byEnd.length - 1; endIndex >= 0; endIndex-- ) {
8816 if ( track.end > byEnd[ endIndex ].end ) {
8817 byEnd.splice( endIndex + 1, 0, track );
8822 // update startIndex and endIndex
8823 if ( startIndex <= this.parent.data.trackEvents.startIndex &&
8824 track.start <= this.parent.data.trackEvents.previousUpdateTime ) {
8826 this.parent.data.trackEvents.startIndex++;
8829 if ( endIndex <= this.parent.data.trackEvents.endIndex &&
8830 track.end < this.parent.data.trackEvents.previousUpdateTime ) {
8832 this.parent.data.trackEvents.endIndex++;
8837 TrackEvents.prototype.remove = function( removeId, state ) {
8839 if ( removeId instanceof TrackEvent ) {
8840 removeId = removeId.id;
8843 if ( typeof removeId === "object" ) {
8844 // Filter by key=val and remove all matching TrackEvents
8845 this.where( removeId ).forEach(function( event ) {
8846 // |this| refers to the calling Popcorn "parent" instance
8847 this.removeTrackEvent( event._id );
8853 var start, end, animate, historyLen, track,
8854 length = this.byStart.length,
8863 state = state || {};
8865 while ( --length > -1 ) {
8866 start = this.byStart[ index ];
8867 end = this.byEnd[ index ];
8869 // Padding events will not have _id properties.
8870 // These should be safely pushed onto the front and back of the
8871 // track event array
8873 byStart.push( start );
8877 // Filter for user track events (vs system track events)
8880 // If not a matching start event for removal
8881 if ( start._id !== removeId ) {
8882 byStart.push( start );
8885 // If not a matching end event for removal
8886 if ( end._id !== removeId ) {
8890 // If the _id is matched, capture the current index
8891 if ( start._id === removeId ) {
8894 // cache the track event being removed
8898 // Increment the track index
8902 // Reset length to be used by the condition below to determine
8903 // if animating track events should also be filtered for removal.
8904 // Reset index below to be used by the reverse while as an
8905 // incrementing counter
8906 length = this.animating.length;
8910 while ( --length > -1 ) {
8911 animate = this.animating[ index ];
8913 // Padding events will not have _id properties.
8914 // These should be safely pushed onto the front and back of the
8915 // track event array
8916 if ( !animate._id ) {
8917 animating.push( animate );
8920 // If not a matching animate event for removal
8921 if ( animate._id && animate._id !== removeId ) {
8922 animating.push( animate );
8924 // Increment the track index
8930 if ( indexWasAt <= this.startIndex ) {
8934 if ( indexWasAt <= this.endIndex ) {
8938 this.byStart = byStart;
8940 this.animating = animating;
8942 historyLen = this.parent.data.history.length;
8944 for ( var i = 0; i < historyLen; i++ ) {
8945 if ( this.parent.data.history[ i ] !== removeId ) {
8946 history.push( this.parent.data.history[ i ] );
8950 // Update ordered history array
8951 this.parent.data.history = history;
8955 // Helper function used to retrieve old values of properties that
8956 // are provided for update.
8957 function getPreviousProperties( oldOptions, newOptions ) {
8958 var matchProps = {};
8960 for ( var prop in oldOptions ) {
8961 if ( hasOwn.call( newOptions, prop ) && hasOwn.call( oldOptions, prop ) ) {
8962 matchProps[ prop ] = oldOptions[ prop ];
8969 // Internal Only - Adds track events to the instance object
8970 Popcorn.addTrackEvent = function( obj, track ) {
8973 if ( track instanceof TrackEvent ) {
8977 track = new TrackEvent( track );
8979 // Determine if this track has default options set for it
8980 // If so, apply them to the track object
8981 if ( track && track._natives && track._natives.type &&
8982 ( obj.options.defaults && obj.options.defaults[ track._natives.type ] ) ) {
8984 // To ensure that the TrackEvent Invariant Policy is enforced,
8985 // First, copy the properties of the newly created track event event
8986 // to a temporary holder
8987 temp = Popcorn.extend( {}, track );
8989 // Next, copy the default onto the newly created trackevent, followed by the
8990 // temporary holder.
8991 Popcorn.extend( track, obj.options.defaults[ track._natives.type ], temp );
8994 if ( track._natives ) {
8995 // Supports user defined track event id
8996 track._id = track.id || track._id || Popcorn.guid( track._natives.type );
8998 // Trigger _setup method if exists
8999 if ( track._natives._setup ) {
9001 track._natives._setup.call( obj, track );
9003 obj.emit( "tracksetup", Popcorn.extend( {}, track, {
9004 plugin: track._natives.type,
9011 obj.data.trackEvents.add( track );
9012 TrackEvent.start( obj, track );
9014 this.timeUpdate( obj, null, true );
9016 // Store references to user added trackevents in ref table
9018 Popcorn.addTrackEvent.ref( obj, track );
9021 obj.emit( "trackadded", Popcorn.extend({}, track,
9022 track._natives ? { plugin: track._natives.type } : {}, {
9028 // Internal Only - Adds track event references to the instance object's trackRefs hash table
9029 Popcorn.addTrackEvent.ref = function( obj, track ) {
9030 obj.data.trackRefs[ track._id ] = track;
9035 Popcorn.removeTrackEvent = function( obj, removeId ) {
9036 var track = obj.getTrackEvent( removeId );
9042 // If a _teardown function was defined,
9043 // enforce for track event removals
9044 if ( track._natives._teardown ) {
9045 track._natives._teardown.call( obj, track );
9048 obj.data.trackEvents.remove( removeId );
9050 // Update track event references
9051 Popcorn.removeTrackEvent.ref( obj, removeId );
9053 if ( track._natives ) {
9055 // Fire a trackremoved event
9056 obj.emit( "trackremoved", Popcorn.extend({}, track, {
9057 plugin: track._natives.type,
9058 type: "trackremoved",
9064 // Internal Only - Removes track event references from instance object's trackRefs hash table
9065 Popcorn.removeTrackEvent.ref = function( obj, removeId ) {
9066 delete obj.data.trackRefs[ removeId ];
9071 // Return an array of track events bound to this instance object
9072 Popcorn.getTrackEvents = function( obj ) {
9074 var trackevents = [],
9075 refs = obj.data.trackEvents.byStart,
9076 length = refs.length,
9080 for ( ; idx < length; idx++ ) {
9082 // Return only user attributed track event references
9084 trackevents.push( ref );
9091 // Internal Only - Returns an instance object's trackRefs hash table
9092 Popcorn.getTrackEvents.ref = function( obj ) {
9093 return obj.data.trackRefs;
9096 // Return a single track event bound to this instance object
9097 Popcorn.getTrackEvent = function( obj, trackId ) {
9098 return obj.data.trackRefs[ trackId ];
9101 // Internal Only - Returns an instance object's track reference by track id
9102 Popcorn.getTrackEvent.ref = function( obj, trackId ) {
9103 return obj.data.trackRefs[ trackId ];
9106 Popcorn.getLastTrackEventId = function( obj ) {
9107 return obj.data.history[ obj.data.history.length - 1 ];
9110 Popcorn.timeUpdate = function( obj, event ) {
9111 var currentTime = obj.media.currentTime,
9112 previousTime = obj.data.trackEvents.previousUpdateTime,
9113 tracks = obj.data.trackEvents,
9114 end = tracks.endIndex,
9115 start = tracks.startIndex,
9116 byStartLen = tracks.byStart.length,
9117 byEndLen = tracks.byEnd.length,
9118 registryByName = Popcorn.registryByName,
9119 trackstart = "trackstart",
9120 trackend = "trackend",
9122 byEnd, byStart, byAnimate, natives, type, runningPlugins;
9124 // Playbar advancing
9125 if ( previousTime <= currentTime ) {
9127 while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end <= currentTime ) {
9129 byEnd = tracks.byEnd[ end ];
9130 natives = byEnd._natives;
9131 type = natives && natives.type;
9133 // If plugin does not exist on this instance, remove it
9135 ( !!registryByName[ type ] ||
9138 if ( byEnd._running === true ) {
9140 byEnd._running = false;
9141 runningPlugins = obj.data.running[ type ];
9142 runningPlugins.splice( runningPlugins.indexOf( byEnd ), 1 );
9144 if ( !obj.data.disabled[ type ] ) {
9146 natives.end.call( obj, event, byEnd );
9149 Popcorn.extend({}, byEnd, {
9160 // remove track event
9161 Popcorn.removeTrackEvent( obj, byEnd._id );
9166 while ( tracks.byStart[ start ] && tracks.byStart[ start ].start <= currentTime ) {
9168 byStart = tracks.byStart[ start ];
9169 natives = byStart._natives;
9170 type = natives && natives.type;
9171 // If plugin does not exist on this instance, remove it
9173 ( !!registryByName[ type ] ||
9175 if ( byStart.end > currentTime &&
9176 byStart._running === false ) {
9178 byStart._running = true;
9179 obj.data.running[ type ].push( byStart );
9181 if ( !obj.data.disabled[ type ] ) {
9183 natives.start.call( obj, event, byStart );
9185 obj.emit( trackstart,
9186 Popcorn.extend({}, byStart, {
9196 // remove track event
9197 Popcorn.removeTrackEvent( obj, byStart._id );
9203 } else if ( previousTime > currentTime ) {
9205 while ( tracks.byStart[ start ] && tracks.byStart[ start ].start > currentTime ) {
9207 byStart = tracks.byStart[ start ];
9208 natives = byStart._natives;
9209 type = natives && natives.type;
9211 // if plugin does not exist on this instance, remove it
9213 ( !!registryByName[ type ] ||
9216 if ( byStart._running === true ) {
9218 byStart._running = false;
9219 runningPlugins = obj.data.running[ type ];
9220 runningPlugins.splice( runningPlugins.indexOf( byStart ), 1 );
9222 if ( !obj.data.disabled[ type ] ) {
9224 natives.end.call( obj, event, byStart );
9227 Popcorn.extend({}, byStart, {
9237 // remove track event
9238 Popcorn.removeTrackEvent( obj, byStart._id );
9243 while ( tracks.byEnd[ end ] && tracks.byEnd[ end ].end > currentTime ) {
9245 byEnd = tracks.byEnd[ end ];
9246 natives = byEnd._natives;
9247 type = natives && natives.type;
9249 // if plugin does not exist on this instance, remove it
9251 ( !!registryByName[ type ] ||
9254 if ( byEnd.start <= currentTime &&
9255 byEnd._running === false ) {
9257 byEnd._running = true;
9258 obj.data.running[ type ].push( byEnd );
9260 if ( !obj.data.disabled[ type ] ) {
9262 natives.start.call( obj, event, byEnd );
9264 obj.emit( trackstart,
9265 Popcorn.extend({}, byEnd, {
9275 // remove track event
9276 Popcorn.removeTrackEvent( obj, byEnd._id );
9282 tracks.endIndex = end;
9283 tracks.startIndex = start;
9284 tracks.previousUpdateTime = currentTime;
9286 //enforce index integrity if trackRemoved
9287 tracks.byStart.length < byStartLen && tracks.startIndex--;
9288 tracks.byEnd.length < byEndLen && tracks.endIndex--;
9292 // Map and Extend TrackEvent functions to all Popcorn instances
9293 Popcorn.extend( Popcorn.p, {
9295 getTrackEvents: function() {
9296 return Popcorn.getTrackEvents.call( null, this );
9299 getTrackEvent: function( id ) {
9300 return Popcorn.getTrackEvent.call( null, this, id );
9303 getLastTrackEventId: function() {
9304 return Popcorn.getLastTrackEventId.call( null, this );
9307 removeTrackEvent: function( id ) {
9309 Popcorn.removeTrackEvent.call( null, this, id );
9313 removePlugin: function( name ) {
9314 Popcorn.removePlugin.call( null, this, name );
9318 timeUpdate: function( event ) {
9319 Popcorn.timeUpdate.call( null, this, event );
9323 destroy: function() {
9324 Popcorn.destroy.call( null, this );
9330 Popcorn.manifest = {};
9331 // Plugins are registered
9332 Popcorn.registry = [];
9333 Popcorn.registryByName = {};
9334 // An interface for extending Popcorn
9335 // with plugin functionality
9336 Popcorn.plugin = function( name, definition, manifest ) {
9338 if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
9339 Popcorn.error( "'" + name + "' is a protected function name" );
9343 // Provides some sugar, but ultimately extends
9344 // the definition into Popcorn.p
9345 var isfn = typeof definition === "function",
9346 blacklist = [ "start", "end", "type", "manifest" ],
9347 methods = [ "_setup", "_teardown", "start", "end", "frame" ],
9351 // combines calls of two function calls into one
9352 var combineFn = function( first, second ) {
9354 first = first || Popcorn.nop;
9355 second = second || Popcorn.nop;
9358 first.apply( this, arguments );
9359 second.apply( this, arguments );
9363 // If `manifest` arg is undefined, check for manifest within the `definition` object
9364 // If no `definition.manifest`, an empty object is a sufficient fallback
9365 Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {};
9367 // apply safe, and empty default functions
9368 methods.forEach(function( method ) {
9369 definition[ method ] = safeTry( definition[ method ] || Popcorn.nop, name );
9372 var pluginFn = function( setup, options ) {
9378 // When the "ranges" property is set and its value is an array, short-circuit
9379 // the pluginFn definition to recall itself with an options object generated from
9380 // each range object in the ranges array. (eg. { start: 15, end: 16 } )
9381 if ( options.ranges && Popcorn.isArray(options.ranges) ) {
9382 Popcorn.forEach( options.ranges, function( range ) {
9383 // Create a fresh object, extend with current options
9384 // and start/end range object's properties
9385 // Works with in/out as well.
9386 var opts = Popcorn.extend( {}, options, range );
9388 // Remove the ranges property to prevent infinitely
9389 // entering this condition
9392 // Call the plugin with the newly created opts object
9393 this[ name ]( opts );
9396 // Return the Popcorn instance to avoid creating an empty track event
9400 // Storing the plugin natives
9401 var natives = options._natives = {},
9403 originalOpts, manifestOpts;
9405 Popcorn.extend( natives, setup );
9407 options._natives.type = options._natives.plugin = name;
9408 options._running = false;
9410 natives.start = natives.start || natives[ "in" ];
9411 natives.end = natives.end || natives[ "out" ];
9413 if ( options.once ) {
9414 natives.end = combineFn( natives.end, function() {
9415 this.removeTrackEvent( options._id );
9419 // extend teardown to always call end if running
9420 natives._teardown = combineFn(function() {
9422 var args = slice.call( arguments ),
9423 runningPlugins = this.data.running[ natives.type ];
9425 // end function signature is not the same as teardown,
9426 // put null on the front of arguments for the event parameter
9427 args.unshift( null );
9429 // only call end if event is running
9430 args[ 1 ]._running &&
9431 runningPlugins.splice( runningPlugins.indexOf( options ), 1 ) &&
9432 natives.end.apply( this, args );
9434 args[ 1 ]._running = false;
9435 this.emit( "trackend",
9436 Popcorn.extend( {}, options, {
9437 plugin: natives.type,
9439 track: Popcorn.getTrackEvent( this, options.id || options._id )
9442 }, natives._teardown );
9444 // extend teardown to always trigger trackteardown after teardown
9445 natives._teardown = combineFn( natives._teardown, function() {
9447 this.emit( "trackteardown", Popcorn.extend( {}, options, {
9449 type: "trackteardown",
9450 track: Popcorn.getTrackEvent( this, options.id || options._id )
9454 // default to an empty string if no effect exists
9455 // split string into an array of effects
9456 options.compose = options.compose || [];
9457 if ( typeof options.compose === "string" ) {
9458 options.compose = options.compose.split( " " );
9460 options.effect = options.effect || [];
9461 if ( typeof options.effect === "string" ) {
9462 options.effect = options.effect.split( " " );
9465 // join the two arrays together
9466 options.compose = options.compose.concat( options.effect );
9468 options.compose.forEach(function( composeOption ) {
9470 // if the requested compose is garbage, throw it away
9471 compose = Popcorn.compositions[ composeOption ] || {};
9473 // extends previous functions with compose function
9474 methods.forEach(function( method ) {
9475 natives[ method ] = combineFn( natives[ method ], compose[ method ] );
9479 // Ensure a manifest object, an empty object is a sufficient fallback
9480 options._natives.manifest = manifest;
9482 // Checks for expected properties
9483 if ( !( "start" in options ) ) {
9484 options.start = options[ "in" ] || 0;
9487 if ( !options.end && options.end !== 0 ) {
9488 options.end = options[ "out" ] || Number.MAX_VALUE;
9491 // Use hasOwn to detect non-inherited toString, since all
9492 // objects will receive a toString - its otherwise undetectable
9493 if ( !hasOwn.call( options, "toString" ) ) {
9494 options.toString = function() {
9496 "start: " + options.start,
9497 "end: " + options.end,
9498 "id: " + (options.id || options._id)
9501 // Matches null and undefined, allows: false, 0, "" and truthy
9502 if ( options.target != null ) {
9503 props.push( "target: " + options.target );
9506 return name + " ( " + props.join(", ") + " )";
9510 // Resolves 239, 241, 242
9511 if ( !options.target ) {
9513 // Sometimes the manifest may be missing entirely
9514 // or it has an options object that doesn't have a `target` property
9515 manifestOpts = "options" in manifest && manifest.options;
9517 options.target = manifestOpts && "target" in manifestOpts && manifestOpts.target;
9520 if ( !options._id && options._natives ) {
9521 // ensure an initial id is there before setup is called
9522 options._id = Popcorn.guid( options._natives.type );
9525 if ( options instanceof TrackEvent ) {
9527 if ( options._natives ) {
9528 // Supports user defined track event id
9529 options._id = options.id || options._id || Popcorn.guid( options._natives.type );
9531 // Trigger _setup method if exists
9532 if ( options._natives._setup ) {
9534 options._natives._setup.call( this, options );
9536 this.emit( "tracksetup", Popcorn.extend( {}, options, {
9537 plugin: options._natives.type,
9544 this.data.trackEvents.add( options );
9545 TrackEvent.start( this, options );
9547 this.timeUpdate( this, null, true );
9549 // Store references to user added trackevents in ref table
9550 if ( options._id ) {
9551 Popcorn.addTrackEvent.ref( this, options );
9554 // Create new track event for this instance
9555 Popcorn.addTrackEvent( this, options );
9558 // Future support for plugin event definitions
9559 // for all of the native events
9560 Popcorn.forEach( setup, function( callback, type ) {
9561 // Don't attempt to create events for certain properties:
9562 // "start", "end", "type", "manifest". Fixes #1365
9563 if ( blacklist.indexOf( type ) === -1 ) {
9564 this.on( type, callback );
9571 // Extend Popcorn.p with new named definition
9572 // Assign new named definition
9573 Popcorn.p[ name ] = plugin[ name ] = function( id, options ) {
9574 var length = arguments.length,
9575 trackEvent, defaults, mergedSetupOpts, previousOpts, newOpts;
9577 // Shift arguments based on use case
9580 // p.plugin( options );
9581 if ( id && !options ) {
9586 // Get the trackEvent that matches the given id.
9587 trackEvent = this.getTrackEvent( id );
9589 // If the track event does not exist, ensure that the options
9590 // object has a proper id
9591 if ( !trackEvent ) {
9594 // If the track event does exist, merge the updated properties
9598 previousOpts = getPreviousProperties( trackEvent, newOpts );
9600 // Call the plugins defined update method if provided. Allows for
9601 // custom defined updating for a track event to be defined by the plugin author
9602 if ( trackEvent._natives._update ) {
9604 this.data.trackEvents.remove( trackEvent );
9606 // It's safe to say that the intent of Start/End will never change
9607 // Update them first before calling update
9608 if ( hasOwn.call( options, "start" ) ) {
9609 trackEvent.start = options.start;
9612 if ( hasOwn.call( options, "end" ) ) {
9613 trackEvent.end = options.end;
9616 TrackEvent.end( this, trackEvent );
9619 definition.call( this, trackEvent );
9622 trackEvent._natives._update.call( this, trackEvent, options );
9624 this.data.trackEvents.add( trackEvent );
9625 TrackEvent.start( this, trackEvent );
9627 // This branch is taken when there is no explicitly defined
9628 // _update method for a plugin. Which will occur either explicitly or
9629 // as a result of the plugin definition being a function that _returns_
9630 // a definition object.
9632 // In either case, this path can ONLY be reached for TrackEvents that
9635 // Directly update the TrackEvent instance.
9636 // This supports TrackEvent invariant enforcement.
9637 Popcorn.extend( trackEvent, options );
9639 this.data.trackEvents.remove( id );
9641 // If a _teardown function was defined,
9642 // enforce for track event removals
9643 if ( trackEvent._natives._teardown ) {
9644 trackEvent._natives._teardown.call( this, trackEvent );
9647 // Update track event references
9648 Popcorn.removeTrackEvent.ref( this, id );
9651 pluginFn.call( this, definition.call( this, trackEvent ), trackEvent );
9654 // Supports user defined track event id
9655 trackEvent._id = trackEvent.id || trackEvent._id || Popcorn.guid( trackEvent._natives.type );
9657 if ( trackEvent._natives && trackEvent._natives._setup ) {
9659 trackEvent._natives._setup.call( this, trackEvent );
9661 this.emit( "tracksetup", Popcorn.extend( {}, trackEvent, {
9662 plugin: trackEvent._natives.type,
9668 this.data.trackEvents.add( trackEvent );
9669 TrackEvent.start( this, trackEvent );
9671 this.timeUpdate( this, null, true );
9673 // Store references to user added trackevents in ref table
9674 Popcorn.addTrackEvent.ref( this, trackEvent );
9677 // Fire an event with change information
9678 this.emit( "trackchange", {
9680 type: "trackchange",
9681 previousValue: previousOpts,
9682 currentValue: trackEvent,
9689 if ( trackEvent._natives.type !== "cue" ) {
9690 // Fire an event with change information
9691 this.emit( "trackchange", {
9693 type: "trackchange",
9694 previousValue: previousOpts,
9695 currentValue: newOpts,
9704 this.data.running[ name ] = this.data.running[ name ] || [];
9706 // Merge with defaults if they exist, make sure per call is prioritized
9707 defaults = ( this.options.defaults && this.options.defaults[ name ] ) || {};
9708 mergedSetupOpts = Popcorn.extend( {}, defaults, options );
9710 pluginFn.call( this, isfn ? definition.call( this, mergedSetupOpts ) : definition,
9716 // if the manifest parameter exists we should extend it onto the definition object
9717 // so that it shows up when calling Popcorn.registry and Popcorn.registryByName
9719 Popcorn.extend( definition, {
9724 // Push into the registry
9727 definition: definition,
9732 Popcorn.registry.push(
9733 Popcorn.extend( plugin, entry, {
9737 Popcorn.registryByName[ name ] = entry;
9742 // Storage for plugin function errors
9743 Popcorn.plugin.errors = [];
9745 // Returns wrapped plugin function
9746 function safeTry( fn, pluginName ) {
9749 // When Popcorn.plugin.debug is true, do not suppress errors
9750 if ( Popcorn.plugin.debug ) {
9751 return fn.apply( this, arguments );
9755 return fn.apply( this, arguments );
9758 // Push plugin function errors into logging queue
9759 Popcorn.plugin.errors.push({
9762 source: fn.toString()
9765 // Trigger an error that the instance can listen for
9767 this.emit( "pluginerror", Popcorn.plugin.errors );
9772 // Debug-mode flag for plugin development
9773 // True for Popcorn development versions, false for stable/tagged versions
9774 Popcorn.plugin.debug = ( Popcorn.version === "@" + "VERSION" );
9776 // removePlugin( type ) removes all tracks of that from all instances of popcorn
9777 // removePlugin( obj, type ) removes all tracks of type from obj, where obj is a single instance of popcorn
9778 Popcorn.removePlugin = function( obj, name ) {
9780 // Check if we are removing plugin from an instance or from all of Popcorn
9787 if ( Popcorn.protect.natives.indexOf( name.toLowerCase() ) >= 0 ) {
9788 Popcorn.error( "'" + name + "' is a protected function name" );
9792 var registryLen = Popcorn.registry.length,
9795 // remove plugin reference from registry
9796 for ( registryIdx = 0; registryIdx < registryLen; registryIdx++ ) {
9797 if ( Popcorn.registry[ registryIdx ].name === name ) {
9798 Popcorn.registry.splice( registryIdx, 1 );
9799 delete Popcorn.registryByName[ name ];
9800 delete Popcorn.manifest[ name ];
9802 // delete the plugin
9805 // plugin found and removed, stop checking, we are done
9812 var byStart = obj.data.trackEvents.byStart,
9813 byEnd = obj.data.trackEvents.byEnd,
9814 animating = obj.data.trackEvents.animating,
9817 // remove all trackEvents
9818 for ( idx = 0, sl = byStart.length; idx < sl; idx++ ) {
9820 if ( byStart[ idx ] && byStart[ idx ]._natives && byStart[ idx ]._natives.type === name ) {
9822 byStart[ idx ]._natives._teardown && byStart[ idx ]._natives._teardown.call( obj, byStart[ idx ] );
9824 byStart.splice( idx, 1 );
9826 // update for loop if something removed, but keep checking
9828 if ( obj.data.trackEvents.startIndex <= idx ) {
9829 obj.data.trackEvents.startIndex--;
9830 obj.data.trackEvents.endIndex--;
9834 // clean any remaining references in the end index
9835 // we do this seperate from the above check because they might not be in the same order
9836 if ( byEnd[ idx ] && byEnd[ idx ]._natives && byEnd[ idx ]._natives.type === name ) {
9838 byEnd.splice( idx, 1 );
9842 //remove all animating events
9843 for ( idx = 0, sl = animating.length; idx < sl; idx++ ) {
9845 if ( animating[ idx ] && animating[ idx ]._natives && animating[ idx ]._natives.type === name ) {
9847 animating.splice( idx, 1 );
9849 // update for loop if something removed, but keep checking
9856 Popcorn.compositions = {};
9858 // Plugin inheritance
9859 Popcorn.compose = function( name, definition, manifest ) {
9861 // If `manifest` arg is undefined, check for manifest within the `definition` object
9862 // If no `definition.manifest`, an empty object is a sufficient fallback
9863 Popcorn.manifest[ name ] = manifest = manifest || definition.manifest || {};
9865 // register the effect by name
9866 Popcorn.compositions[ name ] = definition;
9869 Popcorn.plugin.effect = Popcorn.effect = Popcorn.compose;
9871 var rnaiveExpr = /^(?:\.|#|\[)/;
9873 // Basic DOM utilities and helpers API. See #1037
9876 // Popcorn.dom.find( selector, context )
9878 // Returns the first element that matches the specified selector
9879 // Optionally provide a context element, defaults to `document`
9882 // Popcorn.dom.find("video") returns the first video element
9883 // Popcorn.dom.find("#foo") returns the first element with `id="foo"`
9884 // Popcorn.dom.find("foo") returns the first element with `id="foo"`
9885 // Note: Popcorn.dom.find("foo") is the only allowed deviation
9886 // from valid querySelector selector syntax
9888 // Popcorn.dom.find(".baz") returns the first element with `class="baz"`
9889 // Popcorn.dom.find("[preload]") returns the first element with `preload="..."`
9891 // See https://developer.mozilla.org/En/DOM/Document.querySelector
9894 find: function( selector, context ) {
9897 // Default context is the `document`
9898 context = context || document;
9902 // If the selector does not begin with "#", "." or "[",
9903 // it could be either a nodeName or ID w/o "#"
9904 if ( !rnaiveExpr.test( selector ) ) {
9906 // Try finding an element that matches by ID first
9907 node = document.getElementById( selector );
9909 // If a match was found by ID, return the element
9910 if ( node !== null ) {
9914 // Assume no elements have been found yet
9915 // Catch any invalid selector syntax errors and bury them.
9917 node = context.querySelector( selector );
9919 if ( Popcorn.dom.debug ) {
9928 // Cache references to reused RegExps
9936 success: Popcorn.nop,
9939 contentType: "application/x-www-form-urlencoded; charset=UTF-8"
9942 Popcorn.xhr = function( options ) {
9945 options.dataType = options.dataType && options.dataType.toLowerCase() || null;
9947 if ( options.dataType &&
9948 ( options.dataType === "jsonp" || options.dataType === "script" ) ) {
9950 Popcorn.xhr.getJSONP(
9953 options.dataType === "script"
9958 // Merge the "setup" defaults and custom "options"
9959 // into a new plain object.
9960 settings = Popcorn.extend( {}, setup, options );
9962 // Create new XMLHttpRequest object
9963 settings.ajax = new XMLHttpRequest();
9965 if ( settings.ajax ) {
9967 if ( settings.type === "GET" && settings.data ) {
9969 // append query string
9970 settings.url += ( rparams.test( settings.url ) ? "&" : "?" ) + settings.data;
9972 // Garbage collect and reset settings.data
9973 settings.data = null;
9977 settings.ajax.open( settings.type, settings.url, settings.async );
9979 // For POST, set the content-type request header
9980 if ( settings.type === "POST" ) {
9981 settings.ajax.setRequestHeader(
9982 "Content-Type", settings.contentType
9986 settings.ajax.send( settings.data || null );
9988 return Popcorn.xhr.httpData( settings );
9993 Popcorn.xhr.httpData = function( settings ) {
9995 var data, json = null,
9998 settings.ajax.onreadystatechange = function() {
10000 if ( settings.ajax.readyState === 4 ) {
10003 json = JSON.parse( settings.ajax.responseText );
10009 xml: settings.ajax.responseXML,
10010 text: settings.ajax.responseText,
10014 // Normalize: data.xml is non-null in IE9 regardless of if response is valid xml
10015 if ( !data.xml || !data.xml.documentElement ) {
10019 parser = new DOMParser();
10020 xml = parser.parseFromString( settings.ajax.responseText, "text/xml" );
10022 if ( !xml.getElementsByTagName( "parsererror" ).length ) {
10026 // data.xml remains null
10030 // If a dataType was specified, return that type of data
10031 if ( settings.dataType ) {
10032 data = data[ settings.dataType ];
10036 settings.success.call( settings.ajax, data );
10043 Popcorn.xhr.getJSONP = function( url, success, isScript ) {
10045 var head = document.head || document.getElementsByTagName( "head" )[ 0 ] || document.documentElement,
10046 script = document.createElement( "script" ),
10049 rjsonp = /(=)\?(?=&|$)|\?\?/,
10050 replaceInUrl, prefix, paramStr, callback, callparam;
10054 // is there a calback already in the url
10055 callparam = url.match( /(callback=[^&]*)/ );
10057 if ( callparam !== null && callparam.length ) {
10059 prefix = callparam[ 1 ].split( "=" )[ 1 ];
10061 // Since we need to support developer specified callbacks
10062 // and placeholders in harmony, make sure matches to "callback="
10063 // aren't just placeholders.
10064 // We coded ourselves into a corner here.
10065 // JSONP callbacks should never have been
10066 // allowed to have developer specified callbacks
10067 if ( prefix === "?" ) {
10071 // get the callback name
10072 callback = Popcorn.guid( prefix );
10074 // replace existing callback name with unique callback name
10075 url = url.replace( /(callback=[^&]*)/, "callback=" + callback );
10078 callback = Popcorn.guid( "jsonp" );
10080 if ( rjsonp.test( url ) ) {
10081 url = url.replace( rjsonp, "$1" + callback );
10084 // split on first question mark,
10085 // this is to capture the query string
10086 params = url.split( /\?(.+)?/ );
10088 // rebuild url with callback
10089 url = params[ 0 ] + "?";
10090 if ( params[ 1 ] ) {
10091 url += params[ 1 ] + "&";
10093 url += "callback=" + callback;
10096 // Define the JSONP success callback globally
10097 window[ callback ] = function( data ) {
10098 // Fire success callbacks
10099 success && success( data );
10104 script.addEventListener( "load", function() {
10106 // Handling remote script loading callbacks
10109 success && success();
10112 // Executing for JSONP requests
10114 // Garbage collect the callback
10115 delete window[ callback ];
10117 // Garbage collect the script resource
10118 head.removeChild( script );
10121 script.addEventListener( "error", function( e ) {
10122 // Handling remote script loading callbacks
10123 success && success( { error: e } );
10125 // Executing for JSONP requests
10127 // Garbage collect the callback
10128 delete window[ callback ];
10130 // Garbage collect the script resource
10131 head.removeChild( script );
10135 head.insertBefore( script, head.firstChild );
10140 Popcorn.getJSONP = Popcorn.xhr.getJSONP;
10142 Popcorn.getScript = Popcorn.xhr.getScript = function( url, success ) {
10144 return Popcorn.xhr.getJSONP( url, success, true );
10148 // Simple function to parse a timestamp into seconds
10149 // Acceptable formats are:
10152 // Hours and minutes are optional. They default to 0
10153 toSeconds: function( timeStr, framerate ) {
10154 // Hours and minutes are optional
10155 // Seconds must be specified
10156 // Seconds can be followed by milliseconds OR by the frame information
10157 var validTimeFormat = /^([0-9]+:){0,2}[0-9]+([.;][0-9]+)?$/,
10158 errorMessage = "Invalid time format",
10159 digitPairs, lastIndex, lastPair, firstPair,
10160 frameInfo, frameTime;
10162 if ( typeof timeStr === "number" ) {
10166 if ( typeof timeStr === "string" &&
10167 !validTimeFormat.test( timeStr ) ) {
10168 Popcorn.error( errorMessage );
10171 digitPairs = timeStr.split( ":" );
10172 lastIndex = digitPairs.length - 1;
10173 lastPair = digitPairs[ lastIndex ];
10175 // Fix last element:
10176 if ( lastPair.indexOf( ";" ) > -1 ) {
10178 frameInfo = lastPair.split( ";" );
10181 if ( framerate && ( typeof framerate === "number" ) ) {
10182 frameTime = parseFloat( frameInfo[ 1 ], 10 ) / framerate;
10185 digitPairs[ lastIndex ] = parseInt( frameInfo[ 0 ], 10 ) + frameTime;
10188 firstPair = digitPairs[ 0 ];
10192 1: parseFloat( firstPair, 10 ),
10194 2: ( parseInt( firstPair, 10 ) * 60 ) +
10195 parseFloat( digitPairs[ 1 ], 10 ),
10197 3: ( parseInt( firstPair, 10 ) * 3600 ) +
10198 ( parseInt( digitPairs[ 1 ], 10 ) * 60 ) +
10199 parseFloat( digitPairs[ 2 ], 10 )
10201 }[ digitPairs.length || 1 ];
10205 // alias for exec function
10206 Popcorn.p.cue = Popcorn.p.exec;
10208 // Protected API methods
10209 Popcorn.protect = {
10210 natives: getKeys( Popcorn.p ).map(function( val ) {
10211 return val.toLowerCase();
10215 // Setup logging for deprecated methods
10217 // Deprecated: Recommended
10223 }, function( recommend, api ) {
10224 var original = Popcorn.p[ api ];
10225 // Override the deprecated api method with a method of the same name
10226 // that logs a warning and defers to the new recommended method
10227 Popcorn.p[ api ] = function() {
10228 if ( typeof console !== "undefined" && console.warn ) {
10230 "Deprecated method '" + api + "', " +
10231 (recommend == null ? "do not use." : "use '" + recommend + "' instead." )
10234 // Restore api after first warning
10235 Popcorn.p[ api ] = original;
10237 return Popcorn.p[ recommend ].apply( this, [].slice.call( arguments ) );
10242 // Exposes Popcorn to global context
10243 global.Popcorn = Popcorn;
10245 })(window, window.document);
10247 (function (global, document, $, deck, window, undefined) {
10250 function maybeAddSnippet(audioDataFile, options, andThen) {
10251 if (options.snippets.browsercast) {
10252 if ($(options.selectors.browsercast).size() > 0 && options.alert.goto) {
10253 alert("'options.snippets.browsercast' is true but a "+options.selectors.browsercast+" has been found."
10254 +"\nThis might cause interaction glitches."
10256 +"\nSuggestion: remove your html snippet or pass the {snippets: {browsercast: false}} option."
10259 var ext = audioDataFile.replace(/.*[.]([^.]*)/, '$1');
10260 $('<div/>').addClass('browsercast')
10261 .append($('<audio/>').addClass("browsercast-audio")
10262 .append($('<source/>').attr('src', audioDataFile).attr('type', 'audio/'+ext)))
10263 .append($('<menu/>').append($('<button/>').addClass('playpause')))
10264 .append($('<div/>').addClass('browsercast-markers')
10265 .append($('<div/>').addClass('browsercast-time-label').text('1:00'))
10266 .append($('<div/>').addClass('browsercast-total-time-label').text('9:99')))
10267 .appendTo($.deck('getContainer'));
10271 var $document = $(document);
10273 function togglePlay(popcorn) {
10274 if (popcorn.paused() === true) {
10281 function timeString(nSeconds) {
10282 return new Date(null, null, null, null, null, nSeconds)
10284 .replace(/ .*$/, '')
10285 .replace(/^00:/, '');
10288 function updatePlayPauseClass(paused, that, ifPlay, ifPause) {
10289 if (paused == true) {
10290 $(that).removeClass(ifPlay);
10291 $(that).addClass(ifPause);
10293 $(that).removeClass(ifPause);
10294 $(that).addClass(ifPlay);
10298 // Use the audio timeupdates to drive existing slides.
10299 function playBrowserCast(timings, options) {
10300 var audio, popcorn, markers, bc;
10302 var nTimings = Object.keys(timings).length;
10303 var defaultWidth = (100./nTimings)+'%';
10305 var forEachTiming = function(f) {
10306 Object.keys(timings)
10307 .sort(function(a, b) {return a - b;})
10311 var inited = false; // to avoid the audio setting the current slide to 0 at the beginning (and allow bookmarking)
10313 bc = $(options.selectors.browsercast).get(0);
10314 audio = $(options.selectors.browsercastAudio).get(0);
10315 markers = $(options.selectors.browsercastMarkers).get(0);
10316 popcorn = Popcorn(audio);
10318 $('.playpause', bc).click(function() {
10319 togglePlay(popcorn);
10322 forEachTiming(function(k, i) {
10323 var div = document.createElement('div');
10324 div.className = 'browsercast-cue';
10325 div.onclick = function(event) {
10326 popcorn.currentTime(timings[k]);
10329 .css('width', defaultWidth)
10330 .css('box-sizing', 'border-box');
10331 markers.appendChild(div);
10333 popcorn.cue(k, timings[k], function () {
10334 if (!inited) return;
10335 transitionLock = true;
10336 $.deck('go', parseInt(k));
10337 $('.active', markers).removeClass('active');
10338 $(div).addClass('active');
10339 transitionLock = false;
10342 var trySetCueLengthAndPlay = function(retries, delay) {
10343 if (retries <= 0) { return; }
10344 var totalDuration = popcorn.duration();
10345 if (totalDuration > 0) { // it tests also for NaN
10347 forEachTiming(function(k, i) {
10349 var pc = 100 * (timings[k] - timings[kPrev]) / totalDuration;
10350 $(divs[kPrev]).css('width', pc+'%');
10354 var pc = 100 * (totalDuration - timings[kPrev]) / totalDuration;
10355 $(divs[kPrev]).css('width', pc+'%');
10356 // Start the 'cast!
10358 var currentSlideIndex = $.deck('getSlides').indexOf($.deck('getSlide'));
10359 setTimeout(function() { // delay initialization for popcorn to be properly inited
10360 $.deck('go', currentSlideIndex);
10363 setTimeout(function() {
10364 trySetCueLengthAndPlay(retries - 1, delay*1.5);
10369 // lock for preventing slidechanged event handler during timeupdate handler.
10370 // TODO using a mutex seems clunky.
10371 var transitionLock = false;
10373 // Decorator for creating an event handler that doesn't run
10374 // when the lock is active.
10375 var ifNotLocked = function (f) {
10376 return function (event) {
10377 if (!transitionLock) {
10378 f.apply(this, arguments);
10383 $document.bind('deck.change', ifNotLocked(function (event, from, to) {
10384 popcorn.currentTime(timings[to.toString()]);
10389 var updatePlayPause = function() {
10390 $('.playpause').each(function() {
10391 updatePlayPauseClass(popcorn.paused(), this, 'pause', 'play');
10394 audio.addEventListener('pause', updatePlayPause);
10395 audio.addEventListener('playing', updatePlayPause);
10396 audio.addEventListener('timeupdate', function () {
10397 var estimatedTotal = popcorn.duration();
10398 var pc = 100 * audio.currentTime / estimatedTotal;
10399 var timeTxt = timeString(audio.currentTime);
10400 var totalTimeTxt = timeString(estimatedTotal);
10401 $(options.selectors.browsercastTimeLabel).css('left', pc+'%').text(timeTxt);
10402 $(options.selectors.browsercastTotalTimeLabel).text(totalTimeTxt);
10405 $document.unbind('keydown.deckbcast').bind('keydown.deckbcast', function(e) {
10406 //opts.keys.scale || $.inArray(e.which, opts.keys.scale) > -1) {
10407 if (e.which === 32) {
10408 togglePlay(popcorn);
10409 e.preventDefault();
10413 trySetCueLengthAndPlay(20, 10);
10417 function leftPad(number, targetLength, padding) {
10418 padding = padding || ' ';
10419 var output = number + '';
10420 while (output.length < targetLength) {
10421 output = padding + output;
10426 // Start recording a 'cast
10427 // In the end you can get the slide HTML with the cue attributes set
10429 // browsercastRecorder.getHTMLSlides()
10430 // in the Javascript console.
10432 // Press 'Left' on the first slide to start recording.
10433 function recordBrowserCast(options) {
10435 var bc = $(options.selectors.browsercast);
10436 $(options.selectors.browsercastAudio).attr('controls', 'true');
10437 $(options.selectors.browsercastMarkers).hide();
10438 setTimeout(function(){ $.deck('go', 0); logs = [{time:0, slide:0}];}, 200);
10440 var $document = $(document);
10441 var audio = $(options.selectors.browsercastAudio).get(0);
10442 var logs = []; // as a list of pairs, so we can have multiple values and clean afterwards
10443 var exportLogs = function() {
10449 res += leftPad('"'+logs[i].slide+'"', 8) + ':' + leftPad(logs[i].time.toFixed(2), 6);
10455 $document.bind('deck.change', function(event, from, to) {
10456 logs.push({time: audio.currentTime, slide: to});
10458 $document.unbind('keydown.deckbcastrecord').bind('keydown.deckbcastrecord', function(e) {
10459 if (e.which === 84) { // 't'
10465 function unsetKey(which, fromWhat) {
10466 if ($.isArray(fromWhat)) {
10468 while( (match = fromWhat.indexOf(which)) > -1 ) {
10469 fromWhat.splice(match, 1);
10471 } else if ($.isPlainObject(fromWhat)) {
10472 for (var p in fromWhat) {
10473 if (fromWhat.hasOwnProperty(p)) {
10474 unsetKey(which, fromWhat[p]);
10481 $.extend(true, $.deck.defaults, {
10483 browsercast: '.browsercast',
10484 browsercastAudio: '.browsercast-audio',
10485 browsercastMarkers: '.browsercast-markers',
10486 browsercastTimeLabel: '.browsercast-time-label',
10487 browsercastTotalTimeLabel: '.browsercast-total-time-label'
10492 browsercastAlways: false
10501 $document.bind('deck.init', function() {
10502 var options = $.deck('getOptions');
10503 var audioDataFile = $('html>head>meta[name="audio"]').attr('content');
10504 if (audioDataFile === undefined) {
10507 unsetKey(32, options.keys); // unbind space from 'next slide'
10508 maybeAddSnippet(audioDataFile, options);
10509 var timingDataFile = $('html>head>meta[name="timings"]').attr('content');
10510 if (timingDataFile === undefined) {
10511 recordBrowserCast(options);
10513 $.getJSON(timingDataFile, function(timings) {
10514 playBrowserCast(timings, options);
10515 }).fail(function( jqxhr, textStatus, error ) {
10516 var err = textStatus + ', ' + error;
10517 console.log('[Browsercast] Request Failed: ' + err);
10518 if (options.alert.browsercast) {
10519 alert('Timing file "' + timingDataFile + '" referenced but it was not found or wrong.\n' +
10520 'See console logs for more details.\n' +
10521 "Browsercast replay won't work, falling back to timing recording.");
10523 recordBrowserCast();
10528 })(window, window.document, jQuery, 'deck', this);
10529 function ACTUALLY_FILL_CSS(el) { $(el).text("\n.deck-container {\n position: relative;\n overflow: hidden;\n margin: 0;\n}\n\n.deck-container:not(.show-all-slides):not(.deck-menu):not(.deck-loading) > .slide:not(.deck-current), .deck-container:not(.show-all-slides):not(.deck-menu):not(.deck-loading) > .slide:not(.deck-child-current) {\n display: none;\n}\n.deck-container:not(.show-all-slides):not(.deck-menu):not(.deck-loading) > .slide.deck-current, .deck-container:not(.show-all-slides):not(.deck-menu):not(.deck-loading) > .slide.deck-child-current {\n display: block;\n}\n\n.deck-container.deck-loading > *:not(.deck-loading-splash) {\n visibility: hidden;\n}\n.touch .deck-container {\n -webkit-text-size-adjust: none;\n -moz-text-size-adjust: none;\n}\n.deck-container > .slide {\n position: absolute;\n}\n.deck-container > .slide.deck-current, .deck-container > .slide.deck-child-current {\n position: absolute;\n /* relative to parent */\n}\n.deck-container > .slide.deck-current .slide, .deck-container > .slide.deck-child-current .slide {\n visibility: hidden;\n}\n.deck-container > .slide.deck-current .deck-previous, .deck-container > .slide.deck-current .deck-before, .deck-container > .slide.deck-current .deck-current, .deck-container > .slide.deck-child-current .deck-previous, .deck-container > .slide.deck-child-current .deck-before, .deck-container > .slide.deck-child-current .deck-current {\n visibility: visible;\n}\n.deck-container.deck-anim-ready .deck-loading-splash {\n visibility: hidden;\n opacity: 0;\n /*\n right: 100%;\n left: -100%;\n */\n -webkit-transition: visibility 0s linear 0.5s, all 0.5s linear;\n transition: visibility 0s linear .5s, all 0.5s linear;\n}\n.deck-container .deck-loading-splash {\n visibility: visible;\n opacity: 1;\n position: absolute;\n text-align: center;\n padding-top: 200px;\n display: flex;\n margin: 0 auto;\n left: 0;\n top: 0;\n right: 0;\n bottom: 0;\n background: black;\n color: white;\n z-index: 100;\n}\n\n\n.deck-container {\n width: 100%; height: 100%; /* to get a proper filling of the parent */\n margin: 0; padding: 0; /* any margin is handled by the parent or the fit extension */\n position: absolute;\n left:0; top:0; width:100%; height:100%;\n border: 0;\n}\n.deck-container>.slide {\n width: 100%; height: 100%; /* to get a proper filling of the parent */\n min-width:0; min-height:0; /* undoing some hurting style in the defaults of deck.js */\n overflow: hidden; /* don't show slides outside of their box */\n /* margin:0; padding:0; /* remove possible margins */\n}\n\nbody.is-clone .clonepointer {\n /* default convenient positioning for clone pointers */\n position: absolute;\n z-index: 10; }\n body.is-clone .clonepointer.scale-on-click {\n transition: transform 80ms linear;\n -webkit-transition: -webkit-transform 80ms linear; }\n body.is-clone .clonepointer.scale-on-click.pointer-click {\n transition: transform 150ms linear;\n -webkit-transition: -webkit-transform 150ms linear;\n transform: translate(-50%, -50%) scale(1.5, 1.5) translate(50%, 50%);\n -webkit-transform: translate(-50%, -50%) scale(1.5, 1.5) translate(50%, 50%); }\n\n.notes, .notes-target {\n display: none; }\n\nbody.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-current, body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-child-current {\n outline: 5px solid grey;\n /* use outline to avoid layout issues with old themes and allow for precise pointer position estimation */\n overflow: hidden;\n left: 0;\n top: 0;\n transform: translate(20px, 20px);\n -webkit-transform: translate(20px, 20px); }\n body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-current + .slide, body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-child-current + .slide {\n outline: 5px solid grey;\n overflow: hidden;\n display: block !important;\n visibility: visible;\n top: 0;\n left: 0;\n transform: translate(-50%, -50%) scale(0.5) translate(50%, 50%) translate(200%, 0) translate(80px, 40px);\n -webkit-transform: translate(-50%, -50%) scale(0.5) translate(50%, 50%) translate(200%, 0) translate(80px, 40px); }\n body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-current + .slide.deck-next, body.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) > .slide.deck-child-current + .slide.deck-next {\n outline-color: red; }\nbody.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) .notes-target {\n display: block;\n background: black;\n color: #FFB;\n padding: 5px;\n position: absolute;\n left: 840px;\n right: 0;\n top: 340px;\n bottom: 0; }\n\n.goto-form {\n position: absolute;\n z-index: 3;\n bottom: 10px;\n left: 50%;\n height: 1.75em;\n margin: 0 0 0 -9.125em;\n line-height: 1.75em;\n padding: 0.625em;\n display: none;\n background: #ccc;\n overflow: hidden;\n border-radius: 10px;\n}\n.goto-form label {\n font-weight: bold;\n}\n.goto-form label, .goto-form input {\n display: inline-block;\n font-family: inherit;\n}\n.deck-goto .goto-form {\n display: block;\n}\n\n#goto-slide {\n width: 8.375em;\n margin: 0 0.625em;\n height: 1.4375em;\n}\n\n@media print {\n .goto-form, #goto-slide {\n display: none;\n }\n}\n\n.deck-container.no-status .deck-status {\n display: none;\n}\n\n.deck-status {\n position: absolute;\n z-index: 3;\n left: 0;\n bottom: 10px;\n margin: 0;\n padding: 0;\n font-size: 10px;\n /*outline: 1px solid red;*/\n width: 100%;\n text-align: center;\n color: #888;\n}\n\n.deck-prev-link, .deck-next-link {\n display: none;\n position: absolute;\n z-index: 3;\n top: 50%;\n width: 32px;\n height: 32px;\n margin-top: -16px;\n font-size: 20px;\n font-weight: bold;\n line-height: 32px;\n vertical-align: middle;\n text-align: center;\n text-decoration: none;\n color: #fff;\n background: #888;\n border-radius: 16px;\n}\n.deck-prev-link:hover, .deck-prev-link:focus, .deck-prev-link:active, .deck-prev-link:visited, .deck-next-link:hover, .deck-next-link:focus, .deck-next-link:active, .deck-next-link:visited {\n color: #fff;\n}\n\n.deck-prev-link {\n left: 8px;\n}\n\n.deck-next-link {\n right: 8px;\n}\n\n.deck-container:hover .deck-prev-link, .deck-container:hover .deck-next-link {\n display: block;\n}\n.deck-container:hover .deck-prev-link.deck-nav-disabled, .touch .deck-container:hover .deck-prev-link, .deck-container:hover .deck-next-link.deck-nav-disabled, .touch .deck-container:hover .deck-next-link {\n display: none;\n}\n\n@media print {\n .deck-prev-link, .deck-next-link {\n display: none !important;\n }\n}\n\n.deck-menu {\n overflow: auto;\n}\n.deck-menu .slide {\n background: #eee;\n position: relative;\n left: 0;\n top: 0;\n visibility: visible;\n cursor: pointer;\n}\n.no-csstransforms .deck-menu > .slide {\n float: left;\n width: 22%;\n height: 22%;\n min-height: 0;\n margin: 1%;\n font-size: 0.22em;\n overflow: hidden;\n padding: 0 0.5%;\n}\n.csstransforms .deck-menu > .slide {\n -webkit-transform: scale(0.22) !important;\n -ms-transform: scale(0.22) !important;\n transform: scale(0.22) !important;\n -webkit-transform-origin: 0 0;\n -ms-transform-origin: 0 0;\n transform-origin: 0 0;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n overflow: hidden;\n padding: 0 48px;\n margin: 12px;\n}\n.deck-menu iframe, .deck-menu img, .deck-menu video {\n max-width: 100%;\n}\n.deck-menu .deck-current, .no-touch .deck-menu .slide:hover {\n background: #ddf;\n}\n.deck-menu.deck-container:hover .deck-prev-link, .deck-menu.deck-container:hover .deck-next-link {\n display: none;\n}\n\n.deck-container .attribution-wrap {\n /* cover the complete offset parent */\n position: absolute;\n left: 0;\n width: 100%;\n top: 0;\n height: 100%;\n}\n.deck-container .attribution-link {\n font-size: 10px;\n color: white;\n background: black;\n border: 1px solid darkgrey;\n opacity: 0.6;\n right: 0;\n bottom: 5px;\n position: absolute;\n padding: 0 5px;\n}\n\n/* the time etc */\n.timekeeper {\n font-size: 28px;\n border-radius: 3px;\n background: black;\n color: white;\n display: inline-block;\n position: absolute;\n left: 840px;\n top: 340px;\n width: 400px;\n padding: 4px;\n margin: -4px; }\n body:not(.has-clones) .timekeeper {\n visibility: hidden; }\n .timekeeper .timekeeper-time, .timekeeper .timekeeper-local-relative-time {\n margin: 0;\n padding: 0;\n display: inline-block;\n width: 50%;\n text-align: center;\n vertical-align: middle; }\n .timekeeper .timekeeper-time.timekeeper-local-relative-time, .timekeeper .timekeeper-local-relative-time.timekeeper-local-relative-time {\n color: grey; }\n .timekeeper .timekeeper-time.timekeeper-time, .timekeeper .timekeeper-local-relative-time.timekeeper-time {\n border-left: 2px solid grey;\n /*margin-left: -10px; not needed with the injected template (no space in it)*/\n margin-right: -15px; }\n .timekeeper .timekeeper-relative-time {\n margin-top: 5px;\n border-top: 2px solid grey;\n text-align: center;\n font-size: 300%; }\n .timekeeper .timekeeper-bang, .timekeeper .timekeeper-clear {\n display: inline-block;\n position: absolute;\n width: 10px;\n height: 10px;\n left: 45%;\n border: 2px solid grey;\n border-radius: 15px;\n background: black; }\n .timekeeper .timekeeper-bang.timekeeper-bang, .timekeeper .timekeeper-clear.timekeeper-bang {\n top: 10px; }\n .timekeeper .timekeeper-bang.timekeeper-clear, .timekeeper .timekeeper-clear.timekeeper-clear {\n top: 23px; }\n .timekeeper .timekeeper-bang:not(.timekeeper-notification), .timekeeper .timekeeper-clear:not(.timekeeper-notification) {\n transition: background 300ms linear;\n -webkit-transition: background 300ms linear; }\n .timekeeper .timekeeper-bang.timekeeper-notification, .timekeeper .timekeeper-clear.timekeeper-notification {\n border-color: white;\n background: green; }\n .timekeeper .timekeeper-bang.timekeeper-notification.timekeeper-clear, .timekeeper .timekeeper-clear.timekeeper-notification.timekeeper-clear {\n background: red; }\n\n/* the logs */\n.timekeeper-logs {\n visibility: hidden;\n border: 2px solid black;\n border-radius: 2px;\n background: #181818;\n color: yellow;\n padding: 5px;\n position: absolute;\n width: 500px;\n right: 0;\n top: 0;\n bottom: 0;\n opacity: .8; }\n .timekeeper-logs.timekeeper-logs-visible {\n visibility: visible; }\n .timekeeper-logs pre {\n font-size: 10px;\n overflow-y: scroll;\n position: absolute;\n top: 50px;\n bottom: 0;\n left: 0;\n right: 0; }\n .timekeeper-logs .button {\n color: white;\n background: black;\n display: inline-block;\n padding: 0 5px;\n margin-right: 10px;\n border: 1px solid white;\n border-radius: 3px; }\n\nbody.has-clones .deck-container:not(.deck-globalscale):not(.deck-menu) div.notes-target {\n top: 490px; }\n\n.deck-container .slide.image-full > .attribution-wrap, .deck-container .slide.image-full > img, .deck-container .slide.image-full > div.img, .deck-container .slide.image-fit > .attribution-wrap, .deck-container .slide.image-fit > img, .deck-container .slide.image-fit > div.img {\n z-index: -1;\n}\n.deck-container .slide.image-full > img, .deck-container .slide.image-full > div.img, .deck-container .slide.image-fit > img, .deck-container .slide.image-fit > div.img {\n margin: 0;\n padding: 0;\n position: relative;\n left: 0;\n top: 0;\n width: 100%;\n min-height: 100%;\n}\n.deck-container .slide.image-full div.img, .deck-container .slide.image-fit div.img {\n width: 100%;\n height: 100%;\n outline: 2px solid red;\n background-position: center center;\n background-repeat: no-repeat;\n}\n.deck-container .slide.image-full.image-full div.img, .deck-container .slide.image-fit.image-full div.img {\n -webkit-background-size: cover;\n -moz-background-size: cover;\n -o-background-size: cover;\n background-size: cover;\n}\n.deck-container .slide.image-full.image-fit div.img, .deck-container .slide.image-fit.image-fit div.img {\n -webkit-background-size: contain;\n -moz-background-size: contain;\n -o-background-size: contain;\n background-size: contain;\n}\n.deck-container .slide.top-left h2 {\n position: absolute;\n border: 0px;\n top: 50px;\n left: 50px;\n}\n.deck-container .slide.top-right h2 {\n position: absolute;\n border: 0px;\n top: 50px;\n right: 50px;\n}\n.deck-container .slide.bottom-left h2 {\n position: absolute;\n border: 0px;\n bottom: 50px;\n left: 50px;\n}\n.deck-container .slide.bottom-right h2 {\n position: absolute;\n border: 0px;\n bottom: 50px;\n right: 50px;\n}\n.deck-container .slide.no-title h1, .deck-container .slide.no-title h2 {\n display: none;\n}\n.deck-container .slide.darkened h2 {\n background: rgba(0, 0, 0, 0.75);\n padding: 15px;\n margin: -15px;\n}\n.deck-container .in3d-table {\n transform: scale(0.7) perspective(600px) rotateX(40deg) rotateZ(-15deg) translate(-30px, -120px);\n}\n\n.deck-container:not(.deck-globalscale) div.comment, .deck-container:not(.deck-globalscale) .comment {\n z-index: 1000 !important;\n /* might need theme specific thing here */\n background-color: yellow;\n /* force opaque... */\n color: darkred;\n}\n\n.deck-container:not(.deck-globalscale) .hasSVG .comment {\n /*transform: none;*/\n -webkit-transform: none;\n}\n\nbody:not(.has-clones):not(.show-comments) .deck-container > .slide .comment, body:not(.has-clones):not(.show-comments) .deck-container > .slide .showwhencomment {\n display: none;\n}\n\n.deck-container > .slide div.comment {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n /*outline: 1px solid red;*/\n border-radius: 3px;\n color: darkred;\n background: rgba(255, 255, 128, 0.7);\n /* opacity: .8;*/\n font-size: 14px;\n line-height: initial;\n padding: 1px 15px;\n width: auto;\n height: 20px;\n margin: 0;\n margin-left: 100px;\n margin-top: -6.6px;\n margin-bottom: -13.2px;\n}\n\n.deck-container > .slide div.comment.small {\n width: 120px;\n margin-left: -100px;\n}\n\n.deck-container > .slide div.comment.twolines {\n height: 40px;\n margin-top: -13.333px;\n margin-bottom: -26.667px;\n}\n\n.browsercast {\n position: absolute;\n top: 5px; left: 5px;\n right: 5px;\n}\n\n.browsercast-audio {\n width: 100%;\n margin: auto auto;\n}\n\n.browsercast-cue {\n position: relative;\n float: left;\n height: 10px;\n border-right: solid 2px #000;\n cursor: pointer;\n}\n\n.browsercast-cue:last-child {\n border-right: 0;\n}\n\n.browsercast-cue.active {\n background-color: #abc;\n}\n\n\nmenu {\n /* @size sets the relative size of the buttons, define before calling the buttons mixin */\n /* Play */\n /* Stop */\n /* Fast-Forward */\n /* Rewind */\n /* Pause */\n margin: 2em auto;\n text-align: center;\n position: relative;\n}\nmenu button {\n position: relative;\n display: inline-block;\n padding: .6em;\n background: linear-gradient(#ffffff, #cccccc), #c9c5c9;\n border-radius: 10em;\n border: 0 solid #d0d0d0;\n width: 3em;\n height: 3em;\n margin-right: 20px;\n box-shadow: 0 0.18em 0.21em rgba(0, 0, 0, 0.4);\n}\nmenu button:hover {\n background: linear-gradient(#f5f5f5, #b9b9b9), #c9c5c9;\n}\nmenu button:before,\nmenu button:after {\n position: absolute;\n content: \" \";\n}\nmenu button:active {\n top: 0.15em;\n box-shadow: 0 0.06em 0.09em rgba(0, 0, 0, 0.4);\n}\nmenu .play:before {\n z-index: 2;\n top: 0.66em;\n left: 1.08em;\n width: 0;\n height: 0;\n border: 0.9em solid transparent;\n border-left-color: rgba(100, 100, 100, 0.8);\n border-left-width: 1.35em;\n}\nmenu .play:hover:before {\n border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu .stop:before {\n top: 0.84em;\n left: 0.84em;\n width: 1.41em;\n height: 1.41em;\n background: rgba(100, 100, 100, 0.8);\n}\nmenu .stop:hover:before {\n background: rgba(36, 36, 36, 0.8);\n}\nmenu .ff:before,\nmenu .ff:after {\n width: 0;\n height: 0;\n top: 0.78em;\n border: 0.75em solid transparent;\n border-left-color: rgba(100, 100, 100, 0.8);\n border-left-width: 0.81em;\n}\nmenu .ff:before {\n left: 0.9em;\n}\nmenu .ff:after {\n left: 1.698em;\n content: \" \";\n}\nmenu .ff:hover:before,\nmenu .ff:hover:after {\n border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu .rw:before,\nmenu .rw:after {\n width: 0;\n height: 0;\n top: 0.78em;\n border: 0.75em solid transparent;\n border-right-color: rgba(100, 100, 100, 0.8);\n border-right-width: 0.81em;\n}\nmenu .rw:before {\n left: 0.66em;\n}\nmenu .rw:after {\n left: -0.15em;\n content: \" \";\n}\nmenu .rw:hover:after,\nmenu .rw:hover:before {\n border-right-color: rgba(36, 36, 36, 0.8);\n}\nmenu .pause:before,\nmenu .pause:after {\n height: 1.41em;\n width: 0.57em;\n left: 0.87em;\n top: 0.84em;\n display: block;\n background-color: rgba(100, 100, 100, 0.8);\n}\nmenu .pause:after {\n left: 1.62em;\n}\nmenu .pause:hover:before,\nmenu .pause:hover:after {\n background-color: rgba(36, 36, 36, 0.8);\n}\nmenu.medium {\n /* Play */\n /* Stop */\n /* Fast-Forward */\n /* Rewind */\n /* Pause */\n}\nmenu.medium button {\n position: relative;\n display: inline-block;\n padding: .6em;\n background: linear-gradient(#ffffff, #cccccc), #c9c5c9;\n border-radius: 10em;\n border: 0 solid #d0d0d0;\n width: 5em;\n height: 5em;\n margin-right: 20px;\n box-shadow: 0 0.3em 0.35em rgba(0, 0, 0, 0.4);\n}\nmenu.medium button:hover {\n background: linear-gradient(#f5f5f5, #b9b9b9), #c9c5c9;\n}\nmenu.medium button:before,\nmenu.medium button:after {\n position: absolute;\n content: \" \";\n}\nmenu.medium button:active {\n top: 0.25em;\n box-shadow: 0 0.1em 0.15em rgba(0, 0, 0, 0.4);\n}\nmenu.medium .play:before {\n z-index: 2;\n top: 1.1em;\n left: 1.8em;\n width: 0;\n height: 0;\n border: 1.5em solid transparent;\n border-left-color: rgba(100, 100, 100, 0.8);\n border-left-width: 2.25em;\n}\nmenu.medium .play:hover:before {\n border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu.medium .stop:before {\n top: 1.4em;\n left: 1.4em;\n width: 2.35em;\n height: 2.35em;\n background: rgba(100, 100, 100, 0.8);\n}\nmenu.medium .stop:hover:before {\n background: rgba(36, 36, 36, 0.8);\n}\nmenu.medium .ff:before,\nmenu.medium .ff:after {\n width: 0;\n height: 0;\n top: 1.3em;\n border: 1.25em solid transparent;\n border-left-color: rgba(100, 100, 100, 0.8);\n border-left-width: 1.35em;\n}\nmenu.medium .ff:before {\n left: 1.5em;\n}\nmenu.medium .ff:after {\n left: 2.83em;\n content: \" \";\n}\nmenu.medium .ff:hover:before,\nmenu.medium .ff:hover:after {\n border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu.medium .rw:before,\nmenu.medium .rw:after {\n width: 0;\n height: 0;\n top: 1.3em;\n border: 1.25em solid transparent;\n border-right-color: rgba(100, 100, 100, 0.8);\n border-right-width: 1.35em;\n}\nmenu.medium .rw:before {\n left: 1.1em;\n}\nmenu.medium .rw:after {\n left: -0.25em;\n content: \" \";\n}\nmenu.medium .rw:hover:after,\nmenu.medium .rw:hover:before {\n border-right-color: rgba(36, 36, 36, 0.8);\n}\nmenu.medium .pause:before,\nmenu.medium .pause:after {\n height: 2.35em;\n width: 0.95em;\n left: 1.45em;\n top: 1.4em;\n display: block;\n background-color: rgba(100, 100, 100, 0.8);\n}\nmenu.medium .pause:after {\n left: 2.7em;\n}\nmenu.medium .pause:hover:before,\nmenu.medium .pause:hover:after {\n background-color: rgba(36, 36, 36, 0.8);\n}\nmenu.small {\n /* Play */\n /* Stop */\n /* Fast-Forward */\n /* Rewind */\n /* Pause */\n}\nmenu.small button {\n position: relative;\n display: inline-block;\n padding: .6em;\n background: linear-gradient(#ffffff, #cccccc), #c9c5c9;\n border-radius: 10em;\n border: 0 solid #d0d0d0;\n width: 3em;\n height: 3em;\n margin-right: 20px;\n box-shadow: 0 0.18em 0.21em rgba(0, 0, 0, 0.4);\n}\nmenu.small button:hover {\n background: linear-gradient(#f5f5f5, #b9b9b9), #c9c5c9;\n}\nmenu.small button:before,\nmenu.small button:after {\n position: absolute;\n content: \" \";\n}\nmenu.small button:active {\n top: 0.15em;\n box-shadow: 0 0.06em 0.09em rgba(0, 0, 0, 0.4);\n}\nmenu.small .play:before {\n z-index: 2;\n top: 0.66em;\n left: 1.08em;\n width: 0;\n height: 0;\n border: 0.9em solid transparent;\n border-left-color: rgba(100, 100, 100, 0.8);\n border-left-width: 1.35em;\n}\nmenu.small .play:hover:before {\n border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu.small .stop:before {\n top: 0.84em;\n left: 0.84em;\n width: 1.41em;\n height: 1.41em;\n background: rgba(100, 100, 100, 0.8);\n}\nmenu.small .stop:hover:before {\n background: rgba(36, 36, 36, 0.8);\n}\nmenu.small .ff:before,\nmenu.small .ff:after {\n width: 0;\n height: 0;\n top: 0.78em;\n border: 0.75em solid transparent;\n border-left-color: rgba(100, 100, 100, 0.8);\n border-left-width: 0.81em;\n}\nmenu.small .ff:before {\n left: 0.9em;\n}\nmenu.small .ff:after {\n left: 1.698em;\n content: \" \";\n}\nmenu.small .ff:hover:before,\nmenu.small .ff:hover:after {\n border-left-color: rgba(36, 36, 36, 0.8);\n}\nmenu.small .rw:before,\nmenu.small .rw:after {\n width: 0;\n height: 0;\n top: 0.78em;\n border: 0.75em solid transparent;\n border-right-color: rgba(100, 100, 100, 0.8);\n border-right-width: 0.81em;\n}\nmenu.small .rw:before {\n left: 0.66em;\n}\nmenu.small .rw:after {\n left: -0.15em;\n content: \" \";\n}\nmenu.small .rw:hover:after,\nmenu.small .rw:hover:before {\n border-right-color: rgba(36, 36, 36, 0.8);\n}\nmenu.small .pause:before,\nmenu.small .pause:after {\n height: 1.41em;\n width: 0.57em;\n left: 0.87em;\n top: 0.84em;\n display: block;\n background-color: rgba(100, 100, 100, 0.8);\n}\nmenu.small .pause:after {\n left: 1.62em;\n}\nmenu.small .pause:hover:before,\nmenu.small .pause:hover:after {\n background-color: rgba(36, 36, 36, 0.8);\n}\n/*\nThe buttons mixin that defines the buttons styles, the @size must be defined to set the relative size\n*/\n/*\nOther Styles\n*/\nbody {\n background: #c1c1c1;\n}\n\n\n\n\n/* ///////////////////////////////// */\n\n\n.browsercast-time-label, .browsercast-total-time-label {\n z-index: 1;\n background-color: grey;\n font-family: lato;\n color: #DDD;\n text-shadow: #555 1px 1px 1px;\n padding: 0 5px;\n border-radius: 2px;\n font-size: 10px;\n display: inline-block;\n position: absolute;\n}\n.browsercast-total-time-label {\n right: 0%;\n bottom: -17px;\n background-color: #333;\n transform: translate(50%, 0) translate(-3px, 0);\n}\n.browsercast-time-label {\n z-index: 2;\n left: 0%;\n transition: left 200ms linear;\n bottom: -17px;\n transform: translate(-50%, 0) translate(-3px, 0);\n}\n.browsercast-time-label:after {\n content: ' ';\n height: 0; \n position: absolute;\n width: 0;\n \n border: 8px solid transparent;\n border-bottom-color: grey;\n \n bottom: 100%;\n left: 50%;\n margin-left: -7px;\n}\n\n\n/* ///////////////////////// */\nmenu {\n padding: 0;\n margin: 0;\n}\n\nmenu .playpause {\n position: absolute;\n left: 0;\n top: 0;\n font-size: 12px;\n margin: 0; padding: 0;\n}\n\n.browsercast-markers {\n position: absolute;\n top: 0; height: 10px;\n left: 3em; right: 1em;\n background-color: #e3e3e3;\n}\n") }