DIR : /home/kozerus/public_html/jsdoit_queue_best.html
/home/kozerus/public_html
<!DOCTYPE html>
<html>
<head>
<title>/jsdoit_queue.html 20200505_1100</title>
<!--
<title>/jsdoit_queue.html 20200505_1030</title>
<title>PreloadJS: Queue Example</title>
-->
<!--
<link href="../_assets/css/shared.css" rel="stylesheet" type="text/css"/>
<link href="../_assets/css/examples.css" rel="stylesheet" type="text/css"/>
<script src="../_assets/js/examples.js"></script>
-->
<!--
<link href="/jkwii/js/jsdoit/preload/_assets/css/shared.css" rel="stylesheet" type="text/css"/>
<link href="/jkwii/js/jsdoit/preload/_assets/css/examples.css" rel="stylesheet" type="text/css"/>
<script src="/jkwii/js/jsdoit/preload/_assets/js/examples.js"></script>
-->
<style id="style_queue_shared" >
body {
margin: 3em auto;
padding: 0;
background-color: #eaebee;
font-family: Arial, Verdana, sans-serif;
font-size: 14px;
font-weight: normal;
color: #333;
line-height: 1.4em;
}
a:link, a:visited {
color: #39f;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
h1, h2 {
color: #FFF;
font-size: 1.6em;
margin-bottom: 0;
padding: 1.5em;
padding-bottom: 1.2em;
background: #374252;
text-transform: uppercase;
}
h1::after {
display: block;
content: "";
background: url('../art/logo_createjs.svg') no-repeat;
height:1.5em;
width: 6em;
margin-top: -0.3em;
float: right;
}
h1 em {
font-weight: 200;
font-style: normal;
}
h2 {
font-size: 1.3em;
padding: 1em;
padding-bottom: 0.8em;
}
h3 {
background: #e0e1e5;
color: #374252;
font-size: 1.25em;
padding: 0.5em;
margin-top: 1.25em;
margin-bottom: -0.5em;
position: relative;
}
code {
color: black;
background-color: rgba(255, 230, 0, 0.33);
padding: 1px 3px;
font-family: Courier New, Courier, serif;
font-weight: bold;
}
</style>
<style id="style_queue" >
body {
width: 960px;
}
header {
margin-bottom: 1rem;
width: 960px;
}
h1 {
font-weight: 200;
margin-bottom: 1rem;
}
h1:before {
content:"PRELOADJS ";
font-weight: bold;
}
header p {
margin: 0;
padding: 1em;
background: rgba(250, 252, 255, 0.7);
}
.content, canvas {
background: white;
}
.content {
width: 960px;
height: 400px;
overflow: hidden;
padding: 1em;
box-sizing: border-box;
}
.loading {
position: relative;
}
.loading:after {
content: url("../art/loading.gif");
position: absolute;
left: 50%;
top: 50%;
margin: -13px 0 0 -51px;
opacity: 0.8;
}
#error, #mobile {
width: 960px;
height: 400px;
display:none;
text-align: left;
padding: 1em;
}
body.embedded header {
display: none;
}
body.embedded {
margin: 0;
}
</style>
<script id="script_queue" >
/**
* Very minimal shared code for examples.
*/
(function() {
if (document.body) { setupEmbed(); }
else { document.addEventListener("DOMContentLoaded", setupEmbed); }
function setupEmbed() {
if (window.top != window) {
document.body.className += " embedded";
}
}
var o = window.examples = {};
o.showDistractor = function(id) {
var div = id ? document.getElementById(id) : document.querySelector("div canvas").parentNode;
div.className += " loading";
};
o.hideDistractor = function() {
var div = document.querySelector(".loading");
div.className = div.className.replace(/\bloading\b/);
};
})();
</script>
<style type="text/css">
body{ overflow-y:scroll; }
#template {
display: none;
}
#mainProgress {
width: auto;
height: 20px;
float: none;
position: relative;
}
#mainProgress LABEL {
position: absolute;
}
.item {
height: 170px;
width: 226px;
border: 1px solid #eee;
background-color: #ddd;
padding: 2px;
float: left;
position: relative;
text-align: center;
}
.item .progress {
width: 0;
height: 20px;
background-color: #9c9;
bottom: 0;
}
.complete {
}
.error {
background-color: #FAA;
}
.complete DIV, .error DIV {
display: none;
}
</style>
<script id="script_jtfdcr_imgs">
function jtfdcr(args) {
alert( "BUGS_102 jtfdcr args="+args );
var kolists = new Array;
kolists['jtfdcr'] = `
/fb/jtfdcr/pages/2751MR0144230271201284C00_DXXX_.jpg
/fb/jtfdcr/pages/AUT_0870.jpg
/fb/jtfdcr/pages/AUT_1342.jpg
/fb/jtfdcr/pages/AUT_1593.jpg
/fb/jtfdcr/pages/columbia_pw_adminiwii_ko2us.jpg
/fb/jtfdcr/pages/community_police.jpg
/fb/jtfdcr/pages/defford_boat.jpg
/fb/jtfdcr/pages/donutvanlaw_but_wiis_still_here_300.jpg
/fb/jtfdcr/pages/donutvanlaw_takings_all_took.jpg
/fb/jtfdcr/pages/jtfdc_enter_jtf31_streetswing_n_eagle.jpg
/fb/jtfdcr/pages/jtfdc_jtf30_located_on_private_cul_de_sac_IMG_9425.jpg
/fb/jtfdcr/pages/jtfdc_jtf31_takingIMG_8543.jpg
/fb/jtfdcr/pages/jtfdc_kouIMG_8561.jpg
/fb/jtfdcr/pages/jtfdc_sawhorse_winter.jpg
/fb/jtfdcr/pages/jtfdc_sawhorsey_flag_ngoIMG_9386_20190527_memorialday_flag.jpg
/fb/jtfdcr/pages/jtfdc_skyview.jpg
/fb/jtfdcr/pages/jtfdc_stalkaround_gannon.jpg
/fb/jtfdcr/pages/ladyj_clingyclothes.jpg
/fb/jtfdcr/pages/scale_flag.jpg
/fb/jtfdcr/pages/scale_gavel_book.jpg
/fb/jtfdcr/pages/scale_icon.jpg
/fb/jtfdcr/pages/snap_20170123_187555.jpg
/fb/jtfdcr/pages/snap_20170123_187556_jtf29_jtf38-39_byrd_segrist_tresspass_dog_assault.jpg
/fb/jtfdcr/pages/snap_20170123_187561_jtf29_jtf38-39_byrd_segrist_tresspass_threats2.jpg
/fb/jtfdcr/pages/snap_20170123_187562_jatf29_jtf38-29_byrd_seagrist_tresspass_trheats.jpg
/fb/jtfdcr/pages/snap_20170123_187569_jtf29_ljackmow_notresspas_per_new_jtfdc_trustyelder.jpg
/fb/jtfdcr/pages/snap_20170123_187575_jtf29_sawhorse_jtf31_theft.jpg
/fb/jtfdcr/pages/snap_20170123_187583_jtfdc_little_garbage.jpg
/fb/jtfdcr/pages/snap_20170123_187588.jpg
/fb/jtfdcr/pages/snap_20170123_187589_jtf31_jtfdc_noparking_party_sighn.jpg
/fb/jtfdcr/pages/snap_20170123_187593.jpg
/fb/jtfdcr/pages/snap_20170123_187600.jpg
/fb/jtfdcr/pages/snap_20170123_197519.jpg
/fb/jtfdcr/pages/snap_20170123_197537_map_jtfinc.jpg
/fb/jtfdcr/pages/snap_20170123_197539.jpg
/fb/jtfdcr/pages/snap_20170123_197540.jpg
/fb/jtfdcr/pages/snap_20170123_197541.jpg
/fb/jtfdcr/pages/snap_20170123_197542.jpg
/fb/jtfdcr/pages/snap_20170123_197545_jtf31-32_jtf29_easment.jpg
/fb/jtfdcr/pages/snap_20170123_197546.jpg
/fb/jtfdcr/pages/snap_20170123_197547.jpg
/fb/jtfdcr/pages/snap_20170123_197548.jpg
/fb/jtfdcr/pages/snap_20170123_197553.jpg
/fb/jtfdcr/pages/snap_20170123_197554_jtfinc_northeast.jpg
/fb/jtfdcr/pages/snap_20170123_197559.jpg
/fb/jtfdcr/pages/snap_20170123_197561.jpg
/fb/jtfdcr/pages/snap_20170123_197564.jpg
/fb/jtfdcr/pages/snap_20170123_197565.jpg
/fb/jtfdcr/pages/snap_20170123_197566.jpg
/fb/jtfdcr/pages/snap_20170123_197568.jpg
/fb/jtfdcr/pages/snap_20170123_197574_jtfdc_jtf2930_stlc_platt_easement_detail.jpg
/fb/jtfdcr/pages/tfdc_20170731_jtf29_mailbox_not_blocked_IMG_1048.jpg
/fb/jtfdcr/pages/topos_easements.jpg
/fb/jtfdcr/pages/zn_donutvanlaw_takings_all_took.jpg
`;
// alert( "BUGS_103 jtfdcr kolists_jtfdcr=" );
// alert( "BUGS_103 jtfdcr kolists_jtfdcr="+kolists['jtfdcr'] );
list=kolists['jtfdcr'].split("\n");
// alert( "BUGS_104 jtfdcr list="+list );
htmout = "";
htmout += '<div id="div_jtfdcr">';
htmout += ' <h1>div_jtfdcr Deffords Court est 1979</h1>';
for( j=0; j<list.length; j++ ) {
url=list[j];
htmout += '<a href="'+url+'" target=_blank>';
htmout += ' <img src="'+url+'" height=100 border=0 draggable="true" >';
htmout += ' </a>';
}
htmout += ' </div>';
if( document.getElementById('div_jtfdcr')) {
document.getElementById('div_jtfdcr').innerHTML=htmout;
}
alert( "BUGS_109 jtfdcr() END " );
// alert( 'BUGS_100 kolists_jtfdcr='+kolists['jtfdcr'];
}
</script>
<script id="script_startup_queue" >
function startup_queue(args) {
alert( "BUGS_101 startup_queue args="+args );
init();
alert( "BUGS_102 startup_queue args="+args );
jtfdcr(args);
alert( "BUGS_103 startup_queue args="+args );
}
</script>
</head>
<!-- <body bgcolor=wheat onload="init()"> -->
<body bgcolor=wheat onload="startup_queue('')">
<h1>jtfdc_stalkarounds 20200504</h1>
<hr color=white>
<hr color=white>
<br><br>
<img id="zm_takings_all_took" src="/fb/law/jkwiiv_byrdbell/zm/donutvanlaw_takings/TileGroup0/0-0-0.jpg" onclick="window.open('/fb/law/jkwiiv_byrdbell/zm/zm_donutvanlaw_takings.html');return false;" height=100 border=0 draggable="true">
       
<img id="zm_img_jtf2930" src="/fb/law/jkwiiv_byrdbell/zm/jtf2930/TileGroup0/0-0-0.jpg " onclick="window.open('/fb/law/jkwiiv_byrdbell/zm/zm_jtf2930.html');return false;" height=100 border=0 draggable="true">
       
<img id="zm_img_hrc2011" src="/zm/hrc2011/TileGroup0/0-0-0.jpg" onclick="window.open('/zm/zm_hrc2011.html');return false;" height=100 border=0 draggable="true">
<br><br>
<img src="/imgs/gif/notes/giphy_notes10.gif" alt="notes"
onclick="window.open('/txt/notes.txt');return false;"
height=75 border=0>
       
<img src="/imgs/gif/notes/giphy_notes03.gif" alt="ko_saic"
onclick="window.open('/txt/jtfdcr_mp4.txt');return false;"
height=75 border=0>
       
<div id="div_jtfdcr">
<h1>div_jtfdcr Deffords Court est 1979</h1>
<h2>offroad - private drive - no outlet</h2>
</div>
<hr color=black>
<hr color=black>
<img src="/fb/jtfdc/pages/1.jpg" alt="fb/jtfdc"
onclick="window.open('/fb/jtfdc/');return false;"
height=200 border=0>
       
<img src="/fb/jtfdcr/pages/1.jpg" alt="fb/jtfdcr"
onclick="window.open('/fb/jtfdcr');return false;"
height=200 border=0>
       
<img src="/fb/jtfinc/pages/1.jpg" alt="fb/jtfdcr"
onclick="window.open('/fb/jtfinc');return false;"
height=100 border=0>
       
       
<img src="/fb/stlc/pages/1.jpg" alt="fb/stlc"
onclick="window.open('/fb/stlc/');return false;"
height=200 border=0>
<br><br>
<hr color=linen>
<img src="/fb/law/tc/pages/1.jpg" alt="fb/law/tc"
onclick="window.open('/fb/law/tc/');return false;"
height=200 border=0>
       
<!--
<header class="PreloadJS">
<h1>Preload Queue</h1>
<p>Click "load another" to add another image the the overall queue. As
images are added, the preload progress reflects
the overall loaded progress. Click "load all" to queue everything at
once.
Note that when loading images and sounds locally, you need to ensure
that PreloadJS uses tag loading to avoid
cross-origin errors.</p>
</header>
-->
<div id="container" class="content">
<input type="button" id="loadAnotherBtn" value="Load Another"
disabled="disabled"/>
<input type="button" id="loadAllBtn" value="Load All" disabled="disabled"/>
<input type="button" id="reloadBtn" value="Reset"/>
<div id="mainProgress" class="item">
<label>Overall Progress</label>
<div class="progress"></div>
</div>
<hr/>
<!-- New items will get placed here -->
</div>
<!-- Item Template. This is cloned whenever we want a new one. -->
<div id="template" class="item">
<div class="progress"></div>
</div>
<!-- <script type="text/javascript" src="../lib/preloadjs-NEXT.combined.js"></script> -->
<!-- <script type="text/javascript" src="/jkwii/js/jsdoit/preload/lib/preloadjs-NEXT.combined.js"></script> -->
<script id="script_preloadjs_next_combined_js" >
/*!
* PreloadJS
* Visit http://createjs.com/ for documentation, updates and examples.
*
* Copyright (c) 2010 gskinner.com, inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//##############################################################################
// version.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
/**
* Static class holding library specific information such as the version and buildDate of the library.
* @class PreloadJS
**/
var s = createjs.PreloadJS = createjs.PreloadJS || {};
/**
* The version string for this release.
* @property version
* @type {String}
* @static
**/
s.version = /*=version*/"NEXT"; // injected by build process
/**
* The build date for this release in UTC format.
* @property buildDate
* @type {String}
* @static
**/
s.buildDate = /*=date*/"Fri, 02 Jan 2015 16:29:59 GMT"; // injected by build process
})();
//##############################################################################
// extend.js
//##############################################################################
this.createjs = this.createjs||{};
/**
* @class Utility Methods
*/
/**
* Sets up the prototype chain and constructor property for a new class.
*
* This should be called right after creating the class constructor.
*
* function MySubClass() {}
* createjs.extend(MySubClass, MySuperClass);
* ClassB.prototype.doSomething = function() { }
*
* var foo = new MySubClass();
* console.log(foo instanceof MySuperClass); // true
* console.log(foo.prototype.constructor === MySubClass); // true
*
* @method extend
* @param {Function} subclass The subclass.
* @param {Function} superclass The superclass to extend.
* @return {Function} Returns the subclass's new prototype.
*/
createjs.extend = function(subclass, superclass) {
"use strict";
function o() { this.constructor = subclass; }
o.prototype = superclass.prototype;
return (subclass.prototype = new o());
};
//##############################################################################
// promote.js
//##############################################################################
this.createjs = this.createjs||{};
/**
* @class Utility Methods
*/
/**
* Promotes any methods on the super class that were overridden, by creating an alias in the format `prefix_methodName`.
* It is recommended to use the super class's name as the prefix.
* An alias to the super class's constructor is always added in the format `prefix_constructor`.
* This allows the subclass to call super class methods without using `function.call`, providing better performance.
*
* For example, if `MySubClass` extends `MySuperClass`, and both define a `draw` method, then calling `promote(MySubClass, "MySuperClass")`
* would add a `MySuperClass_constructor` method to MySubClass and promote the `draw` method on `MySuperClass` to the
* prototype of `MySubClass` as `MySuperClass_draw`.
*
* This should be called after the class's prototype is fully defined.
*
* function ClassA(name) {
* this.name = name;
* }
* ClassA.prototype.greet = function() {
* return "Hello "+this.name;
* }
*
* function ClassB(name, punctuation) {
* this.ClassA_constructor(name);
* this.punctuation = punctuation;
* }
* createjs.extend(ClassB, ClassA);
* ClassB.prototype.greet = function() {
* return this.ClassA_greet()+this.punctuation;
* }
* createjs.promote(ClassB, "ClassA");
*
* var foo = new ClassB("World", "!?!");
* console.log(foo.greet()); // Hello World!?!
*
* @method promote
* @param {Function} subclass The class to promote super class methods on.
* @param {String} prefix The prefix to add to the promoted method names. Usually the name of the superclass.
* @return {Function} Returns the subclass.
*/
createjs.promote = function(subclass, prefix) {
"use strict";
var subP = subclass.prototype, supP = (Object.getPrototypeOf&&Object.getPrototypeOf(subP))||subP.__proto__;
if (supP) {
subP[(prefix+="_") + "constructor"] = supP.constructor; // constructor is not always innumerable
for (var n in supP) {
if (subP.hasOwnProperty(n) && (typeof supP[n] == "function")) { subP[prefix + n] = supP[n]; }
}
}
return subclass;
};
//##############################################################################
// indexOf.js
//##############################################################################
this.createjs = this.createjs||{};
/**
* @class Utility Methods
*/
/**
* Finds the first occurrence of a specified value searchElement in the passed in array, and returns the index of
* that value. Returns -1 if value is not found.
*
* var i = createjs.indexOf(myArray, myElementToFind);
*
* @method indexOf
* @param {Array} array Array to search for searchElement
* @param searchElement Element to find in array.
* @return {Number} The first index of searchElement in array.
*/
createjs.indexOf = function (array, searchElement){
"use strict";
for (var i = 0,l=array.length; i < l; i++) {
if (searchElement === array[i]) {
return i;
}
}
return -1;
};
//##############################################################################
// proxy.js
//##############################################################################
this.createjs = this.createjs||{};
/**
* Various utilities that the CreateJS Suite uses. Utilities are created as separate files, and will be available on the
* createjs namespace directly.
*
* <h4>Example</h4>
*
* myObject.addEventListener("change", createjs.proxy(myMethod, scope));
*
* @class Utility Methods
* @main Utility Methods
*/
(function() {
"use strict";
/**
* A function proxy for methods. By default, JavaScript methods do not maintain scope, so passing a method as a
* callback will result in the method getting called in the scope of the caller. Using a proxy ensures that the
* method gets called in the correct scope.
*
* Additional arguments can be passed that will be applied to the function when it is called.
*
* <h4>Example</h4>
*
* myObject.addEventListener("event", createjs.proxy(myHandler, this, arg1, arg2));
*
* function myHandler(arg1, arg2) {
* // This gets called when myObject.myCallback is executed.
* }
*
* @method proxy
* @param {Function} method The function to call
* @param {Object} scope The scope to call the method name on
* @param {mixed} [arg] * Arguments that are appended to the callback for additional params.
* @public
* @static
*/
createjs.proxy = function (method, scope) {
var aArgs = Array.prototype.slice.call(arguments, 2);
return function () {
return method.apply(scope, Array.prototype.slice.call(arguments, 0).concat(aArgs));
};
}
}());
//##############################################################################
// BrowserDetect.js
//##############################################################################
this.createjs = this.createjs||{};
/**
* @class Utility Methods
*/
(function() {
"use strict";
/**
* An object that determines the current browser, version, operating system, and other environment
* variables via user agent string.
*
* Used for audio because feature detection is unable to detect the many limitations of mobile devices.
*
* <h4>Example</h4>
*
* if (createjs.BrowserDetect.isIOS) { // do stuff }
*
* @property BrowserDetect
* @type {Object}
* @param {Boolean} isFirefox True if our browser is Firefox.
* @param {Boolean} isOpera True if our browser is opera.
* @param {Boolean} isChrome True if our browser is Chrome. Note that Chrome for Android returns true, but is a
* completely different browser with different abilities.
* @param {Boolean} isIOS True if our browser is safari for iOS devices (iPad, iPhone, and iPod).
* @param {Boolean} isAndroid True if our browser is Android.
* @param {Boolean} isBlackberry True if our browser is Blackberry.
* @constructor
* @static
*/
function BrowserDetect() {
throw "BrowserDetect cannot be instantiated";
};
var agent = BrowserDetect.agent = window.navigator.userAgent;
BrowserDetect.isWindowPhone = (agent.indexOf("IEMobile") > -1) || (agent.indexOf("Windows Phone") > -1);
BrowserDetect.isFirefox = (agent.indexOf("Firefox") > -1);
BrowserDetect.isOpera = (window.opera != null);
BrowserDetect.isChrome = (agent.indexOf("Chrome") > -1); // NOTE that Chrome on Android returns true but is a completely different browser with different abilities
BrowserDetect.isIOS = (agent.indexOf("iPod") > -1 || agent.indexOf("iPhone") > -1 || agent.indexOf("iPad") > -1) && !BrowserDetect.isWindowPhone;
BrowserDetect.isAndroid = (agent.indexOf("Android") > -1) && !BrowserDetect.isWindowPhone;
BrowserDetect.isBlackberry = (agent.indexOf("Blackberry") > -1);
createjs.BrowserDetect = BrowserDetect;
}());
//##############################################################################
// Event.js
//##############################################################################
this.createjs = this.createjs||{};
(function() {
"use strict";
// constructor:
/**
* Contains properties and methods shared by all events for use with
* {{#crossLink "EventDispatcher"}}{{/crossLink}}.
*
* Note that Event objects are often reused, so you should never
* rely on an event object's state outside of the call stack it was received in.
* @class Event
* @param {String} type The event type.
* @param {Boolean} bubbles Indicates whether the event will bubble through the display list.
* @param {Boolean} cancelable Indicates whether the default behaviour of this event can be cancelled.
* @constructor
**/
function Event(type, bubbles, cancelable) {
// public properties:
/**
* The type of event.
* @property type
* @type String
**/
this.type = type;
/**
* The object that generated an event.
* @property target
* @type Object
* @default null
* @readonly
*/
this.target = null;
/**
* The current target that a bubbling event is being dispatched from. For non-bubbling events, this will
* always be the same as target. For example, if childObj.parent = parentObj, and a bubbling event
* is generated from childObj, then a listener on parentObj would receive the event with
* target=childObj (the original target) and currentTarget=parentObj (where the listener was added).
* @property currentTarget
* @type Object
* @default null
* @readonly
*/
this.currentTarget = null;
/**
* For bubbling events, this indicates the current event phase:<OL>
* <LI> capture phase: starting from the top parent to the target</LI>
* <LI> at target phase: currently being dispatched from the target</LI>
* <LI> bubbling phase: from the target to the top parent</LI>
* </OL>
* @property eventPhase
* @type Number
* @default 0
* @readonly
*/
this.eventPhase = 0;
/**
* Indicates whether the event will bubble through the display list.
* @property bubbles
* @type Boolean
* @default false
* @readonly
*/
this.bubbles = !!bubbles;
/**
* Indicates whether the default behaviour of this event can be cancelled via
* {{#crossLink "Event/preventDefault"}}{{/crossLink}}. This is set via the Event constructor.
* @property cancelable
* @type Boolean
* @default false
* @readonly
*/
this.cancelable = !!cancelable;
/**
* The epoch time at which this event was created.
* @property timeStamp
* @type Number
* @default 0
* @readonly
*/
this.timeStamp = (new Date()).getTime();
/**
* Indicates if {{#crossLink "Event/preventDefault"}}{{/crossLink}} has been called
* on this event.
* @property defaultPrevented
* @type Boolean
* @default false
* @readonly
*/
this.defaultPrevented = false;
/**
* Indicates if {{#crossLink "Event/stopPropagation"}}{{/crossLink}} or
* {{#crossLink "Event/stopImmediatePropagation"}}{{/crossLink}} has been called on this event.
* @property propagationStopped
* @type Boolean
* @default false
* @readonly
*/
this.propagationStopped = false;
/**
* Indicates if {{#crossLink "Event/stopImmediatePropagation"}}{{/crossLink}} has been called
* on this event.
* @property immediatePropagationStopped
* @type Boolean
* @default false
* @readonly
*/
this.immediatePropagationStopped = false;
/**
* Indicates if {{#crossLink "Event/remove"}}{{/crossLink}} has been called on this event.
* @property removed
* @type Boolean
* @default false
* @readonly
*/
this.removed = false;
}
var p = Event.prototype;
/**
* <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
* See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
* for details.
*
* There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
*
* @method initialize
* @protected
* @deprecated
*/
// p.initialize = function() {}; // searchable for devs wondering where it is.
// public methods:
/**
* Sets {{#crossLink "Event/defaultPrevented"}}{{/crossLink}} to true.
* Mirrors the DOM event standard.
* @method preventDefault
**/
p.preventDefault = function() {
this.defaultPrevented = this.cancelable&&true;
};
/**
* Sets {{#crossLink "Event/propagationStopped"}}{{/crossLink}} to true.
* Mirrors the DOM event standard.
* @method stopPropagation
**/
p.stopPropagation = function() {
this.propagationStopped = true;
};
/**
* Sets {{#crossLink "Event/propagationStopped"}}{{/crossLink}} and
* {{#crossLink "Event/immediatePropagationStopped"}}{{/crossLink}} to true.
* Mirrors the DOM event standard.
* @method stopImmediatePropagation
**/
p.stopImmediatePropagation = function() {
this.immediatePropagationStopped = this.propagationStopped = true;
};
/**
* Causes the active listener to be removed via removeEventListener();
*
* myBtn.addEventListener("click", function(evt) {
* // do stuff...
* evt.remove(); // removes this listener.
* });
*
* @method remove
**/
p.remove = function() {
this.removed = true;
};
/**
* Returns a clone of the Event instance.
* @method clone
* @return {Event} a clone of the Event instance.
**/
p.clone = function() {
return new Event(this.type, this.bubbles, this.cancelable);
};
/**
* Provides a chainable shortcut method for setting a number of properties on the instance.
*
* @method set
* @param {Object} props A generic object containing properties to copy to the instance.
* @return {Event} Returns the instance the method is called on (useful for chaining calls.)
* @chainable
*/
p.set = function(props) {
for (var n in props) { this[n] = props[n]; }
return this;
};
/**
* Returns a string representation of this object.
* @method toString
* @return {String} a string representation of the instance.
**/
p.toString = function() {
return "[Event (type="+this.type+")]";
};
createjs.Event = Event;
}());
//##############################################################################
// ErrorEvent.js
//##############################################################################
this.createjs = this.createjs||{};
(function() {
"use strict";
/**
* A general error {{#crossLink "Event"}}{{/crossLink}}, that describes an error that occurred, as well as any details.
* @class ErrorEvent
* @param {String} [title] The error title
* @param {String} [message] The error description
* @param {Object} [data] Additional error data
* @constructor
*/
function ErrorEvent(title, message, data) {
this.Event_constructor("error");
/**
* The short error title, which indicates the type of error that occurred.
* @property title
* @type String
*/
this.title = title;
/**
* The verbose error message, containing details about the error.
* @property message
* @type String
*/
this.message = message;
/**
* Additional data attached to an error.
* @property data
* @type {Object}
*/
this.data = data;
}
var p = createjs.extend(ErrorEvent, createjs.Event);
p.clone = function() {
return new createjs.ErrorEvent(this.title, this.message, this.data);
};
createjs.ErrorEvent = createjs.promote(ErrorEvent, "Event");
}());
//##############################################################################
// EventDispatcher.js
//##############################################################################
this.createjs = this.createjs||{};
(function() {
"use strict";
// constructor:
/**
* EventDispatcher provides methods for managing queues of event listeners and dispatching events.
*
* You can either extend EventDispatcher or mix its methods into an existing prototype or instance by using the
* EventDispatcher {{#crossLink "EventDispatcher/initialize"}}{{/crossLink}} method.
*
* Together with the CreateJS Event class, EventDispatcher provides an extended event model that is based on the
* DOM Level 2 event model, including addEventListener, removeEventListener, and dispatchEvent. It supports
* bubbling / capture, preventDefault, stopPropagation, stopImmediatePropagation, and handleEvent.
*
* EventDispatcher also exposes a {{#crossLink "EventDispatcher/on"}}{{/crossLink}} method, which makes it easier
* to create scoped listeners, listeners that only run once, and listeners with associated arbitrary data. The
* {{#crossLink "EventDispatcher/off"}}{{/crossLink}} method is merely an alias to
* {{#crossLink "EventDispatcher/removeEventListener"}}{{/crossLink}}.
*
* Another addition to the DOM Level 2 model is the {{#crossLink "EventDispatcher/removeAllEventListeners"}}{{/crossLink}}
* method, which can be used to listeners for all events, or listeners for a specific event. The Event object also
* includes a {{#crossLink "Event/remove"}}{{/crossLink}} method which removes the active listener.
*
* <h4>Example</h4>
* Add EventDispatcher capabilities to the "MyClass" class.
*
* EventDispatcher.initialize(MyClass.prototype);
*
* Add an event (see {{#crossLink "EventDispatcher/addEventListener"}}{{/crossLink}}).
*
* instance.addEventListener("eventName", handlerMethod);
* function handlerMethod(event) {
* console.log(event.target + " Was Clicked");
* }
*
* <b>Maintaining proper scope</b><br />
* Scope (ie. "this") can be be a challenge with events. Using the {{#crossLink "EventDispatcher/on"}}{{/crossLink}}
* method to subscribe to events simplifies this.
*
* instance.addEventListener("click", function(event) {
* console.log(instance == this); // false, scope is ambiguous.
* });
*
* instance.on("click", function(event) {
* console.log(instance == this); // true, "on" uses dispatcher scope by default.
* });
*
* If you want to use addEventListener instead, you may want to use function.bind() or a similar proxy to manage scope.
*
*
* @class EventDispatcher
* @constructor
**/
function EventDispatcher() {
// private properties:
/**
* @protected
* @property _listeners
* @type Object
**/
this._listeners = null;
/**
* @protected
* @property _captureListeners
* @type Object
**/
this._captureListeners = null;
}
var p = EventDispatcher.prototype;
/**
* <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
* See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
* for details.
*
* There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
*
* @method initialize
* @protected
* @deprecated
*/
// p.initialize = function() {}; // searchable for devs wondering where it is.
// static public methods:
/**
* Static initializer to mix EventDispatcher methods into a target object or prototype.
*
* EventDispatcher.initialize(MyClass.prototype); // add to the prototype of the class
* EventDispatcher.initialize(myObject); // add to a specific instance
*
* @method initialize
* @static
* @param {Object} target The target object to inject EventDispatcher methods into. This can be an instance or a
* prototype.
**/
EventDispatcher.initialize = function(target) {
target.addEventListener = p.addEventListener;
target.on = p.on;
target.removeEventListener = target.off = p.removeEventListener;
target.removeAllEventListeners = p.removeAllEventListeners;
target.hasEventListener = p.hasEventListener;
target.dispatchEvent = p.dispatchEvent;
target._dispatchEvent = p._dispatchEvent;
target.willTrigger = p.willTrigger;
};
// public methods:
/**
* Adds the specified event listener. Note that adding multiple listeners to the same function will result in
* multiple callbacks getting fired.
*
* <h4>Example</h4>
*
* displayObject.addEventListener("click", handleClick);
* function handleClick(event) {
* // Click happened.
* }
*
* @method addEventListener
* @param {String} type The string type of the event.
* @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when
* the event is dispatched.
* @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
* @return {Function | Object} Returns the listener for chaining or assignment.
**/
p.addEventListener = function(type, listener, useCapture) {
var listeners;
if (useCapture) {
listeners = this._captureListeners = this._captureListeners||{};
} else {
listeners = this._listeners = this._listeners||{};
}
var arr = listeners[type];
if (arr) { this.removeEventListener(type, listener, useCapture); }
arr = listeners[type]; // remove may have deleted the array
if (!arr) { listeners[type] = [listener]; }
else { arr.push(listener); }
return listener;
};
/**
* A shortcut method for using addEventListener that makes it easier to specify an execution scope, have a listener
* only run once, associate arbitrary data with the listener, and remove the listener.
*
* This method works by creating an anonymous wrapper function and subscribing it with addEventListener.
* The created anonymous function is returned for use with .removeEventListener (or .off).
*
* <h4>Example</h4>
*
* var listener = myBtn.on("click", handleClick, null, false, {count:3});
* function handleClick(evt, data) {
* data.count -= 1;
* console.log(this == myBtn); // true - scope defaults to the dispatcher
* if (data.count == 0) {
* alert("clicked 3 times!");
* myBtn.off("click", listener);
* // alternately: evt.remove();
* }
* }
*
* @method on
* @param {String} type The string type of the event.
* @param {Function | Object} listener An object with a handleEvent method, or a function that will be called when
* the event is dispatched.
* @param {Object} [scope] The scope to execute the listener in. Defaults to the dispatcher/currentTarget for function listeners, and to the listener itself for object listeners (ie. using handleEvent).
* @param {Boolean} [once=false] If true, the listener will remove itself after the first time it is triggered.
* @param {*} [data] Arbitrary data that will be included as the second parameter when the listener is called.
* @param {Boolean} [useCapture=false] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
* @return {Function} Returns the anonymous function that was created and assigned as the listener. This is needed to remove the listener later using .removeEventListener.
**/
p.on = function(type, listener, scope, once, data, useCapture) {
if (listener.handleEvent) {
scope = scope||listener;
listener = listener.handleEvent;
}
scope = scope||this;
return this.addEventListener(type, function(evt) {
listener.call(scope, evt, data);
once&&evt.remove();
}, useCapture);
};
/**
* Removes the specified event listener.
*
* <b>Important Note:</b> that you must pass the exact function reference used when the event was added. If a proxy
* function, or function closure is used as the callback, the proxy/closure reference must be used - a new proxy or
* closure will not work.
*
* <h4>Example</h4>
*
* displayObject.removeEventListener("click", handleClick);
*
* @method removeEventListener
* @param {String} type The string type of the event.
* @param {Function | Object} listener The listener function or object.
* @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
**/
p.removeEventListener = function(type, listener, useCapture) {
var listeners = useCapture ? this._captureListeners : this._listeners;
if (!listeners) { return; }
var arr = listeners[type];
if (!arr) { return; }
for (var i=0,l=arr.length; i<l; i++) {
if (arr[i] == listener) {
if (l==1) { delete(listeners[type]); } // allows for faster checks.
else { arr.splice(i,1); }
break;
}
}
};
/**
* A shortcut to the removeEventListener method, with the same parameters and return value. This is a companion to the
* .on method.
*
* @method off
* @param {String} type The string type of the event.
* @param {Function | Object} listener The listener function or object.
* @param {Boolean} [useCapture] For events that bubble, indicates whether to listen for the event in the capture or bubbling/target phase.
**/
p.off = p.removeEventListener;
/**
* Removes all listeners for the specified type, or all listeners of all types.
*
* <h4>Example</h4>
*
* // Remove all listeners
* displayObject.removeAllEventListeners();
*
* // Remove all click listeners
* displayObject.removeAllEventListeners("click");
*
* @method removeAllEventListeners
* @param {String} [type] The string type of the event. If omitted, all listeners for all types will be removed.
**/
p.removeAllEventListeners = function(type) {
if (!type) { this._listeners = this._captureListeners = null; }
else {
if (this._listeners) { delete(this._listeners[type]); }
if (this._captureListeners) { delete(this._captureListeners[type]); }
}
};
/**
* Dispatches the specified event to all listeners.
*
* <h4>Example</h4>
*
* // Use a string event
* this.dispatchEvent("complete");
*
* // Use an Event instance
* var event = new createjs.Event("progress");
* this.dispatchEvent(event);
*
* @method dispatchEvent
* @param {Object | String | Event} eventObj An object with a "type" property, or a string type.
* While a generic object will work, it is recommended to use a CreateJS Event instance. If a string is used,
* dispatchEvent will construct an Event instance with the specified type.
* @return {Boolean} Returns the value of eventObj.defaultPrevented.
**/
p.dispatchEvent = function(eventObj) {
if (typeof eventObj == "string") {
// won't bubble, so skip everything if there's no listeners:
var listeners = this._listeners;
if (!listeners || !listeners[eventObj]) { return false; }
eventObj = new createjs.Event(eventObj);
} else if (eventObj.target && eventObj.clone) {
// redispatching an active event object, so clone it:
eventObj = eventObj.clone();
}
try { eventObj.target = this; } catch (e) {} // try/catch allows redispatching of native events
if (!eventObj.bubbles || !this.parent) {
this._dispatchEvent(eventObj, 2);
} else {
var top=this, list=[top];
while (top.parent) { list.push(top = top.parent); }
var i, l=list.length;
// capture & atTarget
for (i=l-1; i>=0 && !eventObj.propagationStopped; i--) {
list[i]._dispatchEvent(eventObj, 1+(i==0));
}
// bubbling
for (i=1; i<l && !eventObj.propagationStopped; i++) {
list[i]._dispatchEvent(eventObj, 3);
}
}
return eventObj.defaultPrevented;
};
/**
* Indicates whether there is at least one listener for the specified event type.
* @method hasEventListener
* @param {String} type The string type of the event.
* @return {Boolean} Returns true if there is at least one listener for the specified event.
**/
p.hasEventListener = function(type) {
var listeners = this._listeners, captureListeners = this._captureListeners;
return !!((listeners && listeners[type]) || (captureListeners && captureListeners[type]));
};
/**
* Indicates whether there is at least one listener for the specified event type on this object or any of its
* ancestors (parent, parent's parent, etc). A return value of true indicates that if a bubbling event of the
* specified type is dispatched from this object, it will trigger at least one listener.
*
* This is similar to {{#crossLink "EventDispatcher/hasEventListener"}}{{/crossLink}}, but it searches the entire
* event flow for a listener, not just this object.
* @method willTrigger
* @param {String} type The string type of the event.
* @return {Boolean} Returns `true` if there is at least one listener for the specified event.
**/
p.willTrigger = function(type) {
var o = this;
while (o) {
if (o.hasEventListener(type)) { return true; }
o = o.parent;
}
return false;
};
/**
* @method toString
* @return {String} a string representation of the instance.
**/
p.toString = function() {
return "[EventDispatcher]";
};
// private methods:
/**
* @method _dispatchEvent
* @param {Object | String | Event} eventObj
* @param {Object} eventPhase
* @protected
**/
p._dispatchEvent = function(eventObj, eventPhase) {
var l, listeners = (eventPhase==1) ? this._captureListeners : this._listeners;
if (eventObj && listeners) {
var arr = listeners[eventObj.type];
if (!arr||!(l=arr.length)) { return; }
try { eventObj.currentTarget = this; } catch (e) {}
try { eventObj.eventPhase = eventPhase; } catch (e) {}
eventObj.removed = false;
arr = arr.slice(); // to avoid issues with items being removed or added during the dispatch
for (var i=0; i<l && !eventObj.immediatePropagationStopped; i++) {
var o = arr[i];
if (o.handleEvent) { o.handleEvent(eventObj); }
else { o(eventObj); }
if (eventObj.removed) {
this.off(eventObj.type, o, eventPhase==1);
eventObj.removed = false;
}
}
}
};
createjs.EventDispatcher = EventDispatcher;
}());
//##############################################################################
// ProgressEvent.js
//##############################################################################
this.createjs = this.createjs || {};
(function (scope) {
"use strict";
// constructor
/**
* A createjs {{#crossLink "Event"}}{{/crossLink}} that is dispatched when progress changes.
* @class ProgressEvent
* @param {Number} loaded The amount that has been loaded. This can be any number relative to the total.
* @param {Number} [total] The total amount that will load. This will default to 0, so does not need to be passed in,
* as long as the loaded value is a progress value (between 0 and 1).
* @todo Consider having this event be a "fileprogress" event as well
* @constructor
*/
function ProgressEvent(loaded, total) {
this.Event_constructor("progress");
/**
* The amount that has been loaded (out of a total amount)
* @property loaded
* @type {Number}
*/
this.loaded = loaded;
/**
* The total "size" of the load.
* @property total
* @type {Number}
* @default 1
*/
this.total = (total == null) ? 1 : total;
/**
* The percentage (out of 1) that the load has been completed. This is calculated using `loaded/total`.
* @property progress
* @type {Number}
* @default 0
*/
this.progress = (total == 0) ? 0 : this.loaded / this.total;
};
var p = createjs.extend(ProgressEvent, createjs.Event);
/**
* Returns a clone of the ProgressEvent instance.
* @method clone
* @return {ProgressEvent} a clone of the Event instance.
**/
p.clone = function() {
return new createjs.ProgressEvent(this.loaded, this.total);
};
createjs.ProgressEvent = createjs.promote(ProgressEvent, "Event");
}(window));
//##############################################################################
// json3.js
//##############################################################################
/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */
;(function () {
// Detect the `define` function exposed by asynchronous module loaders. The
// strict `define` check is necessary for compatibility with `r.js`.
var isLoader = typeof define === "function" && define.amd;
// A set of types used to distinguish objects from primitives.
var objectTypes = {
"function": true,
"object": true
};
// Detect the `exports` object exposed by CommonJS implementations.
var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
// Use the `global` object exposed by Node (including Browserify via
// `insert-module-globals`), Narwhal, and Ringo as the default context,
// and the `window` object in browsers. Rhino exports a `global` function
// instead.
var root = objectTypes[typeof window] && window || this,
freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == "object" && global;
if (freeGlobal && (freeGlobal["global"] === freeGlobal || freeGlobal["window"] === freeGlobal || freeGlobal["self"] === freeGlobal)) {
root = freeGlobal;
}
// Public: Initializes JSON 3 using the given `context` object, attaching the
// `stringify` and `parse` functions to the specified `exports` object.
function runInContext(context, exports) {
context || (context = root["Object"]());
exports || (exports = root["Object"]());
// Native constructor aliases.
var Number = context["Number"] || root["Number"],
String = context["String"] || root["String"],
Object = context["Object"] || root["Object"],
Date = context["Date"] || root["Date"],
SyntaxError = context["SyntaxError"] || root["SyntaxError"],
TypeError = context["TypeError"] || root["TypeError"],
Math = context["Math"] || root["Math"],
nativeJSON = context["JSON"] || root["JSON"];
// Delegate to the native `stringify` and `parse` implementations.
if (typeof nativeJSON == "object" && nativeJSON) {
exports.stringify = nativeJSON.stringify;
exports.parse = nativeJSON.parse;
}
// Convenience aliases.
var objectProto = Object.prototype,
getClass = objectProto.toString,
isProperty, forEach, undef;
// Test the `Date#getUTC*` methods. Based on work by @Yaffle.
var isExtended = new Date(-3509827334573292);
try {
// The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical
// results for certain dates in Opera >= 10.53.
isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&
// Safari < 2.0.2 stores the internal millisecond time value correctly,
// but clips the values returned by the date methods to the range of
// signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).
isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;
} catch (exception) {}
// Internal: Determines whether the native `JSON.stringify` and `parse`
// implementations are spec-compliant. Based on work by Ken Snyder.
function has(name) {
if (has[name] !== undef) {
// Return cached feature test result.
return has[name];
}
var isSupported;
if (name == "bug-string-char-index") {
// IE <= 7 doesn't support accessing string characters using square
// bracket notation. IE 8 only supports this for primitives.
isSupported = "a"[0] != "a";
} else if (name == "json") {
// Indicates whether both `JSON.stringify` and `JSON.parse` are
// supported.
isSupported = has("json-stringify") && has("json-parse");
} else {
var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';
// Test `JSON.stringify`.
if (name == "json-stringify") {
var stringify = exports.stringify, stringifySupported = typeof stringify == "function" && isExtended;
if (stringifySupported) {
// A test function object with a custom `toJSON` method.
(value = function () {
return 1;
}).toJSON = value;
try {
stringifySupported =
// Firefox 3.1b1 and b2 serialize string, number, and boolean
// primitives as object literals.
stringify(0) === "0" &&
// FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object
// literals.
stringify(new Number()) === "0" &&
stringify(new String()) == '""' &&
// FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or
// does not define a canonical JSON representation (this applies to
// objects with `toJSON` properties as well, *unless* they are nested
// within an object or array).
stringify(getClass) === undef &&
// IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and
// FF 3.1b3 pass this test.
stringify(undef) === undef &&
// Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,
// respectively, if the value is omitted entirely.
stringify() === undef &&
// FF 3.1b1, 2 throw an error if the given value is not a number,
// string, array, object, Boolean, or `null` literal. This applies to
// objects with custom `toJSON` methods as well, unless they are nested
// inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`
// methods entirely.
stringify(value) === "1" &&
stringify([value]) == "[1]" &&
// Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of
// `"[null]"`.
stringify([undef]) == "[null]" &&
// YUI 3.0.0b1 fails to serialize `null` literals.
stringify(null) == "null" &&
// FF 3.1b1, 2 halts serialization if an array contains a function:
// `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3
// elides non-JSON values from objects and arrays, unless they
// define custom `toJSON` methods.
stringify([undef, getClass, null]) == "[null,null,null]" &&
// Simple serialization test. FF 3.1b1 uses Unicode escape sequences
// where character escape codes are expected (e.g., `\b` => `\u0008`).
stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized &&
// FF 3.1b1 and b2 ignore the `filter` and `width` arguments.
stringify(null, value) === "1" &&
stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" &&
// JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly
// serialize extended years.
stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' &&
// The milliseconds are optional in ES 5, but required in 5.1.
stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' &&
// Firefox <= 11.0 incorrectly serializes years prior to 0 as negative
// four-digit years instead of six-digit years. Credits: @Yaffle.
stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' &&
// Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond
// values less than 1000. Credits: @Yaffle.
stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"';
} catch (exception) {
stringifySupported = false;
}
}
isSupported = stringifySupported;
}
// Test `JSON.parse`.
if (name == "json-parse") {
var parse = exports.parse;
if (typeof parse == "function") {
try {
// FF 3.1b1, b2 will throw an exception if a bare literal is provided.
// Conforming implementations should also coerce the initial argument to
// a string prior to parsing.
if (parse("0") === 0 && !parse(false)) {
// Simple parsing test.
value = parse(serialized);
var parseSupported = value["a"].length == 5 && value["a"][0] === 1;
if (parseSupported) {
try {
// Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.
parseSupported = !parse('"\t"');
} catch (exception) {}
if (parseSupported) {
try {
// FF 4.0 and 4.0.1 allow leading `+` signs and leading
// decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow
// certain octal literals.
parseSupported = parse("01") !== 1;
} catch (exception) {}
}
if (parseSupported) {
try {
// FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal
// points. These environments, along with FF 3.1b1 and 2,
// also allow trailing commas in JSON objects and arrays.
parseSupported = parse("1.") !== 1;
} catch (exception) {}
}
}
}
} catch (exception) {
parseSupported = false;
}
}
isSupported = parseSupported;
}
}
return has[name] = !!isSupported;
}
if (!has("json")) {
// Common `[[Class]]` name aliases.
var functionClass = "[object Function]",
dateClass = "[object Date]",
numberClass = "[object Number]",
stringClass = "[object String]",
arrayClass = "[object Array]",
booleanClass = "[object Boolean]";
// Detect incomplete support for accessing string characters by index.
var charIndexBuggy = has("bug-string-char-index");
// Define additional utility methods if the `Date` methods are buggy.
if (!isExtended) {
var floor = Math.floor;
// A mapping between the months of the year and the number of days between
// January 1st and the first of the respective month.
var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
// Internal: Calculates the number of days between the Unix epoch and the
// first day of the given month.
var getDay = function (year, month) {
return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);
};
}
// Internal: Determines if a property is a direct property of the given
// object. Delegates to the native `Object#hasOwnProperty` method.
if (!(isProperty = objectProto.hasOwnProperty)) {
isProperty = function (property) {
var members = {}, constructor;
if ((members.__proto__ = null, members.__proto__ = {
// The *proto* property cannot be set multiple times in recent
// versions of Firefox and SeaMonkey.
"toString": 1
}, members).toString != getClass) {
// Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but
// supports the mutable *proto* property.
isProperty = function (property) {
// Capture and break the object's prototype chain (see section 8.6.2
// of the ES 5.1 spec). The parenthesized expression prevents an
// unsafe transformation by the Closure Compiler.
var original = this.__proto__, result = property in (this.__proto__ = null, this);
// Restore the original prototype chain.
this.__proto__ = original;
return result;
};
} else {
// Capture a reference to the top-level `Object` constructor.
constructor = members.constructor;
// Use the `constructor` property to simulate `Object#hasOwnProperty` in
// other environments.
isProperty = function (property) {
var parent = (this.constructor || constructor).prototype;
return property in this && !(property in parent && this[property] === parent[property]);
};
}
members = null;
return isProperty.call(this, property);
};
}
// Internal: Normalizes the `for...in` iteration algorithm across
// environments. Each enumerated key is yielded to a `callback` function.
forEach = function (object, callback) {
var size = 0, Properties, members, property;
// Tests for bugs in the current environment's `for...in` algorithm. The
// `valueOf` property inherits the non-enumerable flag from
// `Object.prototype` in older versions of IE, Netscape, and Mozilla.
(Properties = function () {
this.valueOf = 0;
}).prototype.valueOf = 0;
// Iterate over a new instance of the `Properties` class.
members = new Properties();
for (property in members) {
// Ignore all properties inherited from `Object.prototype`.
if (isProperty.call(members, property)) {
size++;
}
}
Properties = members = null;
// Normalize the iteration algorithm.
if (!size) {
// A list of non-enumerable properties inherited from `Object.prototype`.
members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"];
// IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable
// properties.
forEach = function (object, callback) {
var isFunction = getClass.call(object) == functionClass, property, length;
var hasProperty = !isFunction && typeof object.constructor != "function" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty;
for (property in object) {
// Gecko <= 1.0 enumerates the `prototype` property of functions under
// certain conditions; IE does not.
if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) {
callback(property);
}
}
// Manually invoke the callback for each non-enumerable property.
for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property));
};
} else if (size == 2) {
// Safari <= 2.0.4 enumerates shadowed properties twice.
forEach = function (object, callback) {
// Create a set of iterated properties.
var members = {}, isFunction = getClass.call(object) == functionClass, property;
for (property in object) {
// Store each property name to prevent double enumeration. The
// `prototype` property of functions is not enumerated due to cross-
// environment inconsistencies.
if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {
callback(property);
}
}
};
} else {
// No bugs detected; use the standard `for...in` algorithm.
forEach = function (object, callback) {
var isFunction = getClass.call(object) == functionClass, property, isConstructor;
for (property in object) {
if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) {
callback(property);
}
}
// Manually invoke the callback for the `constructor` property due to
// cross-environment inconsistencies.
if (isConstructor || isProperty.call(object, (property = "constructor"))) {
callback(property);
}
};
}
return forEach(object, callback);
};
// Public: Serializes a JavaScript `value` as a JSON string. The optional
// `filter` argument may specify either a function that alters how object and
// array members are serialized, or an array of strings and numbers that
// indicates which properties should be serialized. The optional `width`
// argument may be either a string or number that specifies the indentation
// level of the output.
if (!has("json-stringify")) {
// Internal: A map of control characters and their escaped equivalents.
var Escapes = {
92: "\\\\",
34: '\\"',
8: "\\b",
12: "\\f",
10: "\\n",
13: "\\r",
9: "\\t"
};
// Internal: Converts `value` into a zero-padded string such that its
// length is at least equal to `width`. The `width` must be <= 6.
var leadingZeroes = "000000";
var toPaddedString = function (width, value) {
// The `|| 0` expression is necessary to work around a bug in
// Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`.
return (leadingZeroes + (value || 0)).slice(-width);
};
// Internal: Double-quotes a string `value`, replacing all ASCII control
// characters (characters with code unit values between 0 and 31) with
// their escaped equivalents. This is an implementation of the
// `Quote(value)` operation defined in ES 5.1 section 15.12.3.
var unicodePrefix = "\\u00";
var quote = function (value) {
var result = '"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10;
var symbols = useCharIndex && (charIndexBuggy ? value.split("") : value);
for (; index < length; index++) {
var charCode = value.charCodeAt(index);
// If the character is a control character, append its Unicode or
// shorthand escape sequence; otherwise, append the character as-is.
switch (charCode) {
case 8: case 9: case 10: case 12: case 13: case 34: case 92:
result += Escapes[charCode];
break;
default:
if (charCode < 32) {
result += unicodePrefix + toPaddedString(2, charCode.toString(16));
break;
}
result += useCharIndex ? symbols[index] : value.charAt(index);
}
}
return result + '"';
};
// Internal: Recursively serializes an object. Implements the
// `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.
var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {
var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;
try {
// Necessary for host object support.
value = object[property];
} catch (exception) {}
if (typeof value == "object" && value) {
className = getClass.call(value);
if (className == dateClass && !isProperty.call(value, "toJSON")) {
if (value > -1 / 0 && value < 1 / 0) {
// Dates are serialized according to the `Date#toJSON` method
// specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15
// for the ISO 8601 date time string format.
if (getDay) {
// Manually compute the year, month, date, hours, minutes,
// seconds, and milliseconds if the `getUTC*` methods are
// buggy. Adapted from @Yaffle's `date-shim` project.
date = floor(value / 864e5);
for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);
for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);
date = 1 + date - getDay(year, month);
// The `time` value specifies the time within the day (see ES
// 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used
// to compute `A modulo B`, as the `%` operator does not
// correspond to the `modulo` operation for negative numbers.
time = (value % 864e5 + 864e5) % 864e5;
// The hours, minutes, seconds, and milliseconds are obtained by
// decomposing the time within the day. See section 15.9.1.10.
hours = floor(time / 36e5) % 24;
minutes = floor(time / 6e4) % 60;
seconds = floor(time / 1e3) % 60;
milliseconds = time % 1e3;
} else {
year = value.getUTCFullYear();
month = value.getUTCMonth();
date = value.getUTCDate();
hours = value.getUTCHours();
minutes = value.getUTCMinutes();
seconds = value.getUTCSeconds();
milliseconds = value.getUTCMilliseconds();
}
// Serialize extended years correctly.
value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +
"-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) +
// Months, dates, hours, minutes, and seconds should have two
// digits; milliseconds should have three.
"T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) +
// Milliseconds are optional in ES 5.0, but required in 5.1.
"." + toPaddedString(3, milliseconds) + "Z";
} else {
value = null;
}
} else if (typeof value.toJSON == "function" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, "toJSON"))) {
// Prototype <= 1.6.1 adds non-standard `toJSON` methods to the
// `Number`, `String`, `Date`, and `Array` prototypes. JSON 3
// ignores all `toJSON` methods on these objects unless they are
// defined directly on an instance.
value = value.toJSON(property);
}
}
if (callback) {
// If a replacement function was provided, call it to obtain the value
// for serialization.
value = callback.call(object, property, value);
}
if (value === null) {
return "null";
}
className = getClass.call(value);
if (className == booleanClass) {
// Booleans are represented literally.
return "" + value;
} else if (className == numberClass) {
// JSON numbers must be finite. `Infinity` and `NaN` are serialized as
// `"null"`.
return value > -1 / 0 && value < 1 / 0 ? "" + value : "null";
} else if (className == stringClass) {
// Strings are double-quoted and escaped.
return quote("" + value);
}
// Recursively serialize objects and arrays.
if (typeof value == "object") {
// Check for cyclic structures. This is a linear search; performance
// is inversely proportional to the number of unique nested objects.
for (length = stack.length; length--;) {
if (stack[length] === value) {
// Cyclic structures cannot be serialized by `JSON.stringify`.
throw TypeError();
}
}
// Add the object to the stack of traversed objects.
stack.push(value);
results = [];
// Save the current indentation level and indent one additional level.
prefix = indentation;
indentation += whitespace;
if (className == arrayClass) {
// Recursively serialize array elements.
for (index = 0, length = value.length; index < length; index++) {
element = serialize(index, value, callback, properties, whitespace, indentation, stack);
results.push(element === undef ? "null" : element);
}
result = results.length ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]";
} else {
// Recursively serialize object members. Members are selected from
// either a user-specified list of property names, or the object
// itself.
forEach(properties || value, function (property) {
var element = serialize(property, value, callback, properties, whitespace, indentation, stack);
if (element !== undef) {
// According to ES 5.1 section 15.12.3: "If `gap` {whitespace}
// is not the empty string, let `member` {quote(property) + ":"}
// be the concatenation of `member` and the `space` character."
// The "`space` character" refers to the literal space
// character, not the `space` {width} argument provided to
// `JSON.stringify`.
results.push(quote(property) + ":" + (whitespace ? " " : "") + element);
}
});
result = results.length ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}";
}
// Remove the object from the traversed object stack.
stack.pop();
return result;
}
};
// Public: `JSON.stringify`. See ES 5.1 section 15.12.3.
exports.stringify = function (source, filter, width) {
var whitespace, callback, properties, className;
if (objectTypes[typeof filter] && filter) {
if ((className = getClass.call(filter)) == functionClass) {
callback = filter;
} else if (className == arrayClass) {
// Convert the property names array into a makeshift set.
properties = {};
for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1));
}
}
if (width) {
if ((className = getClass.call(width)) == numberClass) {
// Convert the `width` to an integer and create a string containing
// `width` number of space characters.
if ((width -= width % 1) > 0) {
for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " ");
}
} else if (className == stringClass) {
whitespace = width.length <= 10 ? width : width.slice(0, 10);
}
}
// Opera <= 7.54u2 discards the values associated with empty string keys
// (`""`) only if they are used directly within an object member list
// (e.g., `!("" in { "": 1})`).
return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []);
};
}
// Public: Parses a JSON source string.
if (!has("json-parse")) {
var fromCharCode = String.fromCharCode;
// Internal: A map of escaped control characters and their unescaped
// equivalents.
var Unescapes = {
92: "\\",
34: '"',
47: "/",
98: "\b",
116: "\t",
110: "\n",
102: "\f",
114: "\r"
};
// Internal: Stores the parser state.
var Index, Source;
// Internal: Resets the parser state and throws a `SyntaxError`.
var abort = function () {
Index = Source = null;
throw SyntaxError();
};
// Internal: Returns the next token, or `"$"` if the parser has reached
// the end of the source string. A token may be a string, number, `null`
// literal, or Boolean literal.
var lex = function () {
var source = Source, length = source.length, value, begin, position, isSigned, charCode;
while (Index < length) {
charCode = source.charCodeAt(Index);
switch (charCode) {
case 9: case 10: case 13: case 32:
// Skip whitespace tokens, including tabs, carriage returns, line
// feeds, and space characters.
Index++;
break;
case 123: case 125: case 91: case 93: case 58: case 44:
// Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at
// the current position.
value = charIndexBuggy ? source.charAt(Index) : source[Index];
Index++;
return value;
case 34:
// `"` delimits a JSON string; advance to the next character and
// begin parsing the string. String tokens are prefixed with the
// sentinel `@` character to distinguish them from punctuators and
// end-of-string tokens.
for (value = "@", Index++; Index < length;) {
charCode = source.charCodeAt(Index);
if (charCode < 32) {
// Unescaped ASCII control characters (those with a code unit
// less than the space character) are not permitted.
abort();
} else if (charCode == 92) {
// A reverse solidus (`\`) marks the beginning of an escaped
// control character (including `"`, `\`, and `/`) or Unicode
// escape sequence.
charCode = source.charCodeAt(++Index);
switch (charCode) {
case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114:
// Revive escaped control characters.
value += Unescapes[charCode];
Index++;
break;
case 117:
// `\u` marks the beginning of a Unicode escape sequence.
// Advance to the first character and validate the
// four-digit code point.
begin = ++Index;
for (position = Index + 4; Index < position; Index++) {
charCode = source.charCodeAt(Index);
// A valid sequence comprises four hexdigits (case-
// insensitive) that form a single hexadecimal value.
if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {
// Invalid Unicode escape sequence.
abort();
}
}
// Revive the escaped character.
value += fromCharCode("0x" + source.slice(begin, Index));
break;
default:
// Invalid escape sequence.
abort();
}
} else {
if (charCode == 34) {
// An unescaped double-quote character marks the end of the
// string.
break;
}
charCode = source.charCodeAt(Index);
begin = Index;
// Optimize for the common case where a string is valid.
while (charCode >= 32 && charCode != 92 && charCode != 34) {
charCode = source.charCodeAt(++Index);
}
// Append the string as-is.
value += source.slice(begin, Index);
}
}
if (source.charCodeAt(Index) == 34) {
// Advance to the next character and return the revived string.
Index++;
return value;
}
// Unterminated string.
abort();
default:
// Parse numbers and literals.
begin = Index;
// Advance past the negative sign, if one is specified.
if (charCode == 45) {
isSigned = true;
charCode = source.charCodeAt(++Index);
}
// Parse an integer or floating-point value.
if (charCode >= 48 && charCode <= 57) {
// Leading zeroes are interpreted as octal literals.
if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {
// Illegal octal literal.
abort();
}
isSigned = false;
// Parse the integer component.
for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++);
// Floats cannot contain a leading decimal point; however, this
// case is already accounted for by the parser.
if (source.charCodeAt(Index) == 46) {
position = ++Index;
// Parse the decimal component.
for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);
if (position == Index) {
// Illegal trailing decimal.
abort();
}
Index = position;
}
// Parse exponents. The `e` denoting the exponent is
// case-insensitive.
charCode = source.charCodeAt(Index);
if (charCode == 101 || charCode == 69) {
charCode = source.charCodeAt(++Index);
// Skip past the sign following the exponent, if one is
// specified.
if (charCode == 43 || charCode == 45) {
Index++;
}
// Parse the exponential component.
for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);
if (position == Index) {
// Illegal empty exponent.
abort();
}
Index = position;
}
// Coerce the parsed value to a JavaScript number.
return +source.slice(begin, Index);
}
// A negative sign may only precede numbers.
if (isSigned) {
abort();
}
// `true`, `false`, and `null` literals.
if (source.slice(Index, Index + 4) == "true") {
Index += 4;
return true;
} else if (source.slice(Index, Index + 5) == "false") {
Index += 5;
return false;
} else if (source.slice(Index, Index + 4) == "null") {
Index += 4;
return null;
}
// Unrecognized token.
abort();
}
}
// Return the sentinel `$` character if the parser has reached the end
// of the source string.
return "$";
};
// Internal: Parses a JSON `value` token.
var get = function (value) {
var results, hasMembers;
if (value == "$") {
// Unexpected end of input.
abort();
}
if (typeof value == "string") {
if ((charIndexBuggy ? value.charAt(0) : value[0]) == "@") {
// Remove the sentinel `@` character.
return value.slice(1);
}
// Parse object and array literals.
if (value == "[") {
// Parses a JSON array, returning a new JavaScript array.
results = [];
for (;; hasMembers || (hasMembers = true)) {
value = lex();
// A closing square bracket marks the end of the array literal.
if (value == "]") {
break;
}
// If the array literal contains elements, the current token
// should be a comma separating the previous element from the
// next.
if (hasMembers) {
if (value == ",") {
value = lex();
if (value == "]") {
// Unexpected trailing `,` in array literal.
abort();
}
} else {
// A `,` must separate each array element.
abort();
}
}
// Elisions and leading commas are not permitted.
if (value == ",") {
abort();
}
results.push(get(value));
}
return results;
} else if (value == "{") {
// Parses a JSON object, returning a new JavaScript object.
results = {};
for (;; hasMembers || (hasMembers = true)) {
value = lex();
// A closing curly brace marks the end of the object literal.
if (value == "}") {
break;
}
// If the object literal contains members, the current token
// should be a comma separator.
if (hasMembers) {
if (value == ",") {
value = lex();
if (value == "}") {
// Unexpected trailing `,` in object literal.
abort();
}
} else {
// A `,` must separate each object member.
abort();
}
}
// Leading commas are not permitted, object property names must be
// double-quoted strings, and a `:` must separate each property
// name and value.
if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") {
abort();
}
results[value.slice(1)] = get(lex());
}
return results;
}
// Unexpected token encountered.
abort();
}
return value;
};
// Internal: Updates a traversed object member.
var update = function (source, property, callback) {
var element = walk(source, property, callback);
if (element === undef) {
delete source[property];
} else {
source[property] = element;
}
};
// Internal: Recursively traverses a parsed JSON object, invoking the
// `callback` function for each value. This is an implementation of the
// `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.
var walk = function (source, property, callback) {
var value = source[property], length;
if (typeof value == "object" && value) {
// `forEach` can't be used to traverse an array in Opera <= 8.54
// because its `Object#hasOwnProperty` implementation returns `false`
// for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`).
if (getClass.call(value) == arrayClass) {
for (length = value.length; length--;) {
update(value, length, callback);
}
} else {
forEach(value, function (property) {
update(value, property, callback);
});
}
}
return callback.call(source, property, value);
};
// Public: `JSON.parse`. See ES 5.1 section 15.12.2.
exports.parse = function (source, callback) {
var result, value;
Index = 0;
Source = "" + source;
result = get(lex());
// If a JSON string contains multiple tokens, it is invalid.
if (lex() != "$") {
abort();
}
// Reset the parser state.
Index = Source = null;
return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result;
};
}
}
exports["runInContext"] = runInContext;
return exports;
}
if (freeExports && !isLoader) {
// Export for CommonJS environments.
runInContext(root, freeExports);
} else {
// Export for web browsers and JavaScript engines.
var nativeJSON = root.JSON,
previousJSON = root["JSON3"],
isRestored = false;
var JSON3 = runInContext(root, (root["JSON3"] = {
// Public: Restores the original value of the global `JSON` object and
// returns a reference to the `JSON3` object.
"noConflict": function () {
if (!isRestored) {
isRestored = true;
root.JSON = nativeJSON;
root["JSON3"] = previousJSON;
nativeJSON = previousJSON = null;
}
return JSON3;
}
}));
root.JSON = {
"parse": JSON3.parse,
"stringify": JSON3.stringify
};
}
// Export for asynchronous module loaders.
if (isLoader) {
define(function () {
return JSON3;
});
}
}).call(this);
//##############################################################################
// DataUtils.js
//##############################################################################
(function () {
/**
* A few data utilities for formatting different data types.
* @class DataUtils
*/
var s = {};
// static methods
/**
* Parse XML using the DOM. This is required when preloading XML or SVG.
* @method parseXML
* @param {String} text The raw text or XML that is loaded by XHR.
* @param {String} type The mime type of the XML. Use "text/xml" for XML, and "image/svg+xml" for SVG parsing.
* @return {XML} An XML document
* @static
*/
s.parseXML = function (text, type) {
var xml = null;
try {
// CocoonJS does not support XML parsing with either method.
if (window.DOMParser) {
var parser = new DOMParser();
xml = parser.parseFromString(text, type);
} else { // IE
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.loadXML(text);
}
} catch (e) {}
return xml;
};
/**
* Parse a string into an Object.
* @method parseJSON
* @param {String} value The loaded JSON string
* @returns {Object} A JavaScript object.
*/
s.parseJSON = function (value) {
if (value == null) {
return null;
}
try {
return JSON.parse(value);
} catch (e) {
// TODO; Handle this with a custom error?
throw e;
}
};
createjs.DataUtils = s;
}());
//##############################################################################
// LoadItem.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
/**
* All loaders accept an item containing the properties defined in this class. If a raw object is passed instead,
* it will not be affected, but it must contain at least a {{#crossLink "src:property"}}{{/crossLink}} property. A
* string path or HTML tag is also acceptable, but it will be automatically converted to a LoadItem using the
* {{#crossLink "create"}}{{/crossLink}} method by {{#crossLink "AbstractLoader"}}{{/crossLink}}
* @class LoadItem
* @constructor
* @since 0.6.0
*/
function LoadItem() {
/**
* The source of the file that is being loaded. This property is <b>required</b>. The source can either be a
* string (recommended), or an HTML tag.</li>
* @property src
* @type {String}
* @default null
*/
this.src = null;
/**
* The source of the file that is being loaded. This property is <strong>required</strong>. The source can
* either be a string (recommended), or an HTML tag. See the {{#crossLink "AbstractLoader"}}{{/crossLink}}
* class for the full list of supported types.
* @property type
* @type {String}
* @default null
*/
this.type = null;
/**
* A string identifier which can be used to reference the loaded object. If none is provided, this will be
* automatically set to the {{#crossLink "src:property"}}{{/crossLink}}.
* @property id
* @type {String}
* @default null
*/
this.id = null;
/**
* Determines if a manifest will maintain the order of this item, in relation to other items in the manifest
* that have also set the `maintainOrder` property to `true`. This only applies when the max connections has
* been set above 1 (using {{#crossLink "LoadQueue/setMaxConnections"}}{{/crossLink}}). Everything with this
* property set to `false` will finish as it is loaded. Ordered items are combined with script tags loading in
* order when {{#crossLink "LoadQueue/maintainScriptOrder:property"}}{{/crossLink}} is set to `true`.
* @property maintainOrder
* @type {Boolean}
* @default false
*/
this.maintainOrder = false;
/**
* A callback used by JSONP requests that defines what global method to call when the JSONP content is loaded.
* @property callback
* @type {String}
* @default null
*/
this.callback = null;
/**
* An arbitrary data object, which is included with the loaded object.
* @property data
* @type {Object}
* @default null
*/
this.data = null;
/**
* The request method used for HTTP calls. Both {{#crossLink "AbstractLoader/GET:property"}}{{/crossLink}} or
* {{#crossLink "AbstractLoader/POST:property"}}{{/crossLink}} request types are supported, and are defined as
* constants on {{#crossLink "AbstractLoader"}}{{/crossLink}}.
* @property method
* @type {String}
* @default get
*/
this.method = createjs.LoadItem.GET;
/**
* An object hash of name/value pairs to send to the server.
* @property values
* @type {Object}
* @default null
*/
this.values = null;
/**
* An object hash of headers to attach to an XHR request. PreloadJS will automatically attach some default
* headers when required, including "Origin", "Content-Type", and "X-Requested-With". You may override the
* default headers by including them in your headers object.
* @property headers
* @type {Object}
* @default null
*/
this.headers = null;
/**
* Enable credentials for XHR requests.
* @property withCredentials
* @type {Boolean}
* @default false
*/
this.withCredentials = false;
/**
* Set the mime type of XHR-based requests. This is automatically set to "text/plain; charset=utf-8" for text
* based files (json, xml, text, css, js).
* @property mimeType
* @type {String}
* @default null
*/
this.mimeType = null;
/**
* Sets the crossOrigin attribute for CORS-enabled images loading cross-domain.
* @property crossOrigin
* @type {boolean}
* @default Anonymous
*/
this.crossOrigin = null;
/**
* The duration in milliseconds to wait before a request times out. This only applies to tag-based and and XHR
* (level one) loading, as XHR (level 2) provides its own timeout event.
* @property loadTimeout
* @type {Number}
* @default 8000 (8 seconds)
*/
this.loadTimeout = 8000;
};
var p = LoadItem.prototype = {};
var s = LoadItem;
/**
* Create/validate a LoadItem.
* <ul>
* <li>String-based items are converted to a LoadItem with a populated {{#crossLink "src:property"}}{{/crossLink}}.</li>
* <li>LoadItem instances are returned as-is</li>
* <li>Objectss are returned as-is</li>
* </ul>
* @method create
* @param {LoadItem|String|Object} value The load item value
* @returns {Object|LoadItem}
* @static
*/
s.create = function (value) {
if (typeof value == "string") {
var item = new LoadItem();
item.src = value;
return item;
} else if (value instanceof s) {
return value;
} else if (value instanceof Object) { // Don't modify object, allows users to attach random data to the item.
// TODO: Disallow objects with no src?
return value;
} else {
throw new Error("Type not recognized.");
}
};
/**
* Provides a chainable shortcut method for setting a number of properties on the instance.
*
* <h4>Example</h4>
*
* var loadItem = new createjs.LoadItem().set({src:"image.png", maintainOrder:true});
*
* @method set
* @param {Object} props A generic object containing properties to copy to the LoadItem instance.
* @return {LoadItem} Returns the instance the method is called on (useful for chaining calls.)
*/
p.set = function(props) {
for (var n in props) { this[n] = props[n]; }
return this;
};
createjs.LoadItem = s;
}());
//##############################################################################
// RequestUtils.js
//##############################################################################
(function () {
/**
* Utilities that assist with parsing load items, and determining file types, etc.
* @class RequestUtils
*/
var s = {};
/**
* The Regular Expression used to test file URLS for an absolute path.
* @property ABSOLUTE_PATH
* @type {RegExp}
* @static
*/
s.ABSOLUTE_PATT = /^(?:\w+:)?\/{2}/i;
/**
* The Regular Expression used to test file URLS for a relative path.
* @property RELATIVE_PATH
* @type {RegExp}
* @static
*/
s.RELATIVE_PATT = (/^[./]*?\//i);
/**
* The Regular Expression used to test file URLS for an extension. Note that URIs must already have the query string
* removed.
* @property EXTENSION_PATT
* @type {RegExp}
* @static
*/
s.EXTENSION_PATT = /\/?[^/]+\.(\w{1,5})$/i;
/**
* Parse a file path to determine the information we need to work with it. Currently, PreloadJS needs to know:
* <ul>
* <li>If the path is absolute. Absolute paths start with a protocol (such as `http://`, `file://`, or
* `//networkPath`)</li>
* <li>If the path is relative. Relative paths start with `../` or `/path` (or similar)</li>
* <li>The file extension. This is determined by the filename with an extension. Query strings are dropped, and
* the file path is expected to follow the format `name.ext`.</li>
* </ul>
* @method parseURI
* @param {String} path
* @returns {Object} An Object with an `absolute` and `relative` Boolean values, as well as an optional 'extension`
* property, which is the lowercase extension.
* @static
*/
s.parseURI = function (path) {
var info = {absolute: false, relative: false};
if (path == null) { return info; }
// Drop the query string
var queryIndex = path.indexOf("?");
if (queryIndex > -1) {
path = path.substr(0, queryIndex);
}
// Absolute
var match;
if (s.ABSOLUTE_PATT.test(path)) {
info.absolute = true;
// Relative
} else if (s.RELATIVE_PATT.test(path)) {
info.relative = true;
}
// Extension
if (match = path.match(s.EXTENSION_PATT)) {
info.extension = match[1].toLowerCase();
}
return info;
};
/**
* Formats an object into a query string for either a POST or GET request.
* @method formatQueryString
* @param {Object} data The data to convert to a query string.
* @param {Array} [query] Existing name/value pairs to append on to this query.
* @static
*/
s.formatQueryString = function (data, query) {
if (data == null) {
throw new Error('You must specify data.');
}
var params = [];
for (var n in data) {
params.push(n + '=' + escape(data[n]));
}
if (query) {
params = params.concat(query);
}
return params.join('&');
};
/**
* A utility method that builds a file path using a source and a data object, and formats it into a new path.
* @method buildPath
* @param {String} src The source path to add values to.
* @param {Object} [data] Object used to append values to this request as a query string. Existing parameters on the
* path will be preserved.
* @returns {string} A formatted string that contains the path and the supplied parameters.
* @static
*/
s.buildPath = function (src, data) {
if (data == null) {
return src;
}
var query = [];
var idx = src.indexOf('?');
if (idx != -1) {
var q = src.slice(idx + 1);
query = query.concat(q.split('&'));
}
if (idx != -1) {
return src.slice(0, idx) + '?' + this._formatQueryString(data, query);
} else {
return src + '?' + this._formatQueryString(data, query);
}
};
/**
* @method isCrossDomain
* @param {LoadItem|Object} item A load item with a `src` property.
* @return {Boolean} If the load item is loading from a different domain than the current location.
* @static
*/
s.isCrossDomain = function (item) {
var target = document.createElement("a");
target.href = item.src;
var host = document.createElement("a");
host.href = location.href;
var crossdomain = (target.hostname != "") &&
(target.port != host.port ||
target.protocol != host.protocol ||
target.hostname != host.hostname);
return crossdomain;
};
/**
* @method isLocal
* @param {LoadItem|Object} item A load item with a `src` property
* @return {Boolean} If the load item is loading from the "file:" protocol. Assume that the host must be local as
* well.
* @static
*/
s.isLocal = function (item) {
var target = document.createElement("a");
target.href = item.src;
return target.hostname == "" && target.protocol == "file:";
};
/**
* Determine if a specific type should be loaded as a binary file. Currently, only images and items marked
* specifically as "binary" are loaded as binary. Note that audio is <b>not</b> a binary type, as we can not play
* back using an audio tag if it is loaded as binary. Plugins can change the item type to binary to ensure they get
* a binary result to work with. Binary files are loaded using XHR2. Types are defined as static constants on
* {{#crossLink "AbstractLoader"}}{{/crossLink}}.
* @method isBinary
* @param {String} type The item type.
* @return {Boolean} If the specified type is binary.
* @static
*/
s.isBinary = function (type) {
switch (type) {
case createjs.AbstractLoader.IMAGE:
case createjs.AbstractLoader.BINARY:
return true;
default:
return false;
}
};
/**
* Check if item is a valid HTMLImageElement
* @method isImageTag
* @param {Object} item
* @returns {Boolean}
* @static
*/
s.isImageTag = function(item) {
return item instanceof HTMLImageElement;
};
/**
* Check if item is a valid HTMLAudioElement
* @method isAudioTag
* @param {Object} item
* @returns {Boolean}
* @static
*/
s.isAudioTag = function(item) {
if (window.HTMLAudioElement) {
return item instanceof HTMLAudioElement;
} else {
return false;
}
};
/**
* Check if item is a valid HTMLVideoElement
* @method isVideoTag
* @param {Objectitem
* @returns {Boolean}
* @static
*/
s.isVideoTag = function(item) {
if (window.HTMLVideoElement) {
return item instanceof HTMLVideoElement;
} else {
false;
}
};
/**
* Determine if a specific type is a text-based asset, and should be loaded as UTF-8.
* @method isText
* @param {String} type The item type.
* @return {Boolean} If the specified type is text.
* @static
*/
s.isText = function (type) {
switch (type) {
case createjs.AbstractLoader.TEXT:
case createjs.AbstractLoader.JSON:
case createjs.AbstractLoader.MANIFEST:
case createjs.AbstractLoader.XML:
case createjs.AbstractLoader.CSS:
case createjs.AbstractLoader.SVG:
case createjs.AbstractLoader.JAVASCRIPT:
case createjs.AbstractLoader.SPRITESHEET:
return true;
default:
return false;
}
};
/**
* Determine the type of the object using common extensions. Note that the type can be passed in with the load item
* if it is an unusual extension.
* @method getTypeByExtension
* @param {String} extension The file extension to use to determine the load type.
* @return {String} The determined load type (for example, <code>AbstractLoader.IMAGE</code>). Will return `null` if
* the type can not be determined by the extension.
* @static
*/
s.getTypeByExtension = function (extension) {
if (extension == null) {
return createjs.AbstractLoader.TEXT;
}
switch (extension.toLowerCase()) {
case "jpeg":
case "jpg":
case "gif":
case "png":
case "webp":
case "bmp":
return createjs.AbstractLoader.IMAGE;
case "ogg":
case "mp3":
case "webm":
return createjs.AbstractLoader.SOUND;
case "mp4":
case "webm":
case "ts":
return createjs.AbstractLoader.VIDEO;
case "json":
return createjs.AbstractLoader.JSON;
case "xml":
return createjs.AbstractLoader.XML;
case "css":
return createjs.AbstractLoader.CSS;
case "js":
return createjs.AbstractLoader.JAVASCRIPT;
case 'svg':
return createjs.AbstractLoader.SVG;
default:
return createjs.AbstractLoader.TEXT;
}
};
createjs.RequestUtils = s;
}());
//##############################################################################
// AbstractLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* The base loader, which defines all the generic methods, properties, and events. All loaders extend this class,
* including the {{#crossLink "LoadQueue"}}{{/crossLink}}.
* @class AbstractLoader
* @param {LoadItem|object|string} The item to be loaded.
* @param {Boolean} [preferXHR] Determines if the LoadItem should <em>try</em> and load using XHR, or take a
* tag-based approach, which can be better in cross-domain situations. Not all loaders can load using one or the
* other, so this is a suggested directive.
* @oaram {String} [type] The type of loader. Loader types are defined as constants on the AbstractLoader class,
* such as {{#crossLink "IMAGE:property"}}{{/crossLink}}, {{#crossLink "CSS:property"}}{{/crossLink}}, etc.
* @extends EventDispatcher
*/
function AbstractLoader(loadItem, preferXHR, type) {
this.EventDispatcher_constructor();
// public properties
/**
* If the loader has completed loading. This provides a quick check, but also ensures that the different approaches
* used for loading do not pile up resulting in more than one `complete` {{#crossLink "Event"}}{{/crossLink}}.
* @property loaded
* @type {Boolean}
* @default false
*/
this.loaded = false;
/**
* Determine if the loader was canceled. Canceled loads will not fire complete events. Note that this property
* is readonly, so {{#crossLink "LoadQueue"}}{{/crossLink}} queues should be closed using {{#crossLink "LoadQueue/close"}}{{/crossLink}}
* instead.
* @property canceled
* @type {Boolean}
* @default false
*/
this.canceled = false;
/**
* The current load progress (percentage) for this item. This will be a number between 0 and 1.
*
* <h4>Example</h4>
*
* var queue = new createjs.LoadQueue();
* queue.loadFile("largeImage.png");
* queue.on("progress", function() {
* console.log("Progress:", queue.progress, event.progress);
* });
*
* @property progress
* @type {Number}
* @default 0
*/
this.progress = 0;
/**
* The type of item this loader will load. See {{#crossLink "AbstractLoader"}}{{/crossLink}} for a full list of
* supported types.
* @property type
* @type {String}
*/
this.type = type;
/**
* A formatter function that converts the loaded raw result into the final result. For example, the JSONLoader
* converts a string of text into a JavaScript object. Not all loaders have a resultFormatter, and this property
* can be overridden to provide custom formatting.
*
* Optionally, a resultFormatter can return a callback function in cases where the formatting needs to be
* asynchronous, such as creating a new image.
* @property resultFormatter
* @type {Function}
* @default null
*/
this.resultFormatter = null;
// protected properties
/**
* The {{#crossLink "LoadItem"}}{{/crossLink}} this loader represents. Note that this is null in a {{#crossLink "LoadQueue"}}{{/crossLink}},
* but will be available on loaders such as {{#crossLink "XMLLoader"}}{{/crossLink}} and {{#crossLink "ImageLoader"}}{{/crossLink}}.
* @property _item
* @type {LoadItem|Object}
* @private
*/
if (loadItem) {
this._item = createjs.LoadItem.create(loadItem);
} else {
this._item = null;
}
/**
* Whether the loader will try and load content using XHR (true) or HTML tags (false).
* @property _preferXHR
* @type {Boolean}
* @private
*/
this._preferXHR = preferXHR;
/**
* The loaded result after it is formatted by an optional {{#crossLink "resultFormatter"}}{{/crossLink}}. For
* items that are not formatted, this will be the same as the {{#crossLink "_rawResult:property"}}{{/crossLink}}.
* The result is accessed using the {{#crossLink "getResult"}}{{/crossLink}} method.
* @property _result
* @type {Object|String}
* @private
*/
this._result = null;
/**
* The loaded result before it is formatted. The rawResult is accessed using the {{#crossLink "getResult"}}{{/crossLink}}
* method, and passing `true`.
* @property _rawResult
* @type {Object|String}
* @private
*/
this._rawResult = null;
/**
* A list of items that loaders load behind the scenes. This does not include the main item the loader is
* responsible for loading. Examples of loaders that have sub-items include the {{#crossLink "SpriteSheetLoader"}}{{/crossLink}} and
* {{#crossLink "ManifestLoader"}}{{/crossLink}}.
* @property _loadItems
* @type {null}
* @protected
*/
this._loadedItems = null;
/**
* The attribute the items loaded using tags use for the source.
* @type {string}
* @default null
* @private
*/
this._tagSrcAttribute = null;
/**
* An HTML tag (or similar) that a loader may use to load HTML content, such as images, scripts, etc.
* @property _tag
* @type {Object}
* @private
*/
this._tag = null;
};
var p = createjs.extend(AbstractLoader, createjs.EventDispatcher);
var s = AbstractLoader;
// TODO: deprecated
// p.initialize = function() {}; // searchable for devs wondering where it is. REMOVED. See docs for details.
/**
* Defines a POST request, use for a method value when loading data.
* @property POST
* @type {string}
* @default post
*/
s.POST = "POST";
/**
* Defines a GET request, use for a method value when loading data.
* @property GET
* @type {string}
* @default get
*/
s.GET = "GET";
/**
* The preload type for generic binary types. Note that images are loaded as binary files when using XHR.
* @property BINARY
* @type {String}
* @default binary
* @static
* @since 0.6.0
*/
s.BINARY = "binary";
/**
* The preload type for css files. CSS files are loaded using a <link> when loaded with XHR, or a
* <style> tag when loaded with tags.
* @property CSS
* @type {String}
* @default css
* @static
* @since 0.6.0
*/
s.CSS = "css";
/**
* The preload type for image files, usually png, gif, or jpg/jpeg. Images are loaded into an <image> tag.
* @property IMAGE
* @type {String}
* @default image
* @static
* @since 0.6.0
*/
s.IMAGE = "image";
/**
* The preload type for javascript files, usually with the "js" file extension. JavaScript files are loaded into a
* <script> tag.
*
* Since version 0.4.1+, due to how tag-loaded scripts work, all JavaScript files are automatically injected into
* the body of the document to maintain parity between XHR and tag-loaded scripts. In version 0.4.0 and earlier,
* only tag-loaded scripts are injected.
* @property JAVASCRIPT
* @type {String}
* @default javascript
* @static
* @since 0.6.0
*/
s.JAVASCRIPT = "javascript";
/**
* The preload type for json files, usually with the "json" file extension. JSON data is loaded and parsed into a
* JavaScript object. Note that if a `callback` is present on the load item, the file will be loaded with JSONP,
* no matter what the {{#crossLink "LoadQueue/preferXHR:property"}}{{/crossLink}} property is set to, and the JSON
* must contain a matching wrapper function.
* @property JSON
* @type {String}
* @default json
* @static
* @since 0.6.0
*/
s.JSON = "json";
/**
* The preload type for jsonp files, usually with the "json" file extension. JSON data is loaded and parsed into a
* JavaScript object. You are required to pass a callback parameter that matches the function wrapper in the JSON.
* Note that JSONP will always be used if there is a callback present, no matter what the {{#crossLink "LoadQueue/preferXHR:property"}}{{/crossLink}}
* property is set to.
* @property JSONP
* @type {String}
* @default jsonp
* @static
* @since 0.6.0
*/
s.JSONP = "jsonp";
/**
* The preload type for json-based manifest files, usually with the "json" file extension. The JSON data is loaded
* and parsed into a JavaScript object. PreloadJS will then look for a "manifest" property in the JSON, which is an
* Array of files to load, following the same format as the {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}}
* method. If a "callback" is specified on the manifest object, then it will be loaded using JSONP instead,
* regardless of what the {{#crossLink "LoadQueue/preferXHR:property"}}{{/crossLink}} property is set to.
* @property MANIFEST
* @type {String}
* @default manifest
* @static
* @since 0.6.0
*/
s.MANIFEST = "manifest";
/**
* The preload type for sound files, usually mp3, ogg, or wav. When loading via tags, audio is loaded into an
* <audio> tag.
* @property SOUND
* @type {String}
* @default sound
* @static
* @since 0.6.0
*/
s.SOUND = "sound";
/**
* The preload type for video files, usually mp4, ts, or ogg. When loading via tags, video is loaded into an
* <video> tag.
* @property VIDEO
* @type {String}
* @default video
* @static
* @since 0.6.0
*/
s.VIDEO = "video";
/**
* The preload type for SpriteSheet files. SpriteSheet files are JSON files that contain string image paths.
* @property SPRITESHEET
* @type {String}
* @default spritesheet
* @static
* @since 0.6.0
*/
s.SPRITESHEET = "spritesheet";
/**
* The preload type for SVG files.
* @property SVG
* @type {String}
* @default svg
* @static
* @since 0.6.0
*/
s.SVG = "svg";
/**
* The preload type for text files, which is also the default file type if the type can not be determined. Text is
* loaded as raw text.
* @property TEXT
* @type {String}
* @default text
* @static
* @since 0.6.0
*/
s.TEXT = "text";
/**
* The preload type for xml files. XML is loaded into an XML document.
* @property XML
* @type {String}
* @default xml
* @static
* @since 0.6.0
*/
s.XML = "xml";
// Events
/**
* The {{#crossLink "ProgressEvent"}}{{/crossLink}} that is fired when the overall progress changes. Prior to
* version 0.6.0, this was just a regular {{#crossLink "Event"}}{{/crossLink}}.
* @event progress
* @since 0.3.0
*/
/**
* The {{#crossLink "Event"}}{{/crossLink}} that is fired when a load starts.
* @event loadstart
* @param {Object} target The object that dispatched the event.
* @param {String} type The event type.
* @since 0.3.1
*/
/**
* The {{#crossLink "Event"}}{{/crossLink}} that is fired when the entire queue has been loaded.
* @event complete
* @param {Object} target The object that dispatched the event.
* @param {String} type The event type.
* @since 0.3.0
*/
/**
* The {{#crossLink "ErrorEvent"}}{{/crossLink}} that is fired when the loader encounters an error. If the error was
* encountered by a file, the event will contain the item that caused the error. Prior to version 0.6.0, this was
* just a regular {{#crossLink "Event"}}{{/crossLink}}.
* @event error
* @since 0.3.0
*/
/**
* The {{#crossLink "Event"}}{{/crossLink}} that is fired when the loader encounters an internal file load error.
* This enables loaders to maintain internal queues, and surface file load errors.
* @event fileerror
* @param {Object} target The object that dispatched the event.
* @param {String} type The even type ("fileerror")
* @param {LoadItem|object} The item that encountered the error
* @since 0.6.0
*/
/**
* The {{#crossLink "Event"}}{{/crossLink}} that is fired when a loader internally loads a file. This enables
* loaders such as {{#crossLink "ManifestLoader"}}{{/crossLink}} to maintain internal {{#crossLink "LoadQueue"}}{{/crossLink}}s
* and notify when they have loaded a file. The {{#crossLink "LoadQueue"}}{{/crossLink}} class dispatches a
* slightly different {{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}} event.
* @event fileload
* @param {Object} target The object that dispatched the event.
* @param {String} type The event type ("fileload")
* @param {Object} item The file item which was specified in the {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}}
* or {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}} call. If only a string path or tag was specified, the
* object will contain that value as a `src` property.
* @param {Object} result The HTML tag or parsed result of the loaded item.
* @param {Object} rawResult The unprocessed result, usually the raw text or binary data before it is converted
* to a usable object.
* @since 0.6.0
*/
/**
* The {{#crossLink "Event"}}{{/crossLink}} that is fired after the internal request is created, but before a load.
* This allows updates to the loader for specific loading needs, such as binary or XHR image loading.
* @event initialize
* @param {Object} target The object that dispatched the event.
* @param {String} type The event type ("initialize")
* @param {AbstractLoader} loader The loader that has been initialized.
*/
/**
* Get a reference to the manifest item that is loaded by this loader. In some cases this will be the value that was
* passed into {{#crossLink "LoadQueue"}}{{/crossLink}} using {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} or
* {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}}. However if only a String path was passed in, then it will
* be a {{#crossLink "LoadItem"}}{{/crossLink}}.
* @method getItem
* @return {Object} The manifest item that this loader is responsible for loading.
* @since 0.6.0
*/
p.getItem = function () {
return this._item;
};
/**
* Get a reference to the content that was loaded by the loader (only available after the {{#crossLink "complete:event"}}{{/crossLink}}
* event is dispatched.
* @method getResult
* @param {Boolean} [raw=false] Determines if the returned result will be the formatted content, or the raw loaded
* data (if it exists).
* @return {Object}
* @since 0.6.0
*/
p.getResult = function (raw) {
return raw ? this._rawResult : this._result;
};
/**
* Return the `tag` this object creates or uses for loading.
* @method getTag
* @return {Object} The tag instance
* @since 0.6.0
*/
p.getTag = function () {
return this._tag;
};
/**
* Set the `tag` this item uses for loading.
* @method setTag
* @param {Object} tag The tag instance
* @since 0.6.0
*/
p.setTag = function(tag) {
this._tag = tag;
};
/**
* Begin loading the item. This method is required when using a loader by itself.
*
* <h4>Example</h4>
*
* var queue = new createjs.LoadQueue();
* queue.on("complete", handleComplete);
* queue.loadManifest(fileArray, false); // Note the 2nd argument that tells the queue not to start loading yet
* queue.load();
*
* @method load
*/
p.load = function () {
this._createRequest();
this._request.on("complete", this, this);
this._request.on("progress", this, this);
this._request.on("loadStart", this, this);
this._request.on("abort", this, this);
this._request.on("timeout", this, this);
this._request.on("error", this, this);
var evt = new createjs.Event("initialize");
evt.loader = this._request;
this.dispatchEvent(evt);
this._request.load();
};
/**
* Close the the item. This will stop any open requests (although downloads using HTML tags may still continue in
* the background), but events will not longer be dispatched.
* @method cancel
*/
p.cancel = function () {
this.canceled = true;
this.destroy();
};
/**
* Clean up the loader.
* @method destroy
*/
p.destroy = function() {
if (this._request) {
this._request.removeAllEventListeners();
this._request.destroy();
}
this._request = null;
this._item = null;
this._rawResult = null;
this._result = null;
this._loadItems = null;
this.removeAllEventListeners();
};
/**
* Get any items loaded internally by the loader. The enables loaders such as {{#crossLink "ManifestLoader"}}{{/crossLink}}
* to expose items it loads internally.
* @method getLoadedItems
* @return {Array} A list of the items loaded by the loader.
* @since 0.6.0
*/
p.getLoadedItems = function () {
return this._loadedItems;
};
// Private methods
/**
* Create an internal request used for loading. By default, an {{#crossLink "XHRRequest"}}{{/crossLink}} or
* {{#crossLink "TagRequest"}}{{/crossLink}} is created, depending on the value of {{#crossLink "preferXHR:property"}}{{/crossLink}}.
* Other loaders may override this to use different request types, such as {{#crossLink "ManifestLoader"}}{{/crossLink}},
* which uses {{#crossLink "JSONLoader"}}{{/crossLink}} or {{#crossLink "JSONPLoader"}}{{/crossLink}} under the hood.
* @method _createRequest
* @protected
*/
p._createRequest = function() {
if (!this._preferXHR) {
this._request = new createjs.TagRequest(this._item, this._tag || this._createTag(), this._tagSrcAttribute);
} else {
this._request = new createjs.XHRRequest(this._item);
}
};
/**
* Create the HTML tag used for loading. This method does nothing by default, and needs to be implemented
* by loaders that require tag loading.
* @method _createTag
* @param {String} src The tag source
* @return {HTMLElement} The tag that was created
* @protected
*/
p._createTag = function(src) { return null; };
/**
* Dispatch a loadstart {{#crossLink "Event"}}{{/crossLink}}. Please see the {{#crossLink "AbstractLoader/loadstart:event"}}{{/crossLink}}
* event for details on the event payload.
* @method _sendLoadStart
* @protected
*/
p._sendLoadStart = function () {
if (this._isCanceled()) { return; }
this.dispatchEvent("loadstart");
};
/**
* Dispatch a {{#crossLink "ProgressEvent"}}{{/crossLink}}.
* @method _sendProgress
* @param {Number | Object} value The progress of the loaded item, or an object containing <code>loaded</code>
* and <code>total</code> properties.
* @protected
*/
p._sendProgress = function (value) {
if (this._isCanceled()) { return; }
var event = null;
if (typeof(value) == "number") {
this.progress = value;
event = new createjs.ProgressEvent(this.progress);
} else {
event = value;
this.progress = value.loaded / value.total;
event.progress = this.progress;
if (isNaN(this.progress) || this.progress == Infinity) { this.progress = 0; }
}
this.hasEventListener("progress") && this.dispatchEvent(event);
};
/**
* Dispatch a complete {{#crossLink "Event"}}{{/crossLink}}. Please see the {{#crossLink "AbstractLoader/complete:event"}}{{/crossLink}} event
* @method _sendComplete
* @protected
*/
p._sendComplete = function () {
if (this._isCanceled()) { return; }
this.loaded = true;
var event = new createjs.Event("complete");
event.rawResult = this._rawResult;
if (this._result != null) {
event.result = this._result;
}
this.dispatchEvent(event);
};
/**
* Dispatch an error {{#crossLink "Event"}}{{/crossLink}}. Please see the {{#crossLink "AbstractLoader/error:event"}}{{/crossLink}}
* event for details on the event payload.
* @method _sendError
* @param {ErrorEvent} event The event object containing specific error properties.
* @protected
*/
p._sendError = function (event) {
if (this._isCanceled() || !this.hasEventListener("error")) { return; }
if (event == null) {
event = new createjs.ErrorEvent("PRELOAD_ERROR_EMPTY"); // TODO: Populate error
}
this.dispatchEvent(event);
};
/**
* Determine if the load has been canceled. This is important to ensure that method calls or asynchronous events
* do not cause issues after the queue has been cleaned up.
* @method _isCanceled
* @return {Boolean} If the loader has been canceled.
* @protected
*/
p._isCanceled = function () {
if (window.createjs == null || this.canceled) {
return true;
}
return false;
};
/**
* A custom result formatter function, which is called just before a request dispatches its complete event. Most
* loader types already have an internal formatter, but this can be user-overridden for custom formatting. The
* formatted result will be available on Loaders using {{#crossLink "getResult"}}{{/crossLink}}, and passing `true`.
* @property resultFormatter
* @type Function
* @return {Object} The formatted result
* @since 0.6.0
*/
p.resultFormatter = null; //TODO: Add support for async formatting.
/**
* Handle events from internal requests. By default, loaders will handle, and redispatch the necessary events, but
* this method can be overridden for custom behaviours.
* @method handleEvent
* @param {Event} The event that the internal request dispatches.
* @protected
* @since 0.6.0
*/
p.handleEvent = function (event) {
switch (event.type) {
case "complete":
this._rawResult = event.target._response;
var result = this.resultFormatter && this.resultFormatter(this);
var _this = this;
if (result instanceof Function) {
result(function(result) {
_this._result = result;
_this._sendComplete();
});
} else {
this._result = result || this._rawResult;
this._sendComplete();
}
break;
case "progress":
this._sendProgress(event);
break;
case "error":
this._sendError(event);
break;
case "loadstart":
this._sendLoadStart();
break;
case "abort":
case "timeout":
if (!this._isCanceled()) {
this.dispatchEvent(event.type);
}
break;
}
};
/**
* @method buildPath
* @protected
* @deprecated Use the {{#crossLink "RequestUtils"}}{{/crossLink}} method {{#crossLink "RequestUtils/buildPath"}}{{/crossLink}}
* instead.
*/
p.buildPath = function (src, data) {
return createjs.RequestUtils.buildPath(src, data);
};
/**
* @method toString
* @return {String} a string representation of the instance.
*/
p.toString = function () {
return "[PreloadJS AbstractLoader]";
};
createjs.AbstractLoader = createjs.promote(AbstractLoader, "EventDispatcher");
}());
//##############################################################################
// AbstractMediaLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* The AbstractMediaLoader is a base class that handles some of the shared methods and properties of loaders that
* handle HTML media elements, such as Video and Audio.
* @class AbstractMediaLoader
* @param {LoadItem|Object} loadItem
* @param {Boolean} preferXHR
* @param {String} type The type of media to load. Usually "video" or "audio".
* @constructor
*/
function AbstractMediaLoader(loadItem, preferXHR, type) {
this.AbstractLoader_constructor(loadItem, preferXHR, type);
// public properties
this.resultFormatter = this._formatResult;
// protected properties
this._tagSrcAttribute = "src";
};
var p = createjs.extend(AbstractMediaLoader, createjs.AbstractLoader);
// static properties
// public methods
p.load = function () {
// TagRequest will handle most of this, but Sound / Video need a few custom properties, so just handle them here.
if (!this._tag) {
this._tag = this._createTag(this._item.src);
}
this._tag.preload = "auto";
this._tag.load();
this.AbstractLoader_load();
};
// protected methods
/**
* Creates a new tag for loading if it doesn't exist yet.
* @method _createTag
* @private
*/
p._createTag = function () {};
p._createRequest = function() {
if (!this._preferXHR) {
this._request = new createjs.MediaTagRequest(this._item, this._tag || this._createTag(), this._tagSrcAttribute);
} else {
this._request = new createjs.XHRRequest(this._item);
}
};
/**
* The result formatter for media files.
* @method _formatResult
* @param {AbstractLoader} loader
* @returns {HTMLVideoElement|HTMLAudioElement}
* @private
*/
p._formatResult = function (loader) {
this._tag.removeEventListener && this._tag.removeEventListener("canplaythrough", this._loadedHandler);
this._tag.onstalled = null;
if (this._preferXHR) {
loader.getTag().src = loader.getResult(true);
}
return loader.getTag();
};
createjs.AbstractMediaLoader = createjs.promote(AbstractMediaLoader, "AbstractLoader");
}());
//##############################################################################
// AbstractRequest.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
/**
* A base class for actual data requests, such as {{#crossLink "XHRRequest"}}{{/crossLink}}, {{#crossLink "TagRequest"}}{{/crossLink}},
* and {{#crossLink "MediaRequest"}}{{/crossLink}}. PreloadJS loaders will typically use a data loader under the
* hood to get data.
* @class AbstractRequest
* @param {LoadItem} item
* @constructor
*/
var AbstractRequest = function (item) {
this._item = item;
};
var p = createjs.extend(AbstractRequest, createjs.EventDispatcher);
// public methods
/**
* Begin a load.
* @method load
*/
p.load = function() {};
/**
* Clean up a request.
* @method destroy
*/
p.destroy = function() {};
/**
* Cancel an in-progress request.
* @method cancel
*/
p.cancel = function() {};
createjs.AbstractRequest = createjs.promote(AbstractRequest, "EventDispatcher");
}());
//##############################################################################
// TagRequest.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* An {{#crossLink "AbstractRequest"}}{{/crossLink}} that loads HTML tags, such as images and scripts.
* @class TagRequest
* @param {LoadItem} loadItem
* @param {HTMLElement} tag
* @param {String} srcAttribute The tag attribute that specifies the source, such as "src", "href", etc.
*/
function TagRequest(loadItem, tag, srcAttribute) {
this.AbstractRequest_constructor(loadItem);
// protected properties
/**
* The HTML tag instance that is used to load.
* @property _tag
* @type {HTMLElement}
* @protected
*/
this._tag = tag;
/**
* The tag attribute that specifies the source, such as "src", "href", etc.
* @property _tagSrcAttribute
* @type {String}
* @protected
*/
this._tagSrcAttribute = srcAttribute;
/**
* A method closure used for handling the tag load event.
* @property _loadedHandler
* @type {Function}
* @private
*/
this._loadedHandler = createjs.proxy(this._handleTagComplete, this);
/**
* Determines if the element was added to the DOM automatically by PreloadJS, so it can be cleaned up after.
* @property _addedToDOM
* @type {Boolean}
* @private
*/
this._addedToDOM = false;
/**
* Determines what the tags initial style.visibility was, so we can set it correctly after a load.
*
* @type {null}
* @private
*/
this._startTagVisibility = null;
};
var p = createjs.extend(TagRequest, createjs.AbstractRequest);
// public methods
p.load = function () {
if (this._tag.parentNode == null) {
window.document.body.appendChild(this._tag);
this._addedToDOM = true;
}
this._tag.onload = createjs.proxy(this._handleTagComplete, this);
this._tag.onreadystatechange = createjs.proxy(this._handleReadyStateChange, this);
var evt = new createjs.Event("initialize");
evt.loader = this._tag;
this.dispatchEvent(evt);
this._hideTag();
this._tag[this._tagSrcAttribute] = this._item.src;
};
p.destroy = function() {
this._clean();
this._tag = null;
this.AbstractRequest_destroy();
};
// private methods
/**
* Handle the readyStateChange event from a tag. We need this in place of the `onload` callback (mainly SCRIPT
* and LINK tags), but other cases may exist.
* @method _handleReadyStateChange
* @private
*/
p._handleReadyStateChange = function () {
clearTimeout(this._loadTimeout);
// This is strictly for tags in browsers that do not support onload.
var tag = this._tag;
// Complete is for old IE support.
if (tag.readyState == "loaded" || tag.readyState == "complete") {
this._handleTagComplete();
}
};
/**
* Handle the tag's onload callback.
* @method _handleTagComplete
* @private
*/
p._handleTagComplete = function () {
this._rawResult = this._tag;
this._result = this.resultFormatter && this.resultFormatter(this) || this._rawResult;
this._clean();
this._showTag();
this.dispatchEvent("complete");
};
/**
* Remove event listeners, but don't destroy the request object
* @method _clean
* @private
*/
p._clean = function() {
this._tag.onload = null;
this._tag.onreadystatechange = null;
if (this._addedToDOM && this._tag.parentNode != null) {
this._tag.parentNode.removeChild(this._tag);
}
};
p._hideTag = function() {
this._startTagVisibility = this._tag.style.visibility;
this._tag.style.visibility = "hidden";
};
p._showTag = function() {
this._tag.style.visibility = this._startTagVisibility;
};
/**
* Handle a stalled audio event. The main place this happens is with HTMLAudio in Chrome when playing back audio
* that is already in a load, but not complete.
* @method _handleStalled
* @private
*/
p._handleStalled = function () {
//Ignore, let the timeout take care of it. Sometimes its not really stopped.
};
createjs.TagRequest = createjs.promote(TagRequest, "AbstractRequest");
}());
//##############################################################################
// MediaTagRequest.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* An {{#crossLink "TagRequest"}}{{/crossLink}} that loads HTML tags for video and audio.
* @class MediaTagRequest
* @param {LoadItem} loadItem
* @param {HTMLAudioElement|HTMLVideoElement} tag
* @param {String} srcAttribute The tag attribute that specifies the source, such as "src", "href", etc.
* @constructor
*/
function MediaTagRequest(loadItem, tag, srcAttribute) {
this.AbstractRequest_constructor(loadItem);
// protected properties
this._tag = tag;
this._tagSrcAttribute = srcAttribute;
this._loadedHandler = createjs.proxy(this._handleTagComplete, this);
};
var p = createjs.extend(MediaTagRequest, createjs.TagRequest);
var s = MediaTagRequest;
// public methods
p.load = function () {
this._tag.onstalled = createjs.proxy(this._handleStalled, this);
this._tag.onprogress = createjs.proxy(this._handleProgress, this);
// This will tell us when audio is buffered enough to play through, but not when its loaded.
// The tag doesn't keep loading in Chrome once enough has buffered, and we have decided that behaviour is sufficient.
this._tag.addEventListener && this._tag.addEventListener("canplaythrough", this._loadedHandler, false); // canplaythrough callback doesn't work in Chrome, so we use an event.
this.TagRequest_load();
};
// private methods
p._handleReadyStateChange = function () {
clearTimeout(this._loadTimeout);
// This is strictly for tags in browsers that do not support onload.
var tag = this._tag;
// Complete is for old IE support.
if (tag.readyState == "loaded" || tag.readyState == "complete") {
this._handleTagComplete();
}
};
p._handleStalled = function () {
//Ignore, let the timeout take care of it. Sometimes its not really stopped.
};
/**
* An XHR request has reported progress.
* @method _handleProgress
* @param {Object} event The XHR progress event.
* @private
*/
p._handleProgress = function (event) {
if (!event || event.loaded > 0 && event.total == 0) {
return; // Sometimes we get no "total", so just ignore the progress event.
}
var newEvent = new createjs.ProgressEvent(event.loaded, event.total);
this.dispatchEvent(newEvent);
};
// protected methods
p._clean = function () {
this._tag.removeEventListener && this._tag.removeEventListener("canplaythrough", this._loadedHandler);
this._tag.onstalled = null;
this._tag.onprogress = null;
this.TagRequest__clean();
};
createjs.MediaTagRequest = createjs.promote(MediaTagRequest, "TagRequest");
}());
//##############################################################################
// XHRRequest.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A preloader that loads items using XHR requests, usually XMLHttpRequest. However XDomainRequests will be used
* for cross-domain requests if possible, and older versions of IE fall back on to ActiveX objects when necessary.
* XHR requests load the content as text or binary data, provide progress and consistent completion events, and
* can be canceled during load. Note that XHR is not supported in IE 6 or earlier, and is not recommended for
* cross-domain loading.
* @class XHRRequest
* @constructor
* @param {Object} item The object that defines the file to load. Please see the {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}}
* for an overview of supported file properties.
* @extends AbstractLoader
*/
function XHRRequest(item) {
this.AbstractRequest_constructor(item);
// protected properties
/**
* A reference to the XHR request used to load the content.
* @property _request
* @type {XMLHttpRequest | XDomainRequest | ActiveX.XMLHTTP}
* @private
*/
this._request = null;
/**
* A manual load timeout that is used for browsers that do not support the onTimeout event on XHR (XHR level 1,
* typically IE9).
* @property _loadTimeout
* @type {Number}
* @private
*/
this._loadTimeout = null;
/**
* The browser's XHR (XMLHTTPRequest) version. Supported versions are 1 and 2. There is no official way to detect
* the version, so we use capabilities to make a best guess.
* @property _xhrLevel
* @type {Number}
* @default 1
* @private
*/
this._xhrLevel = 1;
/**
* The response of a loaded file. This is set because it is expensive to look up constantly. This property will be
* null until the file is loaded.
* @property _response
* @type {mixed}
* @private
*/
this._response = null;
/**
* The response of the loaded file before it is modified. In most cases, content is converted from raw text to
* an HTML tag or a formatted object which is set to the <code>result</code> property, but the developer may still
* want to access the raw content as it was loaded.
* @property _rawResponse
* @type {String|Object}
* @private
*/
this._rawResponse = null;
this._canceled = false;
// Setup our event handlers now.
this._handleLoadStartProxy = createjs.proxy(this._handleLoadStart, this);
this._handleProgressProxy = createjs.proxy(this._handleProgress, this);
this._handleAbortProxy = createjs.proxy(this._handleAbort, this);
this._handleErrorProxy = createjs.proxy(this._handleError, this);
this._handleTimeoutProxy = createjs.proxy(this._handleTimeout, this);
this._handleLoadProxy = createjs.proxy(this._handleLoad, this);
this._handleReadyStateChangeProxy = createjs.proxy(this._handleReadyStateChange, this);
if (!this._createXHR(item)) {
//TODO: Throw error?
}
};
var p = createjs.extend(XHRRequest, createjs.AbstractRequest);
// static properties
/**
* A list of XMLHTTP object IDs to try when building an ActiveX object for XHR requests in earlier versions of IE.
* @property ACTIVEX_VERSIONS
* @type {Array}
* @since 0.4.2
* @private
*/
XHRRequest.ACTIVEX_VERSIONS = [
"Msxml2.XMLHTTP.6.0",
"Msxml2.XMLHTTP.5.0",
"Msxml2.XMLHTTP.4.0",
"MSXML2.XMLHTTP.3.0",
"MSXML2.XMLHTTP",
"Microsoft.XMLHTTP"
];
// Public methods
/**
* Look up the loaded result.
* @method getResult
* @param {Boolean} [raw=false] Return a raw result instead of a formatted result. This applies to content
* loaded via XHR such as scripts, XML, CSS, and Images. If there is no raw result, the formatted result will be
* returned instead.
* @return {Object} A result object containing the content that was loaded, such as:
* <ul>
* <li>An image tag (<image />) for images</li>
* <li>A script tag for JavaScript (<script />). Note that scripts loaded with tags may be added to the
* HTML head.</li>
* <li>A style tag for CSS (<style />)</li>
* <li>Raw text for TEXT</li>
* <li>A formatted JavaScript object defined by JSON</li>
* <li>An XML document</li>
* <li>An binary arraybuffer loaded by XHR</li>
* </ul>
* Note that if a raw result is requested, but not found, the result will be returned instead.
*/
p.getResult = function (raw) {
if (raw && this._rawResponse) {
return this._rawResponse;
}
return this._response;
};
// Overrides abstract method in AbstractRequest
p.cancel = function () {
this.canceled = true;
this._clean();
this._request.abort();
};
// Overrides abstract method in AbstractLoader
p.load = function () {
if (this._request == null) {
this._handleError();
return;
}
//Events
this._request.addEventListener("loadstart", this._handleLoadStartProxy, false);
this._request.addEventListener("progress", this._handleProgressProxy, false);
this._request.addEventListener("abort", this._handleAbortProxy, false);
this._request.addEventListener("error",this._handleErrorProxy, false);
this._request.addEventListener("timeout", this._handleTimeoutProxy, false);
// Note: We don't get onload in all browsers (earlier FF and IE). onReadyStateChange handles these.
this._request.addEventListener("load", this._handleLoadProxy, false);
this._request.addEventListener("readystatechange", this._handleReadyStateChangeProxy, false);
// Set up a timeout if we don't have XHR2
if (this._xhrLevel == 1) {
this._loadTimeout = setTimeout(createjs.proxy(this._handleTimeout, this), this._item.loadTimeout);
}
// Sometimes we get back 404s immediately, particularly when there is a cross origin request. // note this does not catch in Chrome
try {
if (!this._item.values || this._item.method == createjs.AbstractLoader.GET) {
this._request.send();
} else if (this._item.method == createjs.AbstractLoader.POST) {
this._request.send(createjs.RequestUtils.formatQueryString(this._item.values));
}
} catch (error) {
this.dispatchEvent(new createjs.ErrorEvent("XHR_SEND", null, error));
}
};
p.setResponseType = function (type) {
this._request.responseType = type;
};
/**
* Get all the response headers from the XmlHttpRequest.
*
* <strong>From the docs:</strong> Return all the HTTP headers, excluding headers that are a case-insensitive match
* for Set-Cookie or Set-Cookie2, as a single string, with each header line separated by a U+000D CR U+000A LF pair,
* excluding the status line, and with each header name and header value separated by a U+003A COLON U+0020 SPACE
* pair.
* @method getAllResponseHeaders
* @return {String}
* @since 0.4.1
*/
p.getAllResponseHeaders = function () {
if (this._request.getAllResponseHeaders instanceof Function) {
return this._request.getAllResponseHeaders();
} else {
return null;
}
};
/**
* Get a specific response header from the XmlHttpRequest.
*
* <strong>From the docs:</strong> Returns the header field value from the response of which the field name matches
* header, unless the field name is Set-Cookie or Set-Cookie2.
* @method getResponseHeader
* @param {String} header The header name to retrieve.
* @return {String}
* @since 0.4.1
*/
p.getResponseHeader = function (header) {
if (this._request.getResponseHeader instanceof Function) {
return this._request.getResponseHeader(header);
} else {
return null;
}
};
// protected methods
/**
* The XHR request has reported progress.
* @method _handleProgress
* @param {Object} event The XHR progress event.
* @private
*/
p._handleProgress = function (event) {
if (!event || event.loaded > 0 && event.total == 0) {
return; // Sometimes we get no "total", so just ignore the progress event.
}
var newEvent = new createjs.ProgressEvent(event.loaded, event.total);
this.dispatchEvent(newEvent);
};
/**
* The XHR request has reported a load start.
* @method _handleLoadStart
* @param {Object} event The XHR loadStart event.
* @private
*/
p._handleLoadStart = function (event) {
clearTimeout(this._loadTimeout);
this.dispatchEvent("loadstart");
};
/**
* The XHR request has reported an abort event.
* @method handleAbort
* @param {Object} event The XHR abort event.
* @private
*/
p._handleAbort = function (event) {
this._clean();
this.dispatchEvent(new createjs.ErrorEvent("XHR_ABORTED", null, event));
};
/**
* The XHR request has reported an error event.
* @method _handleError
* @param {Object} event The XHR error event.
* @private
*/
p._handleError = function (event) {
this._clean();
this.dispatchEvent(new createjs.ErrorEvent(event.message));
};
/**
* The XHR request has reported a readyState change. Note that older browsers (IE 7 & 8) do not provide an onload
* event, so we must monitor the readyStateChange to determine if the file is loaded.
* @method _handleReadyStateChange
* @param {Object} event The XHR readyStateChange event.
* @private
*/
p._handleReadyStateChange = function (event) {
if (this._request.readyState == 4) {
this._handleLoad();
}
};
/**
* The XHR request has completed. This is called by the XHR request directly, or by a readyStateChange that has
* <code>request.readyState == 4</code>. Only the first call to this method will be processed.
* @method _handleLoad
* @param {Object} event The XHR load event.
* @private
*/
p._handleLoad = function (event) {
if (this.loaded) {
return;
}
this.loaded = true;
var error = this._checkError();
if (error) {
this._handleError(error);
return;
}
this._response = this._getResponse();
this._clean();
this.dispatchEvent(new createjs.Event("complete"));
};
/**
* The XHR request has timed out. This is called by the XHR request directly, or via a <code>setTimeout</code>
* callback.
* @method _handleTimeout
* @param {Object} [event] The XHR timeout event. This is occasionally null when called by the backup setTimeout.
* @private
*/
p._handleTimeout = function (event) {
this._clean();
this.dispatchEvent(new createjs.ErrorEvent("PRELOAD_TIMEOUT", null, event));
};
// Protected
/**
* Determine if there is an error in the current load. This checks the status of the request for problem codes. Note
* that this does not check for an actual response. Currently, it only checks for 404 or 0 error code.
* @method _checkError
* @return {int} If the request status returns an error code.
* @private
*/
p._checkError = function () {
//LM: Probably need additional handlers here, maybe 501
var status = parseInt(this._request.status);
switch (status) {
case 404: // Not Found
case 0: // Not Loaded
return new Error(status);
}
return null;
};
/**
* Validate the response. Different browsers have different approaches, some of which throw errors when accessed
* in other browsers. If there is no response, the <code>_response</code> property will remain null.
* @method _getResponse
* @private
*/
p._getResponse = function () {
if (this._response != null) {
return this._response;
}
if (this._request.response != null) {
return this._request.response;
}
// Android 2.2 uses .responseText
try {
if (this._request.responseText != null) {
return this._request.responseText;
}
} catch (e) {
}
// When loading XML, IE9 does not return .response, instead it returns responseXML.xml
try {
if (this._request.responseXML != null) {
return this._request.responseXML;
}
} catch (e) {
}
return null;
};
/**
* Create an XHR request. Depending on a number of factors, we get totally different results.
* <ol><li>Some browsers get an <code>XDomainRequest</code> when loading cross-domain.</li>
* <li>XMLHttpRequest are created when available.</li>
* <li>ActiveX.XMLHTTP objects are used in older IE browsers.</li>
* <li>Text requests override the mime type if possible</li>
* <li>Origin headers are sent for crossdomain requests in some browsers.</li>
* <li>Binary loads set the response type to "arraybuffer"</li></ol>
* @method _createXHR
* @param {Object} item The requested item that is being loaded.
* @return {Boolean} If an XHR request or equivalent was successfully created.
* @private
*/
p._createXHR = function (item) {
// Check for cross-domain loads. We can't fully support them, but we can try.
var crossdomain = createjs.RequestUtils.isCrossDomain(item);
var headers = {};
// Create the request. Fallback to whatever support we have.
var req = null;
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
// This is 8 or 9, so use XDomainRequest instead.
if (crossdomain && req.withCredentials === undefined && window.XDomainRequest) {
req = new XDomainRequest();
}
} else { // Old IE versions use a different approach
for (var i = 0, l = s.ACTIVEX_VERSIONS.length; i < l; i++) {
var axVersion = s.ACTIVEX_VERSIONS[i];
try {
req = new ActiveXObject(axVersions);
break;
} catch (e) {}
}
if (req == null) { return false; }
}
// Default to utf-8 for Text requests.
if (item.mimeType == null && createjs.RequestUtils.isText(item.type)) {
item.mimeType = "text/plain; charset=utf-8";
}
// IE9 doesn't support overrideMimeType(), so we need to check for it.
if (item.mimeType && req.overrideMimeType) {
req.overrideMimeType(item.mimeType);
}
// Determine the XHR level
this._xhrLevel = (typeof req.responseType === "string") ? 2 : 1;
var src = null;
if (item.method == createjs.AbstractLoader.GET) {
src = createjs.RequestUtils.buildPath(item.src, item.values);
} else {
src = item.src;
}
// Open the request. Set cross-domain flags if it is supported (XHR level 1 only)
req.open(item.method || createjs.AbstractLoader.GET, src, true);
if (crossdomain && req instanceof XMLHttpRequest && this._xhrLevel == 1) {
headers["Origin"] = location.origin;
}
// To send data we need to set the Content-type header)
if (item.values && item.method == createjs.AbstractLoader.POST) {
headers["Content-Type"] = "application/x-www-form-urlencoded";
}
if (!crossdomain && !headers["X-Requested-With"]) {
headers["X-Requested-With"] = "XMLHttpRequest";
}
if (item.headers) {
for (var n in item.headers) {
headers[n] = item.headers[n];
}
}
for (n in headers) {
req.setRequestHeader(n, headers[n])
}
if (req instanceof XMLHttpRequest && item.withCredentials !== undefined) {
req.withCredentials = item.withCredentials;
}
this._request = req;
return true;
};
/**
* A request has completed (or failed or canceled), and needs to be disposed.
* @method _clean
* @private
*/
p._clean = function () {
clearTimeout(this._loadTimeout);
this._request.removeEventListener("loadstart", this._handleLoadStartProxy);
this._request.removeEventListener("progress", this._handleProgressProxy);
this._request.removeEventListener("abort", this._handleAbortProxy);
this._request.removeEventListener("error",this._handleErrorProxy);
this._request.removeEventListener("timeout", this._handleTimeoutProxy);
this._request.removeEventListener("load", this._handleLoadProxy);
this._request.removeEventListener("readystatechange", this._handleReadyStateChangeProxy);
};
p.toString = function () {
return "[PreloadJS XHRRequest]";
};
createjs.XHRRequest = createjs.promote(XHRRequest, "AbstractRequest");
}());
//##############################################################################
// LoadQueue.js
//##############################################################################
this.createjs = this.createjs || {};
/*
TODO: WINDOWS ISSUES
* No error for HTML audio in IE 678
* SVG no failure error in IE 67 (maybe 8) TAGS AND XHR
* No script complete handler in IE 67 TAGS (XHR is fine)
* No XML/JSON in IE6 TAGS
* Need to hide loading SVG in Opera TAGS
* No CSS onload/readystatechange in Safari or Android TAGS (requires rule checking)
* SVG no load or failure in Opera XHR
* Reported issues with IE7/8
*/
(function () {
"use strict";
// constructor
/**
* The LoadQueue class is the main API for preloading content. LoadQueue is a load manager, which can preload either
* a single file, or queue of files.
*
* <b>Creating a Queue</b><br />
* To use LoadQueue, create a LoadQueue instance. If you want to force tag loading where possible, set the preferXHR
* argument to false.
*
* var queue = new createjs.LoadQueue(true);
*
* <b>Listening for Events</b><br />
* Add any listeners you want to the queue. Since PreloadJS 0.3.0, the {{#crossLink "EventDispatcher"}}{{/crossLink}}
* lets you add as many listeners as you want for events. You can subscribe to the following events:<ul>
* <li>{{#crossLink "AbstractLoader/complete:event"}}{{/crossLink}}: fired when a queue completes loading all
* files</li>
* <li>{{#crossLink "AbstractLoader/error:event"}}{{/crossLink}}: fired when the queue encounters an error with
* any file.</li>
* <li>{{#crossLink "AbstractLoader/progress:event"}}{{/crossLink}}: Progress for the entire queue has
* changed.</li>
* <li>{{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}}: A single file has completed loading.</li>
* <li>{{#crossLink "LoadQueue/fileprogress:event"}}{{/crossLink}}: Progress for a single file has changes. Note
* that only files loaded with XHR (or possibly by plugins) will fire progress events other than 0 or 100%.</li>
* </ul>
*
* queue.on("fileload", handleFileLoad, this);
* queue.on("complete", handleComplete, this);
*
* <b>Adding files and manifests</b><br />
* Add files you want to load using {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} or add multiple files at a
* time using a list or a manifest definition using {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}}. Files are
* appended to the end of the active queue, so you can use these methods as many times as you like, whenever you
* like.
*
* queue.loadFile("filePath/file.jpg");
* queue.loadFile({id:"image", src:"filePath/file.jpg"});
* queue.loadManifest(["filePath/file.jpg", {id:"image", src:"filePath/file.jpg"}]);
*
* // Use an external manifest
* queue.loadManifest("path/to/manifest.json");
* queue.loadManifest({src:"manifest.json", type:"manifest"});
*
* If you pass `false` as the `loadNow` parameter, the queue will not kick of the load of the files, but it will not
* stop if it has already been started. Call the {{#crossLink "AbstractLoader/load"}}{{/crossLink}} method to begin
* a paused queue. Note that a paused queue will automatically resume when new files are added to it with a
* `loadNow` argument of `true`.
*
* queue.load();
*
* <b>File Types</b><br />
* The file type of a manifest item is auto-determined by the file extension. The pattern matching in PreloadJS
* should handle the majority of standard file and url formats, and works with common file extensions. If you have
* either a non-standard file extension, or are serving the file using a proxy script, then you can pass in a
* <code>type</code> property with any manifest item.
*
* queue.loadFile({src:"path/to/myFile.mp3x", type:createjs.AbstractLoader.SOUND});
*
* // Note that PreloadJS will not read a file extension from the query string
* queue.loadFile({src:"http://server.com/proxy?file=image.jpg", type:createjs.AbstractLoader.IMAGE});
*
* Supported types are defined on the {{#crossLink "AbstractLoader"}}{{/crossLink}} class, and include:
* <ul>
* <li>{{#crossLink "AbstractLoader/BINARY:property"}}{{/crossLink}}: Raw binary data via XHR</li>
* <li>{{#crossLink "AbstractLoader/CSS:property"}}{{/crossLink}}: CSS files</li>
* <li>{{#crossLink "AbstractLoader/IMAGE:property"}}{{/crossLink}}: Common image formats</li>
* <li>{{#crossLink "AbstractLoader/JAVASCRIPT:property"}}{{/crossLink}}: JavaScript files</li>
* <li>{{#crossLink "AbstractLoader/JSON:property"}}{{/crossLink}}: JSON data</li>
* <li>{{#crossLink "AbstractLoader/JSONP:property"}}{{/crossLink}}: JSON files cross-domain</li>
* <li>{{#crossLink "AbstractLoader/MANIFEST:property"}}{{/crossLink}}: A list of files to load in JSON format, see
* {{#crossLink "AbstractLoader/loadManifest"}}{{/crossLink}}</li>
* <li>{{#crossLink "AbstractLoader/SOUND:property"}}{{/crossLink}}: Audio file formats</li>
* <li>{{#crossLink "AbstractLoader/SPRITESHEET:property"}}{{/crossLink}}: JSON SpriteSheet definiteions. This
* will also load sub-images, and provide a {{#crossLink "SpriteSheet"}}{{/crossLink}} instance.</li>
* <li>{{#crossLink "AbstractLoader/SVG:property"}}{{/crossLink}}: SVG files</li>
* <li>{{#crossLink "AbstractLoader/TEXT:property"}}{{/crossLink}}: Text files - XHR only</li>
* <li>{{#crossLink "AbstractLoader/XML:property"}}{{/crossLink}}: XML data</li>
* </ul>
*
* <em>Note: Loader types used to be defined on LoadQueue, but have been moved to AbstractLoader for better
* portability of loader classes, which can be used individually now. The properties on LoadQueue still exist, but
* are deprecated.</em>
*
* <b>Handling Results</b><br />
* When a file is finished downloading, a {{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}} event is
* dispatched. In an example above, there is an event listener snippet for fileload. Loaded files are usually a
* formatted object that can be used immediately, including:
* <ul>
* <li>Binary: The binary loaded result</li>
* <li>CSS: A <link /> tag</li>
* <li>Image: An <img /> tag</li>
* <li>JavaScript: A <script /> tag</li>
* <li>JSON/JSONP: A formatted JavaScript Object</li>
* <li>Manifest: A JavaScript object.
* <li>Sound: An <audio /> tag</a>
* <li>SpriteSheet: A {{#crossLink "SpriteSheet"}}{{/crossLink}} instance, containing loaded images.
* <li>SVG: An <object /> tag</li>
* <li>Text: Raw text</li>
* <li>XML: An XML DOM node</li>
* </ul>
*
* function handleFileLoad(event) {
* var item = event.item; // A reference to the item that was passed in to the LoadQueue
* var type = item.type;
*
* // Add any images to the page body.
* if (type == createjs.LoadQueue.IMAGE) {
* document.body.appendChild(event.result);
* }
* }
*
* At any time after the file has been loaded (usually after the queue has completed), any result can be looked up
* via its "id" using {{#crossLink "LoadQueue/getResult"}}{{/crossLink}}. If no id was provided, then the
* "src" or file path can be used instead, including the `path` defined by a manifest, but <strong>not including</strong>
* a base path defined on the LoadQueue. It is recommended to always pass an id if you want to look up content.
*
* var image = queue.getResult("image");
* document.body.appendChild(image);
*
* Raw loaded content can be accessed using the <code>rawResult</code> property of the {{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}}
* event, or can be looked up using {{#crossLink "LoadQueue/getResult"}}{{/crossLink}}, passing `true` as the 2nd
* argument. This is only applicable for content that has been parsed for the browser, specifically: JavaScript,
* CSS, XML, SVG, and JSON objects, or anything loaded with XHR.
*
* var image = queue.getResult("image", true); // load the binary image data loaded with XHR.
*
* <b>Plugins</b><br />
* LoadQueue has a simple plugin architecture to help process and preload content. For example, to preload audio,
* make sure to install the <a href="http://soundjs.com">SoundJS</a> Sound class, which will help load HTML audio,
* Flash audio, and WebAudio files. This should be installed <strong>before</strong> loading any audio files.
*
* queue.installPlugin(createjs.Sound);
*
* <h4>Known Browser Issues</h4>
* <ul>
* <li>Browsers without audio support can not load audio files.</li>
* <li>Safari on Mac OS X can only play HTML audio if QuickTime is installed</li>
* <li>HTML Audio tags will only download until their <code>canPlayThrough</code> event is fired. Browsers other
* than Chrome will continue to download in the background.</li>
* <li>When loading scripts using tags, they are automatically added to the document.</li>
* <li>Scripts loaded via XHR may not be properly inspectable with browser tools.</li>
* <li>IE6 and IE7 (and some other browsers) may not be able to load XML, Text, or JSON, since they require
* XHR to work.</li>
* <li>Content loaded via tags will not show progress, and will continue to download in the background when
* canceled, although no events will be dispatched.</li>
* </ul>
*
* @class LoadQueue
* @param {Boolean} [preferXHR=true] Determines whether the preload instance will favor loading with XHR (XML HTTP
* Requests), or HTML tags. When this is `false`, the queue will use tag loading when possible, and fall back on XHR
* when necessary.
* @param {String} [basePath=""] A path that will be prepended on to the source parameter of all items in the queue
* before they are loaded. Sources beginning with a protocol such as `http://` or a relative path such as `../`
* will not receive a base path.
* @param {String|Boolean} [crossOrigin=""] An optional flag to support images loaded from a CORS-enabled server. To
* use it, set this value to `true`, which will default the crossOrigin property on images to "Anonymous". Any
* string value will be passed through, but only "" and "Anonymous" are recommended. <strong>Note: The crossOrigin
* parameter is deprecated. Use LoadItem.crossOrigin instead</strong>
*
* @constructor
* @extends AbstractLoader
*/
function LoadQueue(preferXHR, basePath, crossOrigin) {
this.AbstractLoader_constructor();
this.init(preferXHR, basePath, crossOrigin);
}
var p = createjs.extend(LoadQueue, createjs.AbstractLoader);
var s = LoadQueue;
/**
* <strong>REMOVED</strong>. Removed in favor of using `MySuperClass_constructor`.
* See {{#crossLink "Utility Methods/extend"}}{{/crossLink}} and {{#crossLink "Utility Methods/promote"}}{{/crossLink}}
* for details.
*
* There is an inheritance tutorial distributed with EaselJS in /tutorials/Inheritance.
*
* @method initialize
* @protected
* @deprecated
*/
// p.initialize = function() {}; // searchable for devs wondering where it is.
/**
* An internal initialization method, which is used for initial set up, but also to reset the LoadQueue.
* @method init
* @param preferXHR
* @param basePath
* @param crossOrigin
* @private
*/
p.init = function(preferXHR, basePath, crossOrigin) {
// public properties
/**
* @property useXHR
* @type {Boolean}
* @readOnly
* @default true
* @deprecated Use preferXHR instead.
*/
this.useXHR = true;
/**
* Try and use XMLHttpRequest (XHR) when possible. Note that LoadQueue will default to tag loading or XHR
* loading depending on the requirements for a media type. For example, HTML audio can not be loaded with XHR,
* and plain text can not be loaded with tags, so it will default the the correct type instead of using the
* user-defined type.
* @type {Boolean}
* @default true
* @since 0.6.0
*/
this.preferXHR = true; //TODO: Get/Set
this._preferXHR = true;
this.setPreferXHR(preferXHR);
/**
* Determines if the LoadQueue will stop processing the current queue when an error is encountered.
* @property stopOnError
* @type {Boolean}
* @default false
*/
this.stopOnError = false;
/**
* Ensure loaded scripts "complete" in the order they are specified. Loaded scripts are added to the document head
* once they are loaded. Scripts loaded via tags will load one-at-a-time when this property is `true`, whereas
* scripts loaded using XHR can load in any order, but will "finish" and be added to the document in the order
* specified.
*
* Any items can be set to load in order by setting the {{#crossLink "maintainOrder:property"}}{{/crossLink}}
* property on the load item, or by ensuring that only one connection can be open at a time using
* {{#crossLink "LoadQueue/setMaxConnections"}}{{/crossLink}}. Note that when the `maintainScriptOrder` property
* is set to `true`, scripts items are automatically set to `maintainOrder=true`, and changing the
* `maintainScriptOrder` to `false` during a load will not change items already in a queue.
*
* <h4>Example</h4>
*
* var queue = new createjs.LoadQueue();
* queue.setMaxConnections(3); // Set a higher number to load multiple items at once
* queue.maintainScriptOrder = true; // Ensure scripts are loaded in order
* queue.loadManifest([
* "script1.js",
* "script2.js",
* "image.png", // Load any time
* {src: "image2.png", maintainOrder: true} // Will wait for script2.js
* "image3.png",
* "script3.js" // Will wait for image2.png before loading (or completing when loading with XHR)
* ]);
*
* @property maintainScriptOrder
* @type {Boolean}
* @default true
*/
this.maintainScriptOrder = true;
/**
* The next preload queue to process when this one is complete. If an error is thrown in the current queue, and
* {{#crossLink "LoadQueue/stopOnError:property"}}{{/crossLink}} is `true`, the next queue will not be processed.
* @property next
* @type {LoadQueue}
* @default null
*/
this.next = null;
// protected properties
/**
* Whether the queue is currently paused or not.
* @property _paused
* @type {boolean}
* @private
*/
this._paused = false;
/**
* A path that will be prepended on to the item's {{#crossLink "LoadItem/src:property"}}{{/crossLink}}. The
* `_basePath` property will only be used if an item's source is relative, and does not include a protocol such
* as `http://`, or a relative path such as `../`.
* @property _basePath
* @type {String}
* @private
* @since 0.3.1
*/
this._basePath = basePath;
/**
* An optional flag to set on images that are loaded using PreloadJS, which enables CORS support. Images loaded
* cross-domain by servers that support CORS require the crossOrigin flag to be loaded and interacted with by
* a canvas. When loading locally, or with a server with no CORS support, this flag can cause other security issues,
* so it is recommended to only set it if you are sure the server supports it. Currently, supported values are ""
* and "Anonymous".
* @property _crossOrigin
* @type {String}
* @default ""
* @private
* @since 0.4.1
*/
this._crossOrigin = crossOrigin;
/**
* An object hash of callbacks that are fired for each file type before the file is loaded, giving plugins the
* ability to override properties of the load. Please see the {{#crossLink "LoadQueue/installPlugin"}}{{/crossLink}}
* method for more information.
* @property _typeCallbacks
* @type {Object}
* @private
*/
this._typeCallbacks = {};
/**
* An object hash of callbacks that are fired for each file extension before the file is loaded, giving plugins the
* ability to override properties of the load. Please see the {{#crossLink "LoadQueue/installPlugin"}}{{/crossLink}}
* method for more information.
* @property _extensionCallbacks
* @type {null}
* @private
*/
this._extensionCallbacks = {};
/**
* Determines if the loadStart event was dispatched already. This event is only fired one time, when the first
* file is requested.
* @property _loadStartWasDispatched
* @type {Boolean}
* @default false
* @private
*/
this._loadStartWasDispatched = false;
/**
* The number of maximum open connections that a loadQueue tries to maintain. Please see
* {{#crossLink "LoadQueue/setMaxConnections"}}{{/crossLink}} for more information.
* @property _maxConnections
* @type {Number}
* @default 1
* @private
*/
this._maxConnections = 1;
/**
* Determines if there is currently a script loading. This helps ensure that only a single script loads at once when
* using a script tag to do preloading.
* @property _currentlyLoadingScript
* @type {Boolean}
* @private
*/
this._currentlyLoadingScript = null;
/**
* An array containing the currently downloading files.
* @property _currentLoads
* @type {Array}
* @private
*/
this._currentLoads = [];
/**
* An array containing the queued items that have not yet started downloading.
* @property _loadQueue
* @type {Array}
* @private
*/
this._loadQueue = [];
/**
* An array containing downloads that have not completed, so that the LoadQueue can be properly reset.
* @property _loadQueueBackup
* @type {Array}
* @private
*/
this._loadQueueBackup = [];
/**
* An object hash of items that have finished downloading, indexed by the {{#crossLink "LoadItem"}}{{/crossLink}}
* id.
* @property _loadItemsById
* @type {Object}
* @private
*/
this._loadItemsById = {};
/**
* An object hash of items that have finished downloading, indexed by {{#crossLink "LoadItem"}}{{/crossLink}}
* source.
* @property _loadItemsBySrc
* @type {Object}
* @private
*/
this._loadItemsBySrc = {};
/**
* An object hash of loaded items, indexed by the ID of the {{#crossLink "LoadItem"}}{{/crossLink}}.
* @property _loadedResults
* @type {Object}
* @private
*/
this._loadedResults = {};
/**
* An object hash of un-parsed loaded items, indexed by the ID of the {{#crossLink "LoadItem"}}{{/crossLink}}.
* @property _loadedRawResults
* @type {Object}
* @private
*/
this._loadedRawResults = {};
/**
* The number of items that have been requested. This helps manage an overall progress without knowing how large
* the files are before they are downloaded. This does not include items inside of loaders such as the
* {{#crossLink "ManifestLoader"}}{{/crossLink}}.
* @property _numItems
* @type {Number}
* @default 0
* @private
*/
this._numItems = 0;
/**
* The number of items that have completed loaded. This helps manage an overall progress without knowing how large
* the files are before they are downloaded.
* @property _numItemsLoaded
* @type {Number}
* @default 0
* @private
*/
this._numItemsLoaded = 0;
/**
* A list of scripts in the order they were requested. This helps ensure that scripts are "completed" in the right
* order.
* @property _scriptOrder
* @type {Array}
* @private
*/
this._scriptOrder = [];
/**
* A list of scripts that have been loaded. Items are added to this list as <code>null</code> when they are
* requested, contain the loaded item if it has completed, but not been dispatched to the user, and <code>true</true>
* once they are complete and have been dispatched.
* @property _loadedScripts
* @type {Array}
* @private
*/
this._loadedScripts = [];
/**
* The last progress amount. This is used to suppress duplicate progress events.
* @property _lastProgress
* @type {Number}
* @private
* @since 0.6.0
*/
this._lastProgress = NaN;
/**
* An internal list of all the default Loaders that are included with PreloadJS. Before an item is loaded, the
* available loader list is iterated, in the order they are included, and as soon as a loader indicates it can
* handle the content, it will be selected. The default loader, ({{#crossLink "TextLoader"}}{{/crossLink}} is
* last in the list, so it will be used if no other match is found. Typically, loaders will match based on the
* {{#crossLink "LoadItem/type"}}{{/crossLink}}, which is automatically determined using the file extension of
* the {{#crossLink "LoadItem/src:property"}}{{/crossLink}}.
*
* Loaders can be removed from PreloadJS by simply not including them.
*
* Custom loaders installed using {{#crossLink "registerLoader"}}{{/crossLink}} will be prepended to this list
* so that they are checked first.
* @property _availableLoaders
* @type {Array}
* @private
* @since 0.6.0
*/
this._availableLoaders = [
createjs.ImageLoader,
createjs.JavaScriptLoader,
createjs.CSSLoader,
createjs.JSONLoader,
createjs.JSONPLoader,
createjs.SoundLoader,
createjs.ManifestLoader,
createjs.SpriteSheetLoader,
createjs.XMLLoader,
createjs.SVGLoader,
createjs.BinaryLoader,
createjs.VideoLoader,
createjs.TextLoader,
];
/**
* The number of built in loaders, so they can't be removed by {{#crossLink "unregisterLoader"}}{{/crossLink}.
* @property _defaultLoaderLength
* @type {Number}
* @private
* @since 0.6.0
*/
this._defaultLoaderLength = this._availableLoaders.length;
};
// static properties
/**
* The time in milliseconds to assume a load has failed. An {{#crossLink "AbstractLoader/error:event"}}{{/crossLink}}
* event is dispatched if the timeout is reached before any data is received.
* @property loadTimeout
* @type {Number}
* @default 8000
* @static
* @since 0.4.1
* @deprecated In favour of LoadItem.loadTimeout
*/
s.loadTimeout = 8000;
/**
* The time in milliseconds to assume a load has failed.
* @property LOAD_TIMEOUT
* @type {Number}
* @default 0
* @deprecated in favor of the {{#crossLink "LoadQueue/loadTimeout:property"}}{{/crossLink}} property.
*/
s.LOAD_TIMEOUT = 0;
// Preload Types
/**
* @property BINARY
* @type {String}
* @default binary
* @static
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/BINARY:property"}}{{/crossLink}} instead.
*/
s.BINARY = createjs.AbstractLoader.BINARY;
/**
* @property CSS
* @type {String}
* @default css
* @static
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/CSS:property"}}{{/crossLink}} instead.
*/
s.CSS = createjs.AbstractLoader.CSS;
/**
* @property IMAGE
* @type {String}
* @default image
* @static
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/CSS:property"}}{{/crossLink}} instead.
*/
s.IMAGE = createjs.AbstractLoader.IMAGE;
/**
* @property JAVASCRIPT
* @type {String}
* @default javascript
* @static
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/JAVASCRIPT:property"}}{{/crossLink}} instead.
*/
s.JAVASCRIPT = createjs.AbstractLoader.JAVASCRIPT;
/**
* @property JSON
* @type {String}
* @default json
* @static
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/JSON:property"}}{{/crossLink}} instead.
*/
s.JSON = createjs.AbstractLoader.JSON;
/**
* @property JSONP
* @type {String}
* @default jsonp
* @static
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/JSONP:property"}}{{/crossLink}} instead.
*/
s.JSONP = createjs.AbstractLoader.JSONP;
/**
* @property MANIFEST
* @type {String}
* @default manifest
* @static
* @since 0.4.1
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/MANIFEST:property"}}{{/crossLink}} instead.
*/
s.MANIFEST = createjs.AbstractLoader.MANIFEST;
/**
* @property SOUND
* @type {String}
* @default sound
* @static
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/JAVASCRIPT:property"}}{{/crossLink}} instead.
*/
s.SOUND = createjs.AbstractLoader.SOUND;
/**
* @property VIDEO
* @type {String}
* @default video
* @static
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/JAVASCRIPT:property"}}{{/crossLink}} instead.
*/
s.VIDEO = createjs.AbstractLoader.VIDEO;
/**
* @property SVG
* @type {String}
* @default svg
* @static
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/SVG:property"}}{{/crossLink}} instead.
*/
s.SVG = createjs.AbstractLoader.SVG;
/**
* @property TEXT
* @type {String}
* @default text
* @static
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/TEXT:property"}}{{/crossLink}} instead.
*/
s.TEXT = createjs.AbstractLoader.TEXT;
/**
* @property XML
* @type {String}
* @default xml
* @static
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/XML:property"}}{{/crossLink}} instead.
*/
s.XML = createjs.AbstractLoader.XML;
/**
* @property POST
* @type {string}
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/POST:property"}}{{/crossLink}} instead.
*/
s.POST = createjs.AbstractLoader.POST;
/**
* @property GET
* @type {string}
* @deprecated Use the AbstractLoader {{#crossLink "AbstractLoader/GET:property"}}{{/crossLink}} instead.
*/
s.GET = createjs.AbstractLoader.GET;
// events
/**
* This event is fired when an individual file has loaded, and been processed.
* @event fileload
* @param {Object} target The object that dispatched the event.
* @param {String} type The event type.
* @param {Object} item The file item which was specified in the {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}}
* or {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}} call. If only a string path or tag was specified, the
* object will contain that value as a `src` property.
* @param {Object} result The HTML tag or parsed result of the loaded item.
* @param {Object} rawResult The unprocessed result, usually the raw text or binary data before it is converted
* to a usable object.
* @since 0.3.0
*/
/**
* This {{#crossLink "ProgressEvent"}}{{/crossLink}} that is fired when an an individual file's progress changes.
* @event fileprogress
* @since 0.3.0
*/
/**
* This event is fired when an individual file starts to load.
* @event filestart
* @param {Object} The object that dispatched the event.
* @param {String} type The event type.
* @param {Object} item The file item which was specified in the {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}}
* or {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}} call. If only a string path or tag was specified, the
* object will contain that value as a property.
*/
// public methods
/**
* Register a custom loaders class. New loaders are given precedence over loaders added earlier and default loaders.
* It is recommended that loaders extend {{#crossLink "AbstractLoader"}}{{/crossLink}}. Loaders can only be added
* once, and will be prepended to the list of available loaders.
* @method registerLoader
* @param {Class} The AbstractLoader class to add.
* @since 0.6.0
*/
p.registerLoader = function (loader) {
if (!loader || !loader.canLoadItem) {
throw new Error("loader is of an incorrect type.");
} else if (this._availableLoaders.indexOf(loader) != -1) {
throw new Error("loader already exists."); //LM: Maybe just silently fail here
}
this._availableLoaders.unshift(loader);
};
/**
* Remove a custom loader added usig {{#crossLink "registerLoader"}}{{/crossLink}}. Only custom loaders can be
* unregistered, the default loaders will always be available.
* @method unregisterLoader
* @param {Class} loader The AbstractLoader class to remove
*/
p.unregisterLoader = function (loader) {
var idx = this._availableLoaders.indexOf(loader);
if (idx != -1 && idx < this._defaultLoaderLength - 1) {
this._availableLoaders.splice(idx, 1);
}
};
/**
* @method setUseXHR
* @param {Boolean} value The new useXHR value to set.
* @return {Boolean} The new useXHR value. If XHR is not supported by the browser, this will return false, even if
* the provided value argument was true.
* @since 0.3.0
* @deprecated use the {{#crossLink "preferXHR:property"}}{{/crossLink}} property, or the {{#crossLink "setUseXHR"}}{{/crossLink}}
* method instead.
*/
p.setUseXHR = function (value) {
return this.setPreferXHR(value);
};
/**
* Change the {{#crossLink "preferXHR:property"}}{{/crossLink}} value. Note that if this is set to `true`, it may
* fail, or be ignored depending on the browser's capabilities and the load type.
* @method setPreferXHR
* @param {Boolean} value
* @returns {Boolean} The value of {{#crossLink "preferXHR"}}{{/crossLink}} that was successfully set.
* @since 0.6.0
*/
p.setPreferXHR = function(value) {
// Determine if we can use XHR. XHR defaults to TRUE, but the browser may not support it.
//TODO: Should we be checking for the other XHR types? Might have to do a try/catch on the different types similar to createXHR.
this.preferXHR = (value != false && window.XMLHttpRequest != null);
return this.preferXHR;
};
/**
* Stops all queued and loading items, and clears the queue. This also removes all internal references to loaded
* content, and allows the queue to be used again.
* @method removeAll
* @since 0.3.0
*/
p.removeAll = function () {
this.remove();
};
/**
* Stops an item from being loaded, and removes it from the queue. If nothing is passed, all items are removed.
* This also removes internal references to loaded item(s).
*
* <h4>Example</h4>
*
* queue.loadManifest([
* {src:"test.png", id:"png"},
* {src:"test.jpg", id:"jpg"},
* {src:"test.mp3", id:"mp3"}
* ]);
* queue.remove("png"); // Single item by ID
* queue.remove("png", "test.jpg"); // Items as arguments. Mixed id and src.
* queue.remove(["test.png", "jpg"]); // Items in an Array. Mixed id and src.
*
* @method remove
* @param {String | Array} idsOrUrls* The id or ids to remove from this queue. You can pass an item, an array of
* items, or multiple items as arguments.
* @since 0.3.0
*/
p.remove = function (idsOrUrls) {
var args = null;
if (idsOrUrls && !(idsOrUrls instanceof Array)) {
args = [idsOrUrls];
} else if (idsOrUrls) {
args = idsOrUrls;
} else if (arguments.length > 0) {
return;
}
var itemsWereRemoved = false;
// Destroy everything
if (!args) {
this.close();
for (var n in this._loadItemsById) {
this._disposeItem(this._loadItemsById[n]);
}
this.init(this.preferXHR, this._basePath);
// Remove specific items
} else {
while (args.length) {
var item = args.pop();
var r = this.getResult(item);
//Remove from the main load Queue
for (i = this._loadQueue.length - 1; i >= 0; i--) {
loadItem = this._loadQueue[i].getItem();
if (loadItem.id == item || loadItem.src == item) {
this._loadQueue.splice(i, 1)[0].cancel();
break;
}
}
//Remove from the backup queue
for (i = this._loadQueueBackup.length - 1; i >= 0; i--) {
loadItem = this._loadQueueBackup[i].getItem();
if (loadItem.id == item || loadItem.src == item) {
this._loadQueueBackup.splice(i, 1)[0].cancel();
break;
}
}
if (r) {
this._disposeItem(this.getItem(item));
} else {
for (var i = this._currentLoads.length - 1; i >= 0; i--) {
var loadItem = this._currentLoads[i].getItem();
if (loadItem.id == item || loadItem.src == item) {
this._currentLoads.splice(i, 1)[0].cancel();
itemsWereRemoved = true;
break;
}
}
}
}
// If this was called during a load, try to load the next item.
if (itemsWereRemoved) {
this._loadNext();
}
}
};
/**
* Stops all open loads, destroys any loaded items, and resets the queue, so all items can
* be reloaded again by calling {{#crossLink "AbstractLoader/load"}}{{/crossLink}}. Items are not removed from the
* queue. To remove items use the {{#crossLink "LoadQueue/remove"}}{{/crossLink}} or
* {{#crossLink "LoadQueue/removeAll"}}{{/crossLink}} method.
* @method reset
* @since 0.3.0
*/
p.reset = function () {
this.close();
for (var n in this._loadItemsById) {
this._disposeItem(this._loadItemsById[n]);
}
//Reset the queue to its start state
var a = [];
for (var i = 0, l = this._loadQueueBackup.length; i < l; i++) {
a.push(this._loadQueueBackup[i].getItem());
}
this.loadManifest(a, false);
};
/**
* Register a plugin. Plugins can map to load types (sound, image, etc), or specific extensions (png, mp3, etc).
* Currently, only one plugin can exist per type/extension.
*
* When a plugin is installed, a <code>getPreloadHandlers()</code> method will be called on it. For more information
* on this method, check out the {{#crossLink "SamplePlugin/getPreloadHandlers"}}{{/crossLink}} method in the
* {{#crossLink "SamplePlugin"}}{{/crossLink}} class.
*
* Before a file is loaded, a matching plugin has an opportunity to modify the load. If a `callback` is returned
* from the {{#crossLink "SamplePlugin/getPreloadHandlers"}}{{/crossLink}} method, it will be invoked first, and its
* result may cancel or modify the item. The callback method can also return a `completeHandler` to be fired when
* the file is loaded, or a `tag` object, which will manage the actual download. For more information on these
* methods, check out the {{#crossLink "SamplePlugin/preloadHandler"}}{{/crossLink}} and {{#crossLink "SamplePlugin/fileLoadHandler"}}{{/crossLink}}
* methods on the {{#crossLink "SamplePlugin"}}{{/crossLink}}.
*
* @method installPlugin
* @param {Function} plugin The plugin class to install.
*/
p.installPlugin = function (plugin) {
if (plugin == null) { return; }
if (plugin.getPreloadHandlers != null) {
var map = plugin.getPreloadHandlers();
map.scope = plugin;
if (map.types != null) {
for (var i = 0, l = map.types.length; i < l; i++) {
this._typeCallbacks[map.types[i]] = map;
}
}
if (map.extensions != null) {
for (i = 0, l = map.extensions.length; i < l; i++) {
this._extensionCallbacks[map.extensions[i]] = map;
}
}
}
};
/**
* Set the maximum number of concurrent connections. Note that browsers and servers may have a built-in maximum
* number of open connections, so any additional connections may remain in a pending state until the browser
* opens the connection. When loading scripts using tags, and when {{#crossLink "LoadQueue/maintainScriptOrder:property"}}{{/crossLink}}
* is `true`, only one script is loaded at a time due to browser limitations.
*
* <h4>Example</h4>
*
* var queue = new createjs.LoadQueue();
* queue.setMaxConnections(10); // Allow 10 concurrent loads
*
* @method setMaxConnections
* @param {Number} value The number of concurrent loads to allow. By default, only a single connection per LoadQueue
* is open at any time.
*/
p.setMaxConnections = function (value) {
this._maxConnections = value;
if (!this._paused && this._loadQueue.length > 0) {
this._loadNext();
}
};
/**
* Load a single file. To add multiple files at once, use the {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}}
* method.
*
* Files are always appended to the current queue, so this method can be used multiple times to add files.
* To clear the queue first, use the {{#crossLink "AbstractLoader/close"}}{{/crossLink}} method.
* @method loadFile
* @param {LoadItem|Object|String} file The file object or path to load. A file can be either
* <ul>
* <li>A {{#crossLink "LoadItem"}}{{/crossLink}} instance</li>
* <li>An object containing properties defined by {{#crossLink "LoadItem"}}{{/crossLink}}</li>
* <li>OR A string path to a resource. Note that this kind of load item will be converted to a {{#crossLink "LoadItem"}}{{/crossLink}}
* in the background.</li>
* </ul>
* @param {Boolean} [loadNow=true] Kick off an immediate load (true) or wait for a load call (false). The default
* value is true. If the queue is paused using {{#crossLink "LoadQueue/setPaused"}}{{/crossLink}}, and the value is
* `true`, the queue will resume automatically.
* @param {String} [basePath] A base path that will be prepended to each file. The basePath argument overrides the
* path specified in the constructor. Note that if you load a manifest using a file of type {{#crossLink "AbstractLoader/MANIFEST:property"}}{{/crossLink}},
* its files will <strong>NOT</strong> use the basePath parameter. <strong>The basePath parameter is deprecated.</strong>
* This parameter will be removed in a future version. Please either use the `basePath` parameter in the LoadQueue
* constructor, or a `path` property in a manifest definition.
*/
p.loadFile = function (file, loadNow, basePath) {
if (file == null) {
var event = new createjs.ErrorEvent("PRELOAD_NO_FILE");
this._sendError(event);
return;
}
this._addItem(file, null, basePath);
if (loadNow !== false) {
this.setPaused(false);
} else {
this.setPaused(true);
}
};
/**
* Load an array of files. To load a single file, use the {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} method.
* The files in the manifest are requested in the same order, but may complete in a different order if the max
* connections are set above 1 using {{#crossLink "LoadQueue/setMaxConnections"}}{{/crossLink}}. Scripts will load
* in the right order as long as {{#crossLink "LoadQueue/maintainScriptOrder"}}{{/crossLink}} is true (which is
* default).
*
* Files are always appended to the current queue, so this method can be used multiple times to add files.
* To clear the queue first, use the {{#crossLink "AbstractLoader/close"}}{{/crossLink}} method.
* @method loadManifest
* @param {Array|String|Object} manifest An list of files to load. The loadManifest call supports four types of
* manifests:
* <ol>
* <li>A string path, which points to a manifest file, which is a JSON file that contains a "manifest" property,
* which defines the list of files to load, and can optionally contain a "path" property, which will be
* prepended to each file in the list.</li>
* <li>An object which defines a "src", which is a JSON or JSONP file. A "callback" can be defined for JSONP
* file. The JSON/JSONP file should contain a "manifest" property, which defines the list of files to load,
* and can optionally contain a "path" property, which will be prepended to each file in the list.</li>
* <li>An object which contains a "manifest" property, which defines the list of files to load, and can
* optionally contain a "path" property, which will be prepended to each file in the list.</li>
* <li>An Array of files to load.</li>
* </ol>
*
* Each "file" in a manifest can be either:
* <ul>
* <li>A {{#crossLink "LoadItem"}}{{/crossLink}} instance</li>
* <li>An object containing properties defined by {{#crossLink "LoadItem"}}{{/crossLink}}</li>
* <li>OR A string path to a resource. Note that this kind of load item will be converted to a {{#crossLink "LoadItem"}}{{/crossLink}}
* in the background.</li>
* </ul>
*
* @param {Boolean} [loadNow=true] Kick off an immediate load (true) or wait for a load call (false). The default
* value is true. If the queue is paused using {{#crossLink "LoadQueue/setPaused"}}{{/crossLink}} and this value is
* `true`, the queue will resume automatically.
* @param {String} [basePath] A base path that will be prepended to each file. The basePath argument overrides the
* path specified in the constructor. Note that if you load a manifest using a file of type {{#crossLink "LoadQueue/MANIFEST:property"}}{{/crossLink}},
* its files will <strong>NOT</strong> use the basePath parameter. <strong>The basePath parameter is deprecated.</strong>
* This parameter will be removed in a future version. Please either use the `basePath` parameter in the LoadQueue
* constructor, or a `path` property in a manifest definition.
*/
p.loadManifest = function (manifest, loadNow, basePath) {
var fileList = null;
var path = null;
// Array-based list of items
if (manifest instanceof Array) {
if (manifest.length == 0) {
var event = new createjs.ErrorEvent("PRELOAD_MANIFEST_EMPTY");
this._sendError(event);
return;
}
fileList = manifest;
// String-based. Only file manifests can be specified this way. Any other types will cause an error when loaded.
} else if (typeof(manifest) === "string") {
fileList = [
{
src: manifest,
type: s.MANIFEST
}
];
} else if (typeof(manifest) == "object") {
// An object that defines a manifest path
if (manifest.src !== undefined) {
if (manifest.type == null) {
manifest.type = s.MANIFEST;
} else if (manifest.type != s.MANIFEST) {
var event = new createjs.ErrorEvent("PRELOAD_MANIFEST_TYPE");
this._sendError(event);
}
fileList = [manifest];
// An object that defines a manifest
} else if (manifest.manifest !== undefined) {
fileList = manifest.manifest;
path = manifest.path;
}
// Unsupported. This will throw an error.
} else {
var event = new createjs.ErrorEvent("PRELOAD_MANIFEST_NULL");
this._sendError(event);
return;
}
for (var i = 0, l = fileList.length; i < l; i++) {
this._addItem(fileList[i], path, basePath);
}
if (loadNow !== false) {
this.setPaused(false);
} else {
this.setPaused(true);
}
};
/**
* Start a LoadQueue that was created, but not automatically started.
* @method load
*/
p.load = function () {
this.setPaused(false);
};
/**
* Look up a {{#crossLink "LoadItem"}}{{/crossLink}} using either the "id" or "src" that was specified when loading it. Note that if no "id" was
* supplied with the load item, the ID will be the "src", including a `path` property defined by a manifest. The
* `basePath` will not be part of the ID.
* @method getItem
* @param {String} value The <code>id</code> or <code>src</code> of the load item.
* @return {Object} The load item that was initially requested using {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}}
* or {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}}. This object is also returned via the {{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}}
* event as the `item` parameter.
*/
p.getItem = function (value) {
return this._loadItemsById[value] || this._loadItemsBySrc[value];
};
/**
* Look up a loaded result using either the "id" or "src" that was specified when loading it. Note that if no "id"
* was supplied with the load item, the ID will be the "src", including a `path` property defined by a manifest. The
* `basePath` will not be part of the ID.
* @method getResult
* @param {String} value The <code>id</code> or <code>src</code> of the load item.
* @param {Boolean} [rawResult=false] Return a raw result instead of a formatted result. This applies to content
* loaded via XHR such as scripts, XML, CSS, and Images. If there is no raw result, the formatted result will be
* returned instead.
* @return {Object} A result object containing the content that was loaded, such as:
* <ul>
* <li>An image tag (<image />) for images</li>
* <li>A script tag for JavaScript (<script />). Note that scripts are automatically added to the HTML
* DOM.</li>
* <li>A style tag for CSS (<style /> or <link >)</li>
* <li>Raw text for TEXT</li>
* <li>A formatted JavaScript object defined by JSON</li>
* <li>An XML document</li>
* <li>A binary arraybuffer loaded by XHR</li>
* <li>An audio tag (<audio >) for HTML audio. Note that it is recommended to use SoundJS APIs to play
* loaded audio. Specifically, audio loaded by Flash and WebAudio will return a loader object using this method
* which can not be used to play audio back.</li>
* </ul>
* This object is also returned via the {{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}} event as the 'item`
* parameter. Note that if a raw result is requested, but not found, the result will be returned instead.
*/
p.getResult = function (value, rawResult) {
var item = this._loadItemsById[value] || this._loadItemsBySrc[value];
if (item == null) { return null; }
var id = item.id;
if (rawResult && this._loadedRawResults[id]) {
return this._loadedRawResults[id];
}
return this._loadedResults[id];
};
/**
* Generate an list of items loaded by this queue.
* @method getItems
* @param {Boolean} loaded Determines if only items that have been loaded should be returned. If false, in-progress
* and failed load items will also be included.
* @returns {Array} A list of objects that have been loaded. Each item includes the {{#crossLink "LoadItem"}}{{/crossLink}},
* result, and rawResult.
* @since 0.6.0
*/
p.getItems = function(loaded) {
var arr = [];
for (var i= 0, l=this._loadQueueBackup.length; i<l; i++) {
var loader = this._loadQueueBackup[i]
var item = loader.getItem();
if (loaded === true && !loader.loaded) { continue; }
arr.push({
item: item,
result: this.getResult(item.id),
rawResult: this.getResult(item.id, true)
});
}
return arr;
};
/**
* Pause or resume the current load. Active loads will not be cancelled, but the next items in the queue will not
* be processed when active loads complete. LoadQueues are not paused by default.
*
* Note that if new items are added to the queue using {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} or
* {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}}, a paused queue will be resumed, unless the `loadNow`
* argument is `false`.
* @method setPaused
* @param {Boolean} value Whether the queue should be paused or not.
*/
p.setPaused = function (value) {
this._paused = value;
if (!this._paused) {
this._loadNext();
}
};
/**
* Close the active queue. Closing a queue completely empties the queue, and prevents any remaining items from
* starting to download. Note that currently any active loads will remain open, and events may be processed.
*
* To stop and restart a queue, use the {{#crossLink "LoadQueue/setPaused"}}{{/crossLink}} method instead.
* @method close
*/
p.close = function () {
while (this._currentLoads.length) {
this._currentLoads.pop().cancel();
}
this._scriptOrder.length = 0;
this._loadedScripts.length = 0;
this.loadStartWasDispatched = false;
this._itemCount = 0;
this._lastProgress = NaN;
};
// protected methods
/**
* Add an item to the queue. Items are formatted into a usable object containing all the properties necessary to
* load the content. The load queue is populated with the loader instance that handles preloading, and not the load
* item that was passed in by the user. To look up the load item by id or src, use the {{#crossLink "LoadQueue.getItem"}}{{/crossLink}}
* method.
* @method _addItem
* @param {String|Object} value The item to add to the queue.
* @param {String} [path] An optional path prepended to the `src`. The path will only be prepended if the src is
* relative, and does not start with a protocol such as `http://`, or a path like `../`. If the LoadQueue was
* provided a {{#crossLink "_basePath"}}{{/crossLink}}, then it will optionally be prepended after.
* @param {String} [basePath] <strong>Deprecated</strong>An optional basePath passed into a {{#crossLink "LoadQueue/loadManifest"}}{{/crossLink}}
* or {{#crossLink "LoadQueue/loadFile"}}{{/crossLink}} call. This parameter will be removed in a future tagged
* version.
* @private
*/
p._addItem = function (value, path, basePath) {
var item = this._createLoadItem(value, path, basePath); // basePath and manifest path are added to the src.
if (item == null) { return; } // Sometimes plugins or types should be skipped.
var loader = this._createLoader(item);
if (loader != null) {
item._loader = loader;
this._loadQueue.push(loader);
this._loadQueueBackup.push(loader);
this._numItems++;
this._updateProgress();
// Only worry about script order when using XHR to load scripts. Tags are only loading one at a time.
if ((this.maintainScriptOrder
&& item.type == createjs.LoadQueue.JAVASCRIPT
//&& loader instanceof createjs.XHRLoader //NOTE: Have to track all JS files this way
)
|| item.maintainOrder === true) {
this._scriptOrder.push(item);
this._loadedScripts.push(null);
}
}
};
/**
* Create a refined {{#crossLink "LoadItem"}}{{/crossLink}}, which contains all the required properties. The type of
* item is determined by browser support, requirements based on the file type, and developer settings. For example,
* XHR is only used for file types that support it in new browsers.
*
* Before the item is returned, any plugins registered to handle the type or extension will be fired, which may
* alter the load item.
* @method _createLoadItem
* @param {String | Object | HTMLAudioElement | HTMLImageElement} value The item that needs to be preloaded.
* @param {String} [path] A path to prepend to the item's source. Sources beginning with http:// or similar will
* not receive a path. Since PreloadJS 0.4.1, the src will be modified to include the `path` and {{#crossLink "LoadQueue/_basePath:property"}}{{/crossLink}}
* when it is added.
* @param {String} [basePath] <strong>Deprectated</strong> A base path to prepend to the items source in addition to
* the path argument.
* @return {Object} The loader instance that will be used.
* @private
*/
p._createLoadItem = function (value, path, basePath) {
var item = createjs.LoadItem.create(value);
if (item == null) { return null; }
// Determine Extension, etc.
var match = createjs.RequestUtils.parseURI(item.src);
if (match.extension) { item.ext = match.extension; }
if (item.type == null) {
item.type = createjs.RequestUtils.getTypeByExtension(item.ext);
}
// Inject path & basePath
var bp = ""; // Store the generated basePath
var useBasePath = basePath || this._basePath;
var autoId = item.src;
if (!match.absolute && !match.relative) {
if (path) {
bp = path;
var pathMatch = createjs.RequestUtils.parseURI(path);
autoId = path + autoId;
// Also append basePath
if (useBasePath != null && !pathMatch.absolute && !pathMatch.relative) {
bp = useBasePath + bp;
}
} else if (useBasePath != null) {
bp = useBasePath;
}
}
item.src = bp + item.src;
item.path = bp;
// If there's no id, set one now.
if (item.id === undefined || item.id === null || item.id === "") {
item.id = autoId;
}
// Give plugins a chance to modify the loadItem:
var customHandler = this._typeCallbacks[item.type] || this._extensionCallbacks[item.ext];
if (customHandler) {
// Plugins are now passed both the full source, as well as a combined path+basePath (appropriately)
var result = customHandler.callback.call(customHandler.scope, item, this);
// The plugin will handle the load, or has canceled it. Ignore it.
if (result === false) {
return null;
// Load as normal:
} else if (result === true) {
// Do Nothing
// Result is a loader class:
} else if (result != null) {
item._loader = result;
}
// Update the extension in case the type changed:
match = createjs.RequestUtils.parseURI(item.src);
if (match.extension != null) {
item.ext = match.extension;
}
}
// Store the item for lookup. This also helps clean-up later.
this._loadItemsById[item.id] = item;
this._loadItemsBySrc[item.src] = item;
if (item.loadTimeout == null) {
item.loadTimeout = s.loadTimeout;
}
if (item.crossOrigin == null) {
item.crossOrigin = this._crossOrigin;
}
return item;
};
/**
* Create a loader for a load item.
* @method _createLoader
* @param {Object} item A formatted load item that can be used to generate a loader.
* @return {AbstractLoader} A loader that can be used to load content.
* @private
*/
p._createLoader = function (item) {
if (item._loader != null) { // A plugin already specified a loader
return item._loader;
}
// Initially, try and use the provided/supported XHR mode:
var preferXHR = this.preferXHR;
for (var i = 0; i < this._availableLoaders.length; i++) {
var loader = this._availableLoaders[i];
if (loader && loader.canLoadItem(item)) {
return new loader(item, preferXHR);
}
}
// TODO: Log error (requires createjs.log)
return null;
};
/**
* Load the next item in the queue. If the queue is empty (all items have been loaded), then the complete event
* is processed. The queue will "fill up" any empty slots, up to the max connection specified using
* {{#crossLink "LoadQueue.setMaxConnections"}}{{/crossLink}} method. The only exception is scripts that are loaded
* using tags, which have to be loaded one at a time to maintain load order.
* @method _loadNext
* @private
*/
p._loadNext = function () {
if (this._paused) { return; }
// Only dispatch loadstart event when the first file is loaded.
if (!this._loadStartWasDispatched) {
this._sendLoadStart();
this._loadStartWasDispatched = true;
}
// The queue has completed.
if (this._numItems == this._numItemsLoaded) {
this.loaded = true;
this._sendComplete();
// Load the next queue, if it has been defined.
if (this.next && this.next.load) {
this.next.load();
}
} else {
this.loaded = false;
}
// Must iterate forwards to load in the right order.
for (var i = 0; i < this._loadQueue.length; i++) {
if (this._currentLoads.length >= this._maxConnections) { break; }
var loader = this._loadQueue[i];
// Determine if we should be only loading one tag-script at a time:
// Note: maintainOrder items don't do anything here because we can hold onto their loaded value
if (!this._canStartLoad(loader)) { continue; }
this._loadQueue.splice(i, 1);
i--;
this._loadItem(loader);
}
};
/**
* Begin loading an item. Event listeners are not added to the loaders until the load starts.
* @method _loadItem
* @param {AbstractLoader} loader The loader instance to start. Currently, this will be an XHRLoader or TagLoader.
* @private
*/
p._loadItem = function (loader) {
loader.on("fileload", this._handleFileLoad, this);
loader.on("progress", this._handleProgress, this);
loader.on("complete", this._handleFileComplete, this);
loader.on("error", this._handleError, this);
loader.on("fileerror", this._handleFileError, this);
this._currentLoads.push(loader);
this._sendFileStart(loader.getItem());
loader.load();
};
/**
* The callback that is fired when a loader loads a file. This enables loaders like {{#crossLink "ManifestLoader"}}{{/crossLink}}
* to maintain internal queues, but for this queue to dispatch the {{#crossLink "fileload:event"}}{{/crossLink}}
* events.
* @param {Event} The {{#crossLink "AbstractLoader/fileload:event"}}{{/crossLink}} event from the loader.
* @private
* @since 0.6.0
*/
p._handleFileLoad = function(event) {
event.target = null;
this.dispatchEvent(event);
};
/**
* The callback that is fired when a loader encounters an error from an internal file load operation. This enables
* loaders like M
* @param event
* @private
*/
p._handleFileError = function(event) {
var newEvent = new createjs.ErrorEvent("FILE_LOAD_ERROR", null, event.item);
this._sendError(newEvent);
};
/**
* The callback that is fired when a loader encounters an error. The queue will continue loading unless {{#crossLink "LoadQueue/stopOnError:property"}}{{/crossLink}}
* is set to `true`.
* @method _handleError
* @param {ErrorEvent} event The error event, containing relevant error information.
* @private
*/
p._handleError = function (event) {
var loader = event.target;
this._numItemsLoaded++;
this._finishOrderedItem(loader, true);
this._updateProgress();
var newEvent = new createjs.ErrorEvent("FILE_LOAD_ERROR", null, loader.getItem());
// TODO: Propagate actual error message.
this._sendError(newEvent);
if (!this.stopOnError) {
this._removeLoadItem(loader);
this._loadNext();
}
};
/**
* An item has finished loading. We can assume that it is totally loaded, has been parsed for immediate use, and
* is available as the "result" property on the load item. The raw text result for a parsed item (such as JSON, XML,
* CSS, JavaScript, etc) is available as the "rawResult" property, and can also be looked up using {{#crossLink "LoadQueue/getResult"}}{{/crossLink}}.
* @method _handleFileComplete
* @param {Event} event The event object from the loader.
* @private
*/
p._handleFileComplete = function (event) {
var loader = event.target;
var item = loader.getItem();
var result = loader.getResult();
this._loadedResults[item.id] = result;
var rawResult = loader.getResult(true);
if (rawResult != null && rawResult !== result) {
this._loadedRawResults[item.id] = rawResult;
}
this._saveLoadedItems(loader);
// Clean up the load item
this._removeLoadItem(loader);
if (!this._finishOrderedItem(loader)) {
// The item was NOT managed, so process it now
this._processFinishedLoad(item, loader);
}
};
/**
* Some loaders might load additional content, other than the item they were passed (such as {{#crossLink "ManifestLoader"}}{{/crossLink}}).
* Any items exposed by the loader using {{#crossLink "AbstractLoader/getLoadItems"}}{{/crossLink}} are added to the
* LoadQueue's look-ups, including {{#crossLink "getItem"}}{{/crossLink}} and {{#crossLink "getResult"}}{{/crossLink}}
* methods.
* @method _saveLoadedItems
* @param {AbstractLoader} loader
* @protected
* @since 0.6.0
*/
p._saveLoadedItems = function(loader) {
// TODO: Not sure how to handle this. Would be nice to expose the items.
// Loaders may load sub-items. This adds them to this queue
var list = loader.getLoadedItems();
if (list === null) { return; }
for (var i = 0; i < list.length; i++) {
var item = list[i].item;
// Store item lookups
this._loadItemsBySrc[item.src] = item;
this._loadItemsById[item.id] = item;
// Store loaded content
this._loadedResults[item.id] = list[i].result;
this._loadedRawResults[item.id] = list[i].rawResult;
}
}
/**
* Flag an item as finished. If the item's order is being managed, then ensure that it is allowed to finish, and if
* so, trigger prior items to trigger as well.
* @method _finishOrderedItem
* @param {AbstractLoader} loader
* @return {Boolean} If the item's order is being managed. This allows the caller to take an alternate
* behaviour if it is.
* @private
*/
p._finishOrderedItem = function (loader, loadFailed) {
var item = loader.getItem();
if ((this.maintainScriptOrder && item.type == createjs.LoadQueue.JAVASCRIPT)
|| item.maintainOrder) {
//TODO: Evaluate removal of the _currentlyLoadingScript
if (loader instanceof createjs.JavaScriptLoader) {
this._currentlyLoadingScript = false;
}
var index = createjs.indexOf(this._scriptOrder, item);
if (index == -1) { return false; } // This loader no longer exists
this._loadedScripts[index] = (loadFailed === true) ? true : item;
this._checkScriptLoadOrder();
return true;
}
return false;
};
/**
* Ensure the scripts load and dispatch in the correct order. When using XHR, scripts are stored in an array in the
* order they were added, but with a "null" value. When they are completed, the value is set to the load item,
* and then when they are processed and dispatched, the value is set to `true`. This method simply
* iterates the array, and ensures that any loaded items that are not preceded by a `null` value are
* dispatched.
* @method _checkScriptLoadOrder
* @private
*/
p._checkScriptLoadOrder = function () {
var l = this._loadedScripts.length;
for (var i = 0; i < l; i++) {
var item = this._loadedScripts[i];
if (item === null) { break; } // This is still loading. Do not process further.
if (item === true) { continue; } // This has completed, and been processed. Move on.
var loadItem = this._loadedResults[item.id];
if (item.type == createjs.LoadQueue.JAVASCRIPT) {
// Append script tags to the head automatically. Tags do this in the loader, but XHR scripts have to maintain order.
(document.body || document.getElementsByTagName("body")[0]).appendChild(loadItem);
}
var loader = item._loader;
this._processFinishedLoad(item, loader);
this._loadedScripts[i] = true;
}
};
/**
* A file has completed loading, and the LoadQueue can move on. This triggers the complete event, and kick-starts
* the next item.
* @method _processFinishedLoad
* @param {LoadItem|Object} item
* @param {AbstractLoader} loader
* @protected
*/
p._processFinishedLoad = function (item, loader) {
this._numItemsLoaded++;
this._updateProgress();
this._sendFileComplete(item, loader);
this._loadNext();
};
/**
* Ensure items with `maintainOrder=true` that are before the specified item have loaded. This only applies to
* JavaScript items that are being loaded with a TagLoader, since they have to be loaded and completed <strong>before</strong>
* the script can even be started, since it exist in the DOM while loading.
* @method _canStartLoad
* @param {AbstractLoader} loader The loader for the item
* @return {Boolean} Whether the item can start a load or not.
* @private
*/
p._canStartLoad = function (loader) {
if (!this.maintainScriptOrder || loader.preferXHR) { return true; }
var item = loader.getItem();
if (item.type != createjs.LoadQueue.JAVASCRIPT) { return true; }
if (this._currentlyLoadingScript) { return false; }
var index = this._scriptOrder.indexOf(item);
var i = 0;
while (i < index) {
var checkItem = this._loadedScripts[i];
if (checkItem == null) { return false; }
i++;
}
this._currentlyLoadingScript = true;
return true;
};
/**
* A load item is completed or was canceled, and needs to be removed from the LoadQueue.
* @method _removeLoadItem
* @param {AbstractLoader} loader A loader instance to remove.
* @private
*/
p._removeLoadItem = function (loader) {
var item = loader.getItem();
delete item._loader;
var l = this._currentLoads.length;
for (var i = 0; i < l; i++) {
if (this._currentLoads[i] == loader) {
this._currentLoads.splice(i, 1);
break;
}
}
};
/**
* An item has dispatched progress. Propagate that progress, and update the LoadQueue's overall progress.
* @method _handleProgress
* @param {ProgressEvent} event The progress event from the item.
* @private
*/
p._handleProgress = function (event) {
var loader = event.target;
this._sendFileProgress(loader.getItem(), loader.progress);
this._updateProgress();
};
/**
* Overall progress has changed, so determine the new progress amount and dispatch it. This changes any time an
* item dispatches progress or completes. Note that since we don't always know the actual filesize of items before
* they are loaded. In this case, we define a "slot" for each item (1 item in 10 would get 10%), and then append
* loaded progress on top of the already-loaded items.
*
* For example, if 5/10 items have loaded, and item 6 is 20% loaded, the total progress would be:
* <ul>
* <li>5/10 of the items in the queue (50%)</li>
* <li>plus 20% of item 6's slot (2%)</li>
* <li>equals 52%</li>
* </ul>
* @method _updateProgress
* @private
*/
p._updateProgress = function () {
var loaded = this._numItemsLoaded / this._numItems; // Fully Loaded Progress
var remaining = this._numItems - this._numItemsLoaded;
if (remaining > 0) {
var chunk = 0;
for (var i = 0, l = this._currentLoads.length; i < l; i++) {
chunk += this._currentLoads[i].progress;
}
loaded += (chunk / remaining) * (remaining / this._numItems);
}
if (this._lastProgress != loaded) {
this._sendProgress(loaded);
this._lastProgress = loaded;
}
};
/**
* Clean out item results, to free them from memory. Mainly, the loaded item and results are cleared from internal
* hashes.
* @method _disposeItem
* @param {LoadItem|Object} item The item that was passed in for preloading.
* @private
*/
p._disposeItem = function (item) {
delete this._loadedResults[item.id];
delete this._loadedRawResults[item.id];
delete this._loadItemsById[item.id];
delete this._loadItemsBySrc[item.src];
};
/**
* Dispatch a "fileprogress" {{#crossLink "Event"}}{{/crossLink}}. Please see the LoadQueue {{#crossLink "LoadQueue/fileprogress:event"}}{{/crossLink}}
* event for details on the event payload.
* @method _sendFileProgress
* @param {LoadItem|Object} item The item that is being loaded.
* @param {Number} progress The amount the item has been loaded (between 0 and 1).
* @protected
*/
p._sendFileProgress = function (item, progress) {
if (this._isCanceled()) {
this._cleanUp();
return;
}
if (!this.hasEventListener("fileprogress")) { return; }
//LM: Rework ProgressEvent to support this?
var event = new createjs.Event("fileprogress");
event.progress = progress;
event.loaded = progress;
event.total = 1;
event.item = item;
this.dispatchEvent(event);
};
/**
* Dispatch a fileload {{#crossLink "Event"}}{{/crossLink}}. Please see the {{#crossLink "LoadQueue/fileload:event"}}{{/crossLink}} event for
* details on the event payload.
* @method _sendFileComplete
* @param {LoadItemObject} item The item that is being loaded.
* @param {AbstractLoader} loader
* @protected
*/
p._sendFileComplete = function (item, loader) {
if (this._isCanceled()) { return; }
var event = new createjs.Event("fileload");
event.loader = loader;
event.item = item;
event.result = this._loadedResults[item.id];
event.rawResult = this._loadedRawResults[item.id];
// This calls a handler specified on the actual load item. Currently, the SoundJS plugin uses this.
if (item.completeHandler) {
item.completeHandler(event);
}
this.hasEventListener("fileload") && this.dispatchEvent(event);
};
/**
* Dispatch a filestart {{#crossLink "Event"}}{{/crossLink}} immediately before a file starts to load. Please see
* the {{#crossLink "LoadQueue/filestart:event"}}{{/crossLink}} event for details on the event payload.
* @method _sendFileStart
* @param {LoadItem|Object} item The item that is being loaded.
* @protected
*/
p._sendFileStart = function (item) {
var event = new createjs.Event("filestart");
event.item = item;
this.hasEventListener("filestart") && this.dispatchEvent(event);
};
p.toString = function () {
return "[PreloadJS LoadQueue]";
};
createjs.LoadQueue = createjs.promote(LoadQueue, "AbstractLoader");
}());
//##############################################################################
// TextLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for Text files.
* @class TextLoader
* @param {LoadItem|Object} loadItem
* @constructor
*/
function TextLoader(loadItem) {
this.AbstractLoader_constructor(loadItem, true, createjs.AbstractLoader.TEXT);
};
var p = createjs.extend(TextLoader, createjs.AbstractLoader);
var s = TextLoader;
// static methods
/**
* Determines if the loader can load a specific item. This loader loads items that are of type {{#crossLink "AbstractLoader/TEXT:property"}}{{/crossLink}},
* but is also the default loader if a file type can not be determined.
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.TEXT;
};
createjs.TextLoader = createjs.promote(TextLoader, "AbstractLoader");
}());
//##############################################################################
// BinaryLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for binary files. This is useful for loading web audio, or content that requires an ArrayBuffer.
* @class BinaryLoader
* @param {LoadItem|Object} loadItem
* @constructor
*/
function BinaryLoader(loadItem) {
this.AbstractLoader_constructor(loadItem, true, createjs.AbstractLoader.BINARY);
this.on("initialize", this._updateXHR, this);
};
var p = createjs.extend(BinaryLoader, createjs.AbstractLoader);
var s = BinaryLoader;
// static methods
/**
* Determines if the loader can load a specific item. This loader can only load items that are of type
* {{#crossLink "AbstractLoader/BINARY:property"}}{{/crossLink}}
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.BINARY;
};
// private methods
/**
* Before the item loads, set the response type to "arraybuffer"
* @property _updateXHR
* @param {Event} event
* @private
*/
p._updateXHR = function (event) {
event.loader.setResponseType("arraybuffer");
};
createjs.BinaryLoader = createjs.promote(BinaryLoader, "AbstractLoader");
}());
//##############################################################################
// CSSLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for CSS files.
* @class CSSLoader
* @param {LoadItem|Object} loadItem
* @param {Boolean} preferXHR
* @constructor
*/
function CSSLoader(loadItem, preferXHR) {
this.AbstractLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.CSS);
// public properties
this.resultFormatter = this._formatResult;
// protected properties
this._tagSrcAttribute = "href";
if (preferXHR) {
this._tag = document.createElement("style");
} else {
this._tag = document.createElement("link");
}
this._tag.rel = "stylesheet";
this._tag.type = "text/css";
};
var p = createjs.extend(CSSLoader, createjs.AbstractLoader);
var s = CSSLoader;
// static methods
/**
* Determines if the loader can load a specific item. This loader can only load items that are of type
* {{#crossLink "AbstractLoader/CSS:property"}}{{/crossLink}}.
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.CSS;
};
// protected methods
/**
* The result formatter for CSS files.
* @method _formatResult
* @param {AbstractLoader} loader
* @returns {HTMLLinkElement|HTMLStyleElement}
* @private
*/
p._formatResult = function (loader) {
if (this._preferXHR) {
var tag = loader.getTag();
var head = document.getElementsByTagName("head")[0]; //Note: This is unavoidable in IE678
head.appendChild(tag);
if (tag.styleSheet) { // IE
tag.styleSheet.cssText = loader.getResult(true);
} else {
var textNode = document.createTextNode(loader.getResult(true));
tag.appendChild(textNode);
}
} else {
tag = this._tag;
}
return tag;
};
createjs.CSSLoader = createjs.promote(CSSLoader, "AbstractLoader");
}());
//##############################################################################
// ImageLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for image files.
* @class ImageLoader
* @param {LoadItem|Object} loadItem
* @param {Boolean} preferXHR
* @constructor
*/
function ImageLoader (loadItem, preferXHR) {
this.AbstractLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.IMAGE);
// public properties
this.resultFormatter = this._formatResult;
// protected properties
this._tagSrcAttribute = "src";
// Check if the preload item is already a tag.
if (createjs.RequestUtils.isImageTag(loadItem)) {
this._tag = loadItem;
} else if (createjs.RequestUtils.isImageTag(loadItem.src)) {
this._tag = loadItem.src;
} else if (createjs.RequestUtils.isImageTag(loadItem.tag)) {
this._tag = loadItem.tag;
}
if (this._tag != null) {
this._preferXHR = false;
} else {
this._tag = document.createElement("img");
}
this.on("initialize", this._updateXHR, this);
};
var p = createjs.extend(ImageLoader, createjs.AbstractLoader);
var s = ImageLoader;
// static methods
/**
* Determines if the loader can load a specific item. This loader can only load items that are of type
* {{#crossLink "AbstractLoader/IMAGE:property"}}{{/crossLink}}.
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.IMAGE;
};
// public methods
p.load = function () {
if (this._tag.src != "" && this._tag.complete) {
this._sendComplete();
return;
}
var crossOrigin = this._item.crossOrigin;
if (crossOrigin == true) { crossOrigin = "Anonymous"; }
if (crossOrigin != null && !createjs.RequestUtils.isLocal(this._item.src)) {
this._tag.crossOrigin = crossOrigin;
}
this.AbstractLoader_load();
};
// protected methods
/**
* Before the item loads, set its mimetype and responseType.
* @property _updateXHR
* @param {Event} event
* @private
*/
p._updateXHR = function (event) {
event.loader.mimeType = 'text/plain; charset=x-user-defined-binary';
// Only exists for XHR
if (event.loader.setResponseType) {
event.loader.setResponseType("blob");
}
};
/**
* The result formatter for Image files.
* @method _formatResult
* @param {AbstractLoader} loader
* @returns {HTMLImageElement}
* @private
*/
p._formatResult = function (loader) {
var _this = this;
return function (done) {
var tag = _this._tag;
var URL = window.URL || window.webkitURL;
if (!_this._preferXHR) {
//document.body.removeChild(tag);
} else if (URL) {
var objURL = URL.createObjectURL(loader.getResult(true));
tag.src = objURL;
tag.onload = function () {
URL.revokeObjectURL(_this.src);
}
} else {
tag.src = loader.getItem().src;
}
if (tag.complete) {
done(tag);
} else {
tag.onload = function () {
done(this);
}
}
};
};
createjs.ImageLoader = createjs.promote(ImageLoader, "AbstractLoader");
}());
//##############################################################################
// JavaScriptLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for JavaScript files.
* @class JavaScriptLoader
* @param {LoadItem|Object} loadItem
* @param {Boolean} preferXHR
* @constructor
*/
function JavaScriptLoader(loadItem, preferXHR) {
this.AbstractLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.JAVASCRIPT);
// public properties
this.resultFormatter = this._formatResult;
// protected properties
this._tagSrcAttribute = "src";
this.setTag(document.createElement("script"));
};
var p = createjs.extend(JavaScriptLoader, createjs.AbstractLoader);
var s = JavaScriptLoader;
// static methods
/**
* Determines if the loader can load a specific item. This loader can only load items that are of type
* {{#crossLink "AbstractLoader/JAVASCRIPT:property"}}{{/crossLink}}
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.JAVASCRIPT;
};
// protected methods
/**
* The result formatter for JavaScript files.
* @method _formatResult
* @param {AbstractLoader} loader
* @returns {HTMLLinkElement|HTMLStyleElement}
* @private
*/
p._formatResult = function (loader) {
var tag = loader.getTag();
if (this._preferXHR) {
tag.text = loader.getResult(true);
}
return tag;
}
createjs.JavaScriptLoader = createjs.promote(JavaScriptLoader, "AbstractLoader");
}());
//##############################################################################
// JSONLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for JSON files. To load JSON cross-domain, use JSONP and the {{#crossLink "JSONPLoader"}}{{/crossLink}}
* instead. To load JSON-formatted manifests, use {{#crossLink "ManifestLoader"}}{{/crossLink}}, and to
* load EaselJS SpriteSheets, use {{#crossLink "SpriteSheetLoader"}}{{/crossLink}}.
* @class JSONLoader
* @param {LoadItem|Object} loadItem
* @constructor
*/
function JSONLoader(loadItem) {
this.AbstractLoader_constructor(loadItem, true, createjs.AbstractLoader.JSON);
// public properties
this.resultFormatter = this._formatResult;
};
var p = createjs.extend(JSONLoader, createjs.AbstractLoader);
var s = JSONLoader;
// static methods
/**
* Determines if the loader can load a specific item. This loader can only load items that are of type
* {{#crossLink "AbstractLoader/JSON:property"}}{{/crossLink}}.
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.JSON && !item._loadAsJSONP;
};
// protected methods
/**
* The result formatter for JSON files.
* @method _formatResult
* @param {AbstractLoader} loader
* @returns {HTMLLinkElement|HTMLStyleElement}
* @private
*/
p._formatResult = function (loader) {
var json = null;
try {
json = createjs.DataUtils.parseJSON(loader.getResult(true));
} catch (e) {
var event = new createjs.ErrorEvent("JSON_FORMAT", null, e);
this._sendError(event);
return e;
}
return json;
};
createjs.JSONLoader = createjs.promote(JSONLoader, "AbstractLoader");
}());
//##############################################################################
// JSONPLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for JSONP files, which are JSON-formatted text files, wrapped in a callback. To load regular JSON
* without a callback use the {{#crossLink "JSONLoader"}}{{/crossLink}} instead. To load JSON-formatted manifests,
* use {{#crossLink "ManifestLoader"}}{{/crossLink}}, and to load EaselJS SpriteSheets, use
* {{#crossLink "SpriteSheetLoader"}}{{/crossLink}}.
*
* Note that JSONP files loaded concurrently require a <em>unique</em> callback. To ensure JSONP files are loaded
* in order, either use the {{#crossLink "LoadQueue/setMaxConnections"}}{{/crossLink}} method (set to 1),
* or set {{#crossLink "LoadItem/maintainOrder:property"}}{{/crossLink}} on items with the same callback.
* @class JSONPLoader
* @param {LoadItem|Object} loadItem
* @constructor
*/
function JSONPLoader(loadItem) {
this.AbstractLoader_constructor(loadItem, false, createjs.AbstractLoader.JSONP);
this.setTag(document.createElement("script"));
this.getTag().type = "text/javascript";
};
var p = createjs.extend(JSONPLoader, createjs.AbstractLoader);
var s = JSONPLoader;
// static methods
/**
* Determines if the loader can load a specific item. This loader can only load items that are of type
* {{#crossLink "AbstractLoader/JSONP:property"}}{{/crossLink}}.
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.JSONP || item._loadAsJSONP;
};
// public methods
p.cancel = function () {
this.AbstractLoader_cancel();
this._dispose();
};
p.load = function () {
if (this._item.callback == null) {
throw new Error('callback is required for loading JSONP requests.');
}
// TODO: Look into creating our own iFrame to handle the load
// In the first attempt, FF did not get the result
// result instanceof Object did not work either
// so we would need to clone the result.
if (window[this._item.callback] != null) {
throw new Error(
"JSONP callback '" +
this._item.callback +
"' already exists on window. You need to specify a different callback or re-name the current one.");
}
window[this._item.callback] = createjs.proxy(this._handleLoad, this);
window.document.body.appendChild(this._tag);
// Load the tag
this._tag.src = this._item.src;
};
// private methods
/**
* Handle the JSONP callback, which is a public method defined on `window`.
* @method _handleLoad
* @param {Object} The formatted JSON data.
* @private
*/
p._handleLoad = function (data) {
this._result = this._rawResult = data;
this._sendComplete();
this._dispose();
};
/**
* Clean up the JSONP load. This clears out the callback and script tag that this loader creates.
* @method _dispose
* @private
*/
p._dispose = function () {
window.document.body.removeChild(this._tag);
delete window[this._item.callback];
};
createjs.JSONPLoader = createjs.promote(JSONPLoader, "AbstractLoader");
}());
//##############################################################################
// ManifestLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for JSON manifests. Items inside the manifest are loaded before the loader completes. To load manifests
* using JSONP, specify a {{#crossLink "LoadItem/callback:property"}}{{/crossLink}} as part of the
* {{#crossLink "LoadItem"}}{{/crossLink}}. Note that the {{#crossLink "JSONLoader"}}{{/crossLink}} and
* {{#crossLink "JSONPLoader"}}{{/crossLink}} are higher priority loaders, so manifests <strong>must</strong>
* set the {{#crossLink "LoadItem"}}{{/crossLink}} {{#crossLink "LoadItem/type:property"}}{{/crossLink}} property
* to {{#crossLink "AbstractLoader/MANIFEST:property"}}{{/crossLink}}.
* @class ManifestLoader
* @param {LoadItem|Object} loadItem
* @constructor
*/
function ManifestLoader(loadItem) {
this.AbstractLoader_constructor(loadItem, null, createjs.AbstractLoader.MANIFEST);
// protected properties
/**
* An internal {{#crossLink "LoadQueue"}}{{/crossLink}} that loads the contents of the manifest.
* @property _manifestQueue
* @type {LoadQueue}
* @private
*/
this._manifestQueue = null;
};
var p = createjs.extend(ManifestLoader, createjs.AbstractLoader);
var s = ManifestLoader;
// static properties
/**
* The amount of progress that the manifest itself takes up.
* @property MANIFEST_PROGRESS
* @type {number}
* @default 0.25 (25%)
* @private
* @static
*/
s.MANIFEST_PROGRESS = 0.25;
// static methods
/**
* Determines if the loader can load a specific item. This loader can only load items that are of type
* {{#crossLink "AbstractLoader/MANIFEST:property"}}{{/crossLink}}
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.MANIFEST;
};
// public methods
p.load = function () {
this.AbstractLoader_load();
};
// protected methods
p._createRequest = function() {
var callback = this._item.callback
if (callback != null) {
this._request = new createjs.JSONPLoader(this._item);
} else {
this._request = new createjs.JSONLoader(this._item);
}
};
p.handleEvent = function (event) {
switch (event.type) {
case "complete":
this._rawResult = event.target.getResult(true);
this._result = event.target.getResult();
this._sendProgress(s.MANIFEST_PROGRESS);
this._loadManifest(this._result);
return;
case "progress":
event.loaded *= s.MANIFEST_PROGRESS;
this.progress = event.loaded / event.total;
if (isNaN(this.progress) || this.progress == Infinity) { this.progress = 0; }
this._sendProgress(event);
return;
}
this.AbstractLoader_handleEvent(event);
};
p.destroy = function() {
this.AbstractLoader_destroy();
this._manifestQueue.close();
};
/**
* Create and load the manifest items once the actual manifest has been loaded.
* @method _loadManifest
* @param {Object} json
* @private
*/
p._loadManifest = function (json) {
if (json && json.manifest) {
var queue = this._manifestQueue = new createjs.LoadQueue();
queue.on("fileload", this._handleManifestFileLoad, this);
queue.on("progress", this._handleManifestProgress, this);
queue.on("complete", this._handleManifestComplete, this, true);
queue.on("error", this._handleManifestError, this, true);
queue.loadManifest(json);
} else {
this._sendComplete();
}
};
/**
* An item from the {{#crossLink "_manifestQueue:property"}}{{/crossLink}} has completed.
* @method _handleManifestFileLoad
* @param {Event} event
* @private
*/
p._handleManifestFileLoad = function (event) {
event.target = null;
this.dispatchEvent(event);
};
/**
* The manifest has completed loading. This triggers the {{#crossLink "AbstractLoader/complete:event"}}{{/crossLink}}
* {{#crossLink "Event"}}{{/crossLink}} from the ManifestLoader.
* @method _handleManifestComplete
* @param {Event} event
* @private
*/
p._handleManifestComplete = function (event) {
this._loadedItems = this._manifestQueue.getItems(true);
this._sendComplete();
};
/**
* The manifest has reported progress.
* @method _handleManifestProgress
* @param {ProgressEvent} event
* @private
*/
p._handleManifestProgress = function (event) {
this.progress = event.progress * (1 - s.MANIFEST_PROGRESS) + s.MANIFEST_PROGRESS;
this._sendProgress(this.progress);
};
/**
* The manifest has reported an error with one of the files.
* @method _handleManifestError
* @param {ErrorEvent} event
* @private
*/
p._handleManifestError = function (event) {
var newEvent = new createjs.Event("fileerror");
newEvent.item = event.data;
this.dispatchEvent(newEvent);
};
createjs.ManifestLoader = createjs.promote(ManifestLoader, "AbstractLoader");
}());
//##############################################################################
// SoundLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for HTML audio files. PreloadJS can not load WebAudio files, as a WebAudio context is required, which
* should be created by either a library playing the sound (such as <a href="http://soundjs.com">SoundJS</a>, or an
* external framework that handles audio playback. To load content that can be played by WebAudio, use the
* {{#crossLink "BinaryLoader"}}{{/crossLink}}, and handle the audio context decoding manually.
* @class SoundLoader
* @param {LoadItem|Object} loadItem
* @param {Boolean} preferXHR
* @constructor
*/
function SoundLoader(loadItem, preferXHR) {
this.AbstractMediaLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.SOUND);
// protected properties
if (createjs.RequestUtils.isAudioTag(loadItem)) {
this._tag = loadItem;
} else if (createjs.RequestUtils.isAudioTag(loadItem.src)) {
this._tag = loadItem;
} else if (createjs.RequestUtils.isAudioTag(loadItem.tag)) {
this._tag = createjs.RequestUtils.isAudioTag(loadItem) ? loadItem : loadItem.src;
}
if (this._tag != null) {
this._preferXHR = false;
}
};
var p = createjs.extend(SoundLoader, createjs.AbstractMediaLoader);
var s = SoundLoader;
// static methods
/**
* Determines if the loader can load a specific item. This loader can only load items that are of type
* {{#crossLink "AbstractLoader/SOUND:property"}}{{/crossLink}}.
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.SOUND;
};
// protected methods
p._createTag = function (src) {
var tag = document.createElement("audio");
tag.autoplay = false;
tag.preload = "none";
//LM: Firefox fails when this the preload="none" for other tags, but it needs to be "none" to ensure PreloadJS works.
tag.src = src;
return tag;
};
createjs.SoundLoader = createjs.promote(SoundLoader, "AbstractMediaLoader");
}());
//##############################################################################
// VideoLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for video files.
* @class VideoLoader
* @param {LoadItem|Object} loadItem
* @param {Boolean} preferXHR
* @constructor
*/
function VideoLoader(loadItem, preferXHR) {
this.AbstractMediaLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.VIDEO);
if (createjs.RequestUtils.isVideoTag(loadItem) || createjs.RequestUtils.isVideoTag(loadItem.src)) {
this.setTag(createjs.RequestUtils.isVideoTag(loadItem)?loadItem:loadItem.src);
// We can't use XHR for a tag that's passed in.
this._preferXHR = false;
} else {
this.setTag(this._createTag());
}
};
var p = createjs.extend(VideoLoader, createjs.AbstractMediaLoader);
var s = VideoLoader;
/**
* Create a new video tag
*
* @returns {HTMLElement}
* @private
*/
p._createTag = function () {
return document.createElement("video");
};
// static methods
/**
* Determines if the loader can load a specific item. This loader can only load items that are of type
* {{#crossLink "AbstractLoader/VIDEO:property"}}{{/crossLink}}.
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.VIDEO;
};
createjs.VideoLoader = createjs.promote(VideoLoader, "AbstractMediaLoader");
}());
//##############################################################################
// SpriteSheetLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for EaselJS SpriteSheets. Images inside the spritesheet definition are loaded before the loader
* completes. To load SpriteSheets using JSONP, specify a {{#crossLink "LoadItem/callback:property"}}{{/crossLink}}
* as part of the {{#crossLink "LoadItem"}}{{/crossLink}}. Note that the {{#crossLink "JSONLoader"}}{{/crossLink}}
* and {{#crossLink "JSONPLoader"}}{{/crossLink}} are higher priority loaders, so SpriteSheets <strong>must</strong>
* set the {{#crossLink "LoadItem"}}{{/crossLink}} {{#crossLink "LoadItem/type:property"}}{{/crossLink}} property
* to {{#crossLink "AbstractLoader/SPRITESHEET:property"}}{{/crossLink}}.
* @class SpriteSheetLoader
* @param {LoadItem|Object} loadItem
* @constructor
*/
function SpriteSheetLoader(loadItem) {
this.AbstractLoader_constructor(loadItem, null, createjs.AbstractLoader.SPRITESHEET);
// protected properties
/**
* An internal queue which loads the SpriteSheet's images.
* @method _manifestQueue
* @type {LoadQueue}
* @private
*/
this._manifestQueue = null;
}
var p = createjs.extend(SpriteSheetLoader, createjs.AbstractLoader);
var s = SpriteSheetLoader;
// static properties
/**
* The amount of progress that the manifest itself takes up.
* @property SPRITESHEET_PROGRESS
* @type {number}
* @default 0.25 (25%)
* @private
* @static
*/
s.SPRITESHEET_PROGRESS = 0.25;
// static methods
/**
* Determines if the loader can load a specific item. This loader can only load items that are of type
* {{#crossLink "AbstractLoader/SPRITESHEET:property"}}{{/crossLink}}
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.SPRITESHEET;
};
// public methods
p.destroy = function() {
this.AbstractLoader_destroy;
this._manifestQueue.close();
};
// protected methods
p._createRequest = function() {
var callback = this._item.callback
if (callback != null && callback instanceof Function) {
this._request = new createjs.JSONPLoader(this._item);
} else {
this._request = new createjs.JSONLoader(this._item);
}
};
p.handleEvent = function (event) {
switch (event.type) {
case "complete":
this._rawResult = event.target.getResult(true);
this._result = event.target.getResult();
this._sendProgress(s.SPRITESHEET_PROGRESS);
this._loadManifest(this._result);
return;
case "progress":
event.loaded *= s.SPRITESHEET_PROGRESS;
this.progress = event.loaded / event.total;
if (isNaN(this.progress) || this.progress == Infinity) { this.progress = 0; }
this._sendProgress(event);
return;
}
this.AbstractLoader_handleEvent(event);
};
/**
* Create and load the images once the SpriteSheet JSON has been loaded.
* @method _loadManifest
* @param {Object} json
* @private
*/
p._loadManifest = function (json) {
if (json && json.images) {
var queue = this._manifestQueue = new createjs.LoadQueue();
queue.on("complete", this._handleManifestComplete, this, true);
queue.on("fileload", this._handleManifestFileLoad, this);
queue.on("progress", this._handleManifestProgress, this);
queue.on("error", this._handleManifestError, this, true);
queue.loadManifest(json.images);
}
};
/**
* An item from the {{#crossLink "_manifestQueue:property"}}{{/crossLink}} has completed.
* @method _handleManifestFileLoad
* @param {Event} event
* @private
*/
p._handleManifestFileLoad = function (event) {
var image = event.result;
if (image != null) {
var images = this.getResult().images;
var pos = images.indexOf(event.item.src);
images[pos] = image;
}
};
/**
* The images have completed loading. This triggers the {{#crossLink "AbstractLoader/complete:event"}}{{/crossLink}}
* {{#crossLink "Event"}}{{/crossLink}} from the SpriteSheetLoader.
* @method _handleManifestComplete
* @param {Event} event
* @private
*/
p._handleManifestComplete = function (event) {
this._result = new createjs.SpriteSheet(this._result);
this._loadedItems = this._manifestQueue.getItems(true);
this._sendComplete();
};
/**
* The images {{#crossLink "LoadQueue"}}{{/crossLink}} has reported progress.
* @method _handleManifestProgress
* @param {ProgressEvent} event
* @private
*/
p._handleManifestProgress = function (event) {
this.progress = event.progress * (1 - s.SPRITESHEET_PROGRESS) + s.SPRITESHEET_PROGRESS;
this._sendProgress(this.progress);
};
/**
* An image has reported an error.
* @method _handleManifestError
* @param {ErrorEvent} event
* @private
*/
p._handleManifestError = function (event) {
var newEvent = new createjs.Event("fileerror");
newEvent.item = event.data;
this.dispatchEvent(newEvent);
};
createjs.SpriteSheetLoader = createjs.promote(SpriteSheetLoader, "AbstractLoader");
}());
//##############################################################################
// SVGLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for SVG files.
* @class SVGLoader
* @param {LoadItem|Object} loadItem
* @param {Boolean} preferXHR
* @constructor
*/
function SVGLoader(loadItem, preferXHR) {
this.AbstractLoader_constructor(loadItem, preferXHR, createjs.AbstractLoader.SVG);
// public properties
this.resultFormatter = this._formatResult;
// protected properties
this._tagSrcAttribute = "data";
if (preferXHR) {
this.setTag(document.createElement("svg"));
} else {
this.setTag(document.createElement("object"));
this.getTag().type = "image/svg+xml";
}
this.getTag().style.visibility = "hidden";
};
var p = createjs.extend(SVGLoader, createjs.AbstractLoader);
var s = SVGLoader;
// static methods
/**
* Determines if the loader can load a specific item. This loader can only load items that are of type
* {{#crossLink "AbstractLoader/SVG:property"}}{{/crossLink}}
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.SVG;
};
// protected methods
/**
* The result formatter for SVG files.
* @method _formatResult
* @param {AbstractLoader} loader
* @returns {Object}
* @private
*/
p._formatResult = function (loader) {
// mime should be image/svg+xml, but Opera requires text/xml
var xml = createjs.DataUtils.parseXML(loader.getResult(true), "text/xml");
var tag = loader.getTag();
if (!this._preferXHR && document.body.contains(tag)) {
document.body.removeChild(tag);
}
if (xml.documentElement != null) {
tag.appendChild(xml.documentElement);
tag.style.visibility = "visible";
return tag;
} else { // For browsers that don't support SVG, just give them the XML. (IE 9-8)
return xml;
}
}
createjs.SVGLoader = createjs.promote(SVGLoader, "AbstractLoader");
}());
//##############################################################################
// XMLLoader.js
//##############################################################################
this.createjs = this.createjs || {};
(function () {
"use strict";
// constructor
/**
* A loader for CSS files.
* @class XMLLoader
* @param {LoadItem|Object} loadItem
* @constructor
*/
function XMLLoader(loadItem) {
this.AbstractLoader_constructor(loadItem, true, createjs.AbstractLoader.XML);
// public properties
this.resultFormatter = this._formatResult;
};
var p = createjs.extend(XMLLoader, createjs.AbstractLoader);
var s = XMLLoader;
// static methods
/**
* Determines if the loader can load a specific item. This loader can only load items that are of type
* {{#crossLink "AbstractLoader/XML:property"}}{{/crossLink}}.
* @method canLoadItem
* @param {LoadItem|Object} item The LoadItem that a LoadQueue is trying to load.
* @returns {Boolean} Whether the loader can load the item.
* @static
*/
s.canLoadItem = function (item) {
return item.type == createjs.AbstractLoader.XML;
};
// protected methods
/**
* The result formatter for XML files.
* @method _formatResult
* @param {AbstractLoader} loader
* @returns {XMLDocument}
* @private
*/
p._formatResult = function (loader) {
return createjs.DataUtils.parseXML(loader.getResult(true), "text/xml");
};
createjs.XMLLoader = createjs.promote(XMLLoader, "AbstractLoader");
}());
</script>
<!-- We also provide hosted minified versions of all CreateJS libraries.
http://code.createjs.com -->
<!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> -->
<script id="script_jquery_171_min_js">
/*! jQuery v1.7.1 jquery.com | jquery.org/license */
(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function cb(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function ca(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bE.test(a)?d(a,e):ca(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)ca(a+"["+e+"]",b[e],c,d);else d(a,b)}function b_(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bT,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bP),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bC(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bx:by,g=0,h=e.length;if(d>0){if(c!=="border")for(;g<h;g++)c||(d-=parseFloat(f.css(a,"padding"+e[g]))||0),c==="margin"?d+=parseFloat(f.css(a,c+e[g]))||0:d-=parseFloat(f.css(a,"border"+e[g]+"Width"))||0;return d+"px"}d=bz(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0;if(c)for(;g<h;g++)d+=parseFloat(f.css(a,"padding"+e[g]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+e[g]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+e[g]))||0);return d+"px"}function bp(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c+(i[c][d].namespace?".":"")+i[c][d].namespace,i[c][d],i[c][d].data)}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?m(g):h==="function"&&(!a.unique||!o.has(g))&&c.push(g)},n=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,l=j||0,j=0,k=c.length;for(;c&&l<k;l++)if(c[l].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}i=!1,c&&(a.once?e===!0?o.disable():c=[]:d&&d.length&&(e=d.shift(),o.fireWith(e[0],e[1])))},o={add:function(){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){i&&f<=k&&(k--,f<=l&&l--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&o.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(i?a.once||d.push([b,c]):(!a.once||!e)&&n(b,c));return this},fire:function(){o.fireWith(this,arguments);return this},fired:function(){return!!e}};return o};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p,q=c.createElement("div"),r=c.documentElement;q.setAttribute("className","t"),q.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="<div "+n+"><div></div></div>"+"<table "+n+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="<div style='width:4px;'></div>",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h=null;if(typeof a=="undefined"){if(this.length){h=f.data(this[0]);if(this[0].nodeType===1&&!f._data(this[0],"parsedAttrs")){e=this[0].attributes;for(var i=0,j=e.length;i<j;i++)g=e[i].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),l(this[0],g,h[g]));f._data(this[0],"parsedAttrs",!0)}}return h}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split("."),d[1]=d[1]?"."+d[1]:"";if(c===b){h=this.triggerHandler("getData"+d[1]+"!",[d[0]]),h===b&&this.length&&(h=f.data(this[0],a),h=l(this[0],a,h));return h===b&&d[1]?this.data(d[0]):h}return this.each(function(){var b=f(this),e=[d[0],c];b.triggerHandler("setData"+d[1]+"!",e),f.data(this,a,c),b.triggerHandler("changeData"+d[1]+"!",e)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise()}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h<g;h++)e=d[h],e&&(c=f.propFix[e]||e,f.attr(a,e,""),a.removeAttribute(v?e:c),u.test(e)&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};
f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=[],j,k,l,m,n,o,p,q,r,s,t;g[0]=c,c.delegateTarget=this;if(e&&!c.target.disabled&&(!c.button||c.type!=="click")){m=f(this),m.context=this.ownerDocument||this;for(l=c.target;l!=this;l=l.parentNode||this){o={},q=[],m[0]=l;for(j=0;j<e;j++)r=d[j],s=r.selector,o[s]===b&&(o[s]=r.quick?H(l,r.quick):m.is(s)),o[s]&&q.push(r);q.length&&i.push({elem:l,matches:q})}}d.length>e&&i.push({elem:this,matches:d.slice(e)});for(j=0;j<i.length&&!c.isPropagationStopped();j++){p=i[j],c.currentTarget=p.elem;for(k=0;k<p.matches.length&&!c.isImmediatePropagationStopped();k++){r=p.matches[k];if(h||!c.namespace&&!r.namespace||c.namespace_re&&c.namespace_re.test(r.namespace))c.data=r.data,c.handleObj=r,n=((f.event.special[r.origType]||{}).handle||r.handler).apply(p.elem,g),n!==b&&(c.result=n,n===!1&&(c.preventDefault(),c.stopPropagation()))}}return c.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0)}),d._submit_attached=!0)})},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on.call(this,a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.type+"."+e.namespace:e.type,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.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(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.POS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function()
{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bp)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bn(k[i]);else bn(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bq=/alpha\([^)]*\)/i,br=/opacity=([^)]*)/,bs=/([A-Z]|^ms)/g,bt=/^-?\d+(?:px)?$/i,bu=/^-?\d/,bv=/^([\-+])=([\-+.\de]+)/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bv.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bC(a,b,d);f.swap(a,bw,function(){e=bC(a,b,d)});return e}},set:function(a,b){if(!bt.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cv(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cn.test(h)?(o=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),o?(f._data(this,"toggle"+i,o==="show"?"hide":"show"),j[o]()):j[h]()):(k=co.exec(h),l=j.cur(),k?(m=parseFloat(k[2]),n=k[3]||(f.cssNumber[i]?"":"px"),n!=="px"&&(f.style(this,i,(m||1)+n),l=(m||1)/j.cur()*l,f.style(this,i,l+n)),k[1]&&(m=(k[1]==="-="?-1:1)*m+l),j.custom(l,m,n)):j.custom(l,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cr||cs(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){e.options.hide&&f._data(e.elem,"fxshow"+e.prop)===b&&f._data(e.elem,"fxshow"+e.prop,e.start)},h()&&f.timers.push(h)&&!cp&&(cp=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cr||cs(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cp),cp=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(["width","height"],function(a,b){f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.support.fixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.support.fixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
</script>
<script type="text/javascript" id="editable">
var map = {};
var preload;
var loader;
var manifest;
var w = 226; // Item width
var h = 170; // Item height
function init() {
$("#loadAnotherBtn").click(loadAnother);
$("#loadAllBtn").click(loadAll);
$("#reloadBtn").click(reload);
reload();
}
// Reset everything
function reload() {
// If there is an open preload queue, close it.
if (preload != null) {
preload.close();
}
// Reset the UI
$("#reloadBtn").css("display", "none");
$(".box").remove();
$("#mainProgress .progress").width(0);
$("#loadAnotherBtn").attr("disabled", null);
$("#loadAllBtn").attr("disabled", null);
// Push each item into our manifest
manifest = [
"/imgs/mp4gifs/jtfdc_20200504__0950_stalkaround_police_sqrbak_jkwiigoin_terror.jpg",
"/imgs/mp4gifs/jtfdc_20200424_1833_stalkaroundup_longflatbed_truck.jpg",
"/imgs/mp4gifs/jtfdc_20200424_1850_stalkaroundup_speedy_bigtruckvan.jpg",
"/imgs/mp4gif/jtfdc_20200501_2012_stalkaround_jtf31_bigups_crunch.jpg",
"/imgs/mp4gifs/jtfdc_20200501_0051_stalkaroundup_owl_rumblepickup.jpg",
"/imgs/mp4gifs/jtfdc_20200423_1423_stalkaroundup_speeding_amazon_stalk.jpg",
"/fb/konet/pages/1.jpg",
"/fb/jtfdc/pages/1.jpg",
"/fb/jtfdc/pages/2.jpg",
"/fb/jtfdc/pages/3.jpg",
"/fb/jtfdc/pages/4.jpg",
"/fb/jtfdc/pages/4.jpg",
"/fb/jtfdc/pages/5.jpg",
"/fb/jtfdc/pages/6.jpg",
"/fb/jtfdc/pages/8.jpg",
"/fb/iperms/pages/1.jpg",
"/fb/konet/pages/1.jpg"
];
// "/imgs/mp4gifs/jtfdc_20200503_0810_stalkaroundacross_dogs2.jpg",
// "/imgs/mp4gifs/jtfdc_20200503_1656_stalkaoundacross_shiygrey_cpl.jpg",
// "/imgs/mp4gifs/jtfdc_20200503_1815_jtf30_doogys_allin.jpg",
// "/imgs/mp4gifs/jtfdc_20200503_1816_stalkaround_drksqrbak.jpg",
// "/imgs/mp4gifs/jtfdc_20200503_1825_stalkaroudup_shyredcpl.jpg",
// "/imgs/mp4gifs/jtfdc_20200503_1825_stalkaroundup_shinysilverguy.jpg",
// "/imgs/mp4gifs/jtfdc_20200503_1905_stalkaroudacross_ltlsilvrguy.jpg",
// "/imgs/mp4gifs/jtfdc_20200503_2011_stalaround_acrosss_ltlwhtcarguy.jpg",
// "/imgs/mp4gifs/jtfdc_20200502_1124_stalkaroundsup_fedex_gigglegirls.jpg",
// "/imgs/mp4gif/jtfdc_20200501_2012_stalkaround_jtf31_bigups_crunch.jpg",
// "/imgs/mp4gifs/jtfdc_20200501_0051_stalkaroundup_owl_rumblepickup.jpg",
// "/imgs/mp4gifs/jtfdc_20200423_1423_stalkaroundup_speeding_amazon_stalk.jpg",
// "/imgs/mp4gifs/jtfdc_20200424_1833_stalkaroundup_longflatbed_truck.jpg",
// "/imgs/mp4gifs/jtfdc_20200424_1850_stalkaroundup_speedy_bigtruckvan.jpg",
// /imgs/mp4gifs/jtfdc_20200411_1538_ks.jpg"
// Create a preloader. There is no manifest added to it up-front, we will add items on-demand.
preload = new createjs.LoadQueue(true, "../_assets/art/");
// Use this instead to use tag loading
//preload = new createjs.LoadQueue(false);
preload.on("fileload", handleFileLoad);
preload.on("progress", handleOverallProgress);
preload.on("fileprogress", handleFileProgress);
preload.on("error", handleFileError);
preload.setMaxConnections(5);
}
function stop() {
if (preload != null) {
preload.close();
}
}
function loadAll() {
while (manifest.length > 0) {
loadAnother();
}
}
function loadAnother() {
// Get the next manifest item, and load it
var item = manifest.shift();
preload.loadFile(item);
// If we have no more items, disable the UI.
if (manifest.length == 0) {
$("#loadAnotherBtn").attr("disabled", "disabled");
$("#loadAllBtn").attr("disabled", "disabled");
$("#reloadBtn").css("display", "inline");
}
// Create a new loader display item
var div = $("#template").clone();
div.attr("id", ""); // Wipe out the ID
div.addClass("box")
$("#container").append(div);
map[item] = div; // Store a reference to each item by its src
}
// File complete handler
function handleFileLoad(event) {
var div = map[event.item.id];
div.addClass("complete");
// Get a reference to the loaded image (<img/>)
var img = event.result;
// Resize it to fit inside the item
var r = img.width / img.height;
var ir = w / h
if (r > ir) {
img.width = w;
img.height = w / r;
} else {
img.height = h;
img.width = h;
}
div.append(img); // Add it to the DOM
}
// File progress handler
function handleFileProgress(event) {
var div = map[event.item.id]; // Lookup the related item
div.children("DIV").width(event.progress * div.width()); // Set the width the progress.
}
// Overall progress handler
function handleOverallProgress(event) {
$("#mainProgress > .progress").width(preload.progress * $("#mainProgress").width());
}
// An error happened on a file
function handleFileError(event) {
var div = map[event.item.id];
div.addClass("error");
}
</script>
</body>
</html>
//
koh5_pano
Drag mouse to navigate.
Navigation
- Left/Right Mouse drag: Changes camera heading.
- Up/Sown Mouse drag: Changes camera pitch.
- Scroll wheel: Changes camera field of view.
- I-Key: Displays Info panel with canvas size, image size and FPS.
17.Aug.2010, Martin Wengenmayer