Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / uglify-js / tmp / app.js
1 /* Modernizr 2.0.6 (Custom Build) | MIT & BSD
2  * Build: http://www.modernizr.com/download/#-iepp
3  */
4 ;window.Modernizr=function(a,b,c){function w(a,b){return!!~(""+a).indexOf(b)}function v(a,b){return typeof a===b}function u(a,b){return t(prefixes.join(a+";")+(b||""))}function t(a){j.cssText=a}var d="2.0.6",e={},f=b.documentElement,g=b.head||b.getElementsByTagName("head")[0],h="modernizr",i=b.createElement(h),j=i.style,k,l=Object.prototype.toString,m={},n={},o={},p=[],q,r={}.hasOwnProperty,s;!v(r,c)&&!v(r.call,c)?s=function(a,b){return r.call(a,b)}:s=function(a,b){return b in a&&v(a.constructor.prototype[b],c)};for(var x in m)s(m,x)&&(q=x.toLowerCase(),e[q]=m[x](),p.push((e[q]?"":"no-")+q));t(""),i=k=null,a.attachEvent&&function(){var a=b.createElement("div");a.innerHTML="<elem></elem>";return a.childNodes.length!==1}()&&function(a,b){function s(a){var b=-1;while(++b<g)a.createElement(f[b])}a.iepp=a.iepp||{};var d=a.iepp,e=d.html5elements||"abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",f=e.split("|"),g=f.length,h=new RegExp("(^|\\s)("+e+")","gi"),i=new RegExp("<(/*)("+e+")","gi"),j=/^\s*[\{\}]\s*$/,k=new RegExp("(^|[^\\n]*?\\s)("+e+")([^\\n]*)({[\\n\\w\\W]*?})","gi"),l=b.createDocumentFragment(),m=b.documentElement,n=m.firstChild,o=b.createElement("body"),p=b.createElement("style"),q=/print|all/,r;d.getCSS=function(a,b){if(a+""===c)return"";var e=-1,f=a.length,g,h=[];while(++e<f){g=a[e];if(g.disabled)continue;b=g.media||b,q.test(b)&&h.push(d.getCSS(g.imports,b),g.cssText),b="all"}return h.join("")},d.parseCSS=function(a){var b=[],c;while((c=k.exec(a))!=null)b.push(((j.exec(c[1])?"\n":c[1])+c[2]+c[3]).replace(h,"$1.iepp_$2")+c[4]);return b.join("\n")},d.writeHTML=function(){var a=-1;r=r||b.body;while(++a<g){var c=b.getElementsByTagName(f[a]),d=c.length,e=-1;while(++e<d)c[e].className.indexOf("iepp_")<0&&(c[e].className+=" iepp_"+f[a])}l.appendChild(r),m.appendChild(o),o.className=r.className,o.id=r.id,o.innerHTML=r.innerHTML.replace(i,"<$1font")},d._beforePrint=function(){p.styleSheet.cssText=d.parseCSS(d.getCSS(b.styleSheets,"all")),d.writeHTML()},d.restoreHTML=function(){o.innerHTML="",m.removeChild(o),m.appendChild(r)},d._afterPrint=function(){d.restoreHTML(),p.styleSheet.cssText=""},s(b),s(l);d.disablePP||(n.insertBefore(p,n.firstChild),p.media="print",p.className="iepp-printshim",a.attachEvent("onbeforeprint",d._beforePrint),a.attachEvent("onafterprint",d._afterPrint))}(a,b),e._version=d;return e}(this,this.document);
5 (function (con) {
6     // the dummy function
7     function dummy() {};
8     // console methods that may exist
9     for(var methods = "assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profileEnd,time,timeEnd,trace,warn".split(','), func; func = methods.pop();) {
10         con[func] = con[func] || dummy;
11     }
12 }(window.console = window.console || {})); 
13 // we do this crazy little dance so that the `console` object
14 // inside the function is a name that can be shortened to a single
15 // letter by the compressor to make the compressed script as tiny
16 // as possible.
17 /*!
18  * jQuery JavaScript Library v1.6.3
19  * http://jquery.com/
20  *
21  * Copyright 2011, John Resig
22  * Dual licensed under the MIT or GPL Version 2 licenses.
23  * http://jquery.org/license
24  *
25  * Includes Sizzle.js
26  * http://sizzlejs.com/
27  * Copyright 2011, The Dojo Foundation
28  * Released under the MIT, BSD, and GPL Licenses.
29  *
30  * Date: Wed Aug 31 10:35:15 2011 -0400
31  */
32 (function( window, undefined ) {
33
34 // Use the correct document accordingly with window argument (sandbox)
35 var document = window.document,
36         navigator = window.navigator,
37         location = window.location;
38 var jQuery = (function() {
39
40 // Define a local copy of jQuery
41 var jQuery = function( selector, context ) {
42                 // The jQuery object is actually just the init constructor 'enhanced'
43                 return new jQuery.fn.init( selector, context, rootjQuery );
44         },
45
46         // Map over jQuery in case of overwrite
47         _jQuery = window.jQuery,
48
49         // Map over the $ in case of overwrite
50         _$ = window.$,
51
52         // A central reference to the root jQuery(document)
53         rootjQuery,
54
55         // A simple way to check for HTML strings or ID strings
56         // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
57         quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
58
59         // Check if a string has a non-whitespace character in it
60         rnotwhite = /\S/,
61
62         // Used for trimming whitespace
63         trimLeft = /^\s+/,
64         trimRight = /\s+$/,
65
66         // Check for digits
67         rdigit = /\d/,
68
69         // Match a standalone tag
70         rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
71
72         // JSON RegExp
73         rvalidchars = /^[\],:{}\s]*$/,
74         rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
75         rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
76         rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
77
78         // Useragent RegExp
79         rwebkit = /(webkit)[ \/]([\w.]+)/,
80         ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
81         rmsie = /(msie) ([\w.]+)/,
82         rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
83
84         // Matches dashed string for camelizing
85         rdashAlpha = /-([a-z]|[0-9])/ig,
86         rmsPrefix = /^-ms-/,
87
88         // Used by jQuery.camelCase as callback to replace()
89         fcamelCase = function( all, letter ) {
90                 return ( letter + "" ).toUpperCase();
91         },
92
93         // Keep a UserAgent string for use with jQuery.browser
94         userAgent = navigator.userAgent,
95
96         // For matching the engine and version of the browser
97         browserMatch,
98
99         // The deferred used on DOM ready
100         readyList,
101
102         // The ready event handler
103         DOMContentLoaded,
104
105         // Save a reference to some core methods
106         toString = Object.prototype.toString,
107         hasOwn = Object.prototype.hasOwnProperty,
108         push = Array.prototype.push,
109         slice = Array.prototype.slice,
110         trim = String.prototype.trim,
111         indexOf = Array.prototype.indexOf,
112
113         // [[Class]] -> type pairs
114         class2type = {};
115
116 jQuery.fn = jQuery.prototype = {
117         constructor: jQuery,
118         init: function( selector, context, rootjQuery ) {
119                 var match, elem, ret, doc;
120
121                 // Handle $(""), $(null), or $(undefined)
122                 if ( !selector ) {
123                         return this;
124                 }
125
126                 // Handle $(DOMElement)
127                 if ( selector.nodeType ) {
128                         this.context = this[0] = selector;
129                         this.length = 1;
130                         return this;
131                 }
132
133                 // The body element only exists once, optimize finding it
134                 if ( selector === "body" && !context && document.body ) {
135                         this.context = document;
136                         this[0] = document.body;
137                         this.selector = selector;
138                         this.length = 1;
139                         return this;
140                 }
141
142                 // Handle HTML strings
143                 if ( typeof selector === "string" ) {
144                         // Are we dealing with HTML string or an ID?
145                         if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
146                                 // Assume that strings that start and end with <> are HTML and skip the regex check
147                                 match = [ null, selector, null ];
148
149                         } else {
150                                 match = quickExpr.exec( selector );
151                         }
152
153                         // Verify a match, and that no context was specified for #id
154                         if ( match && (match[1] || !context) ) {
155
156                                 // HANDLE: $(html) -> $(array)
157                                 if ( match[1] ) {
158                                         context = context instanceof jQuery ? context[0] : context;
159                                         doc = (context ? context.ownerDocument || context : document);
160
161                                         // If a single string is passed in and it's a single tag
162                                         // just do a createElement and skip the rest
163                                         ret = rsingleTag.exec( selector );
164
165                                         if ( ret ) {
166                                                 if ( jQuery.isPlainObject( context ) ) {
167                                                         selector = [ document.createElement( ret[1] ) ];
168                                                         jQuery.fn.attr.call( selector, context, true );
169
170                                                 } else {
171                                                         selector = [ doc.createElement( ret[1] ) ];
172                                                 }
173
174                                         } else {
175                                                 ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
176                                                 selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
177                                         }
178
179                                         return jQuery.merge( this, selector );
180
181                                 // HANDLE: $("#id")
182                                 } else {
183                                         elem = document.getElementById( match[2] );
184
185                                         // Check parentNode to catch when Blackberry 4.6 returns
186                                         // nodes that are no longer in the document #6963
187                                         if ( elem && elem.parentNode ) {
188                                                 // Handle the case where IE and Opera return items
189                                                 // by name instead of ID
190                                                 if ( elem.id !== match[2] ) {
191                                                         return rootjQuery.find( selector );
192                                                 }
193
194                                                 // Otherwise, we inject the element directly into the jQuery object
195                                                 this.length = 1;
196                                                 this[0] = elem;
197                                         }
198
199                                         this.context = document;
200                                         this.selector = selector;
201                                         return this;
202                                 }
203
204                         // HANDLE: $(expr, $(...))
205                         } else if ( !context || context.jquery ) {
206                                 return (context || rootjQuery).find( selector );
207
208                         // HANDLE: $(expr, context)
209                         // (which is just equivalent to: $(context).find(expr)
210                         } else {
211                                 return this.constructor( context ).find( selector );
212                         }
213
214                 // HANDLE: $(function)
215                 // Shortcut for document ready
216                 } else if ( jQuery.isFunction( selector ) ) {
217                         return rootjQuery.ready( selector );
218                 }
219
220                 if (selector.selector !== undefined) {
221                         this.selector = selector.selector;
222                         this.context = selector.context;
223                 }
224
225                 return jQuery.makeArray( selector, this );
226         },
227
228         // Start with an empty selector
229         selector: "",
230
231         // The current version of jQuery being used
232         jquery: "1.6.3",
233
234         // The default length of a jQuery object is 0
235         length: 0,
236
237         // The number of elements contained in the matched element set
238         size: function() {
239                 return this.length;
240         },
241
242         toArray: function() {
243                 return slice.call( this, 0 );
244         },
245
246         // Get the Nth element in the matched element set OR
247         // Get the whole matched element set as a clean array
248         get: function( num ) {
249                 return num == null ?
250
251                         // Return a 'clean' array
252                         this.toArray() :
253
254                         // Return just the object
255                         ( num < 0 ? this[ this.length + num ] : this[ num ] );
256         },
257
258         // Take an array of elements and push it onto the stack
259         // (returning the new matched element set)
260         pushStack: function( elems, name, selector ) {
261                 // Build a new jQuery matched element set
262                 var ret = this.constructor();
263
264                 if ( jQuery.isArray( elems ) ) {
265                         push.apply( ret, elems );
266
267                 } else {
268                         jQuery.merge( ret, elems );
269                 }
270
271                 // Add the old object onto the stack (as a reference)
272                 ret.prevObject = this;
273
274                 ret.context = this.context;
275
276                 if ( name === "find" ) {
277                         ret.selector = this.selector + (this.selector ? " " : "") + selector;
278                 } else if ( name ) {
279                         ret.selector = this.selector + "." + name + "(" + selector + ")";
280                 }
281
282                 // Return the newly-formed element set
283                 return ret;
284         },
285
286         // Execute a callback for every element in the matched set.
287         // (You can seed the arguments with an array of args, but this is
288         // only used internally.)
289         each: function( callback, args ) {
290                 return jQuery.each( this, callback, args );
291         },
292
293         ready: function( fn ) {
294                 // Attach the listeners
295                 jQuery.bindReady();
296
297                 // Add the callback
298                 readyList.done( fn );
299
300                 return this;
301         },
302
303         eq: function( i ) {
304                 return i === -1 ?
305                         this.slice( i ) :
306                         this.slice( i, +i + 1 );
307         },
308
309         first: function() {
310                 return this.eq( 0 );
311         },
312
313         last: function() {
314                 return this.eq( -1 );
315         },
316
317         slice: function() {
318                 return this.pushStack( slice.apply( this, arguments ),
319                         "slice", slice.call(arguments).join(",") );
320         },
321
322         map: function( callback ) {
323                 return this.pushStack( jQuery.map(this, function( elem, i ) {
324                         return callback.call( elem, i, elem );
325                 }));
326         },
327
328         end: function() {
329                 return this.prevObject || this.constructor(null);
330         },
331
332         // For internal use only.
333         // Behaves like an Array's method, not like a jQuery method.
334         push: push,
335         sort: [].sort,
336         splice: [].splice
337 };
338
339 // Give the init function the jQuery prototype for later instantiation
340 jQuery.fn.init.prototype = jQuery.fn;
341
342 jQuery.extend = jQuery.fn.extend = function() {
343         var options, name, src, copy, copyIsArray, clone,
344                 target = arguments[0] || {},
345                 i = 1,
346                 length = arguments.length,
347                 deep = false;
348
349         // Handle a deep copy situation
350         if ( typeof target === "boolean" ) {
351                 deep = target;
352                 target = arguments[1] || {};
353                 // skip the boolean and the target
354                 i = 2;
355         }
356
357         // Handle case when target is a string or something (possible in deep copy)
358         if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
359                 target = {};
360         }
361
362         // extend jQuery itself if only one argument is passed
363         if ( length === i ) {
364                 target = this;
365                 --i;
366         }
367
368         for ( ; i < length; i++ ) {
369                 // Only deal with non-null/undefined values
370                 if ( (options = arguments[ i ]) != null ) {
371                         // Extend the base object
372                         for ( name in options ) {
373                                 src = target[ name ];
374                                 copy = options[ name ];
375
376                                 // Prevent never-ending loop
377                                 if ( target === copy ) {
378                                         continue;
379                                 }
380
381                                 // Recurse if we're merging plain objects or arrays
382                                 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
383                                         if ( copyIsArray ) {
384                                                 copyIsArray = false;
385                                                 clone = src && jQuery.isArray(src) ? src : [];
386
387                                         } else {
388                                                 clone = src && jQuery.isPlainObject(src) ? src : {};
389                                         }
390
391                                         // Never move original objects, clone them
392                                         target[ name ] = jQuery.extend( deep, clone, copy );
393
394                                 // Don't bring in undefined values
395                                 } else if ( copy !== undefined ) {
396                                         target[ name ] = copy;
397                                 }
398                         }
399                 }
400         }
401
402         // Return the modified object
403         return target;
404 };
405
406 jQuery.extend({
407         noConflict: function( deep ) {
408                 if ( window.$ === jQuery ) {
409                         window.$ = _$;
410                 }
411
412                 if ( deep && window.jQuery === jQuery ) {
413                         window.jQuery = _jQuery;
414                 }
415
416                 return jQuery;
417         },
418
419         // Is the DOM ready to be used? Set to true once it occurs.
420         isReady: false,
421
422         // A counter to track how many items to wait for before
423         // the ready event fires. See #6781
424         readyWait: 1,
425
426         // Hold (or release) the ready event
427         holdReady: function( hold ) {
428                 if ( hold ) {
429                         jQuery.readyWait++;
430                 } else {
431                         jQuery.ready( true );
432                 }
433         },
434
435         // Handle when the DOM is ready
436         ready: function( wait ) {
437                 // Either a released hold or an DOMready/load event and not yet ready
438                 if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
439                         // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
440                         if ( !document.body ) {
441                                 return setTimeout( jQuery.ready, 1 );
442                         }
443
444                         // Remember that the DOM is ready
445                         jQuery.isReady = true;
446
447                         // If a normal DOM Ready event fired, decrement, and wait if need be
448                         if ( wait !== true && --jQuery.readyWait > 0 ) {
449                                 return;
450                         }
451
452                         // If there are functions bound, to execute
453                         readyList.resolveWith( document, [ jQuery ] );
454
455                         // Trigger any bound ready events
456                         if ( jQuery.fn.trigger ) {
457                                 jQuery( document ).trigger( "ready" ).unbind( "ready" );
458                         }
459                 }
460         },
461
462         bindReady: function() {
463                 if ( readyList ) {
464                         return;
465                 }
466
467                 readyList = jQuery._Deferred();
468
469                 // Catch cases where $(document).ready() is called after the
470                 // browser event has already occurred.
471                 if ( document.readyState === "complete" ) {
472                         // Handle it asynchronously to allow scripts the opportunity to delay ready
473                         return setTimeout( jQuery.ready, 1 );
474                 }
475
476                 // Mozilla, Opera and webkit nightlies currently support this event
477                 if ( document.addEventListener ) {
478                         // Use the handy event callback
479                         document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
480
481                         // A fallback to window.onload, that will always work
482                         window.addEventListener( "load", jQuery.ready, false );
483
484                 // If IE event model is used
485                 } else if ( document.attachEvent ) {
486                         // ensure firing before onload,
487                         // maybe late but safe also for iframes
488                         document.attachEvent( "onreadystatechange", DOMContentLoaded );
489
490                         // A fallback to window.onload, that will always work
491                         window.attachEvent( "onload", jQuery.ready );
492
493                         // If IE and not a frame
494                         // continually check to see if the document is ready
495                         var toplevel = false;
496
497                         try {
498                                 toplevel = window.frameElement == null;
499                         } catch(e) {}
500
501                         if ( document.documentElement.doScroll && toplevel ) {
502                                 doScrollCheck();
503                         }
504                 }
505         },
506
507         // See test/unit/core.js for details concerning isFunction.
508         // Since version 1.3, DOM methods and functions like alert
509         // aren't supported. They return false on IE (#2968).
510         isFunction: function( obj ) {
511                 return jQuery.type(obj) === "function";
512         },
513
514         isArray: Array.isArray || function( obj ) {
515                 return jQuery.type(obj) === "array";
516         },
517
518         // A crude way of determining if an object is a window
519         isWindow: function( obj ) {
520                 return obj && typeof obj === "object" && "setInterval" in obj;
521         },
522
523         isNaN: function( obj ) {
524                 return obj == null || !rdigit.test( obj ) || isNaN( obj );
525         },
526
527         type: function( obj ) {
528                 return obj == null ?
529                         String( obj ) :
530                         class2type[ toString.call(obj) ] || "object";
531         },
532
533         isPlainObject: function( obj ) {
534                 // Must be an Object.
535                 // Because of IE, we also have to check the presence of the constructor property.
536                 // Make sure that DOM nodes and window objects don't pass through, as well
537                 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
538                         return false;
539                 }
540
541                 try {
542                         // Not own constructor property must be Object
543                         if ( obj.constructor &&
544                                 !hasOwn.call(obj, "constructor") &&
545                                 !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
546                                 return false;
547                         }
548                 } catch ( e ) {
549                         // IE8,9 Will throw exceptions on certain host objects #9897
550                         return false;
551                 }
552
553                 // Own properties are enumerated firstly, so to speed up,
554                 // if last one is own, then all properties are own.
555
556                 var key;
557                 for ( key in obj ) {}
558
559                 return key === undefined || hasOwn.call( obj, key );
560         },
561
562         isEmptyObject: function( obj ) {
563                 for ( var name in obj ) {
564                         return false;
565                 }
566                 return true;
567         },
568
569         error: function( msg ) {
570                 throw msg;
571         },
572
573         parseJSON: function( data ) {
574                 if ( typeof data !== "string" || !data ) {
575                         return null;
576                 }
577
578                 // Make sure leading/trailing whitespace is removed (IE can't handle it)
579                 data = jQuery.trim( data );
580
581                 // Attempt to parse using the native JSON parser first
582                 if ( window.JSON && window.JSON.parse ) {
583                         return window.JSON.parse( data );
584                 }
585
586                 // Make sure the incoming data is actual JSON
587                 // Logic borrowed from http://json.org/json2.js
588                 if ( rvalidchars.test( data.replace( rvalidescape, "@" )
589                         .replace( rvalidtokens, "]" )
590                         .replace( rvalidbraces, "")) ) {
591
592                         return (new Function( "return " + data ))();
593
594                 }
595                 jQuery.error( "Invalid JSON: " + data );
596         },
597
598         // Cross-browser xml parsing
599         parseXML: function( data ) {
600                 var xml, tmp;
601                 try {
602                         if ( window.DOMParser ) { // Standard
603                                 tmp = new DOMParser();
604                                 xml = tmp.parseFromString( data , "text/xml" );
605                         } else { // IE
606                                 xml = new ActiveXObject( "Microsoft.XMLDOM" );
607                                 xml.async = "false";
608                                 xml.loadXML( data );
609                         }
610                 } catch( e ) {
611                         xml = undefined;
612                 }
613                 if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
614                         jQuery.error( "Invalid XML: " + data );
615                 }
616                 return xml;
617         },
618
619         noop: function() {},
620
621         // Evaluates a script in a global context
622         // Workarounds based on findings by Jim Driscoll
623         // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
624         globalEval: function( data ) {
625                 if ( data && rnotwhite.test( data ) ) {
626                         // We use execScript on Internet Explorer
627                         // We use an anonymous function so that context is window
628                         // rather than jQuery in Firefox
629                         ( window.execScript || function( data ) {
630                                 window[ "eval" ].call( window, data );
631                         } )( data );
632                 }
633         },
634
635         // Convert dashed to camelCase; used by the css and data modules
636         // Microsoft forgot to hump their vendor prefix (#9572)
637         camelCase: function( string ) {
638                 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
639         },
640
641         nodeName: function( elem, name ) {
642                 return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
643         },
644
645         // args is for internal usage only
646         each: function( object, callback, args ) {
647                 var name, i = 0,
648                         length = object.length,
649                         isObj = length === undefined || jQuery.isFunction( object );
650
651                 if ( args ) {
652                         if ( isObj ) {
653                                 for ( name in object ) {
654                                         if ( callback.apply( object[ name ], args ) === false ) {
655                                                 break;
656                                         }
657                                 }
658                         } else {
659                                 for ( ; i < length; ) {
660                                         if ( callback.apply( object[ i++ ], args ) === false ) {
661                                                 break;
662                                         }
663                                 }
664                         }
665
666                 // A special, fast, case for the most common use of each
667                 } else {
668                         if ( isObj ) {
669                                 for ( name in object ) {
670                                         if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
671                                                 break;
672                                         }
673                                 }
674                         } else {
675                                 for ( ; i < length; ) {
676                                         if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
677                                                 break;
678                                         }
679                                 }
680                         }
681                 }
682
683                 return object;
684         },
685
686         // Use native String.trim function wherever possible
687         trim: trim ?
688                 function( text ) {
689                         return text == null ?
690                                 "" :
691                                 trim.call( text );
692                 } :
693
694                 // Otherwise use our own trimming functionality
695                 function( text ) {
696                         return text == null ?
697                                 "" :
698                                 text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
699                 },
700
701         // results is for internal usage only
702         makeArray: function( array, results ) {
703                 var ret = results || [];
704
705                 if ( array != null ) {
706                         // The window, strings (and functions) also have 'length'
707                         // The extra typeof function check is to prevent crashes
708                         // in Safari 2 (See: #3039)
709                         // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
710                         var type = jQuery.type( array );
711
712                         if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
713                                 push.call( ret, array );
714                         } else {
715                                 jQuery.merge( ret, array );
716                         }
717                 }
718
719                 return ret;
720         },
721
722         inArray: function( elem, array ) {
723                 if ( !array ) {
724                         return -1;
725                 }
726
727                 if ( indexOf ) {
728                         return indexOf.call( array, elem );
729                 }
730
731                 for ( var i = 0, length = array.length; i < length; i++ ) {
732                         if ( array[ i ] === elem ) {
733                                 return i;
734                         }
735                 }
736
737                 return -1;
738         },
739
740         merge: function( first, second ) {
741                 var i = first.length,
742                         j = 0;
743
744                 if ( typeof second.length === "number" ) {
745                         for ( var l = second.length; j < l; j++ ) {
746                                 first[ i++ ] = second[ j ];
747                         }
748
749                 } else {
750                         while ( second[j] !== undefined ) {
751                                 first[ i++ ] = second[ j++ ];
752                         }
753                 }
754
755                 first.length = i;
756
757                 return first;
758         },
759
760         grep: function( elems, callback, inv ) {
761                 var ret = [], retVal;
762                 inv = !!inv;
763
764                 // Go through the array, only saving the items
765                 // that pass the validator function
766                 for ( var i = 0, length = elems.length; i < length; i++ ) {
767                         retVal = !!callback( elems[ i ], i );
768                         if ( inv !== retVal ) {
769                                 ret.push( elems[ i ] );
770                         }
771                 }
772
773                 return ret;
774         },
775
776         // arg is for internal usage only
777         map: function( elems, callback, arg ) {
778                 var value, key, ret = [],
779                         i = 0,
780                         length = elems.length,
781                         // jquery objects are treated as arrays
782                         isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
783
784                 // Go through the array, translating each of the items to their
785                 if ( isArray ) {
786                         for ( ; i < length; i++ ) {
787                                 value = callback( elems[ i ], i, arg );
788
789                                 if ( value != null ) {
790                                         ret[ ret.length ] = value;
791                                 }
792                         }
793
794                 // Go through every key on the object,
795                 } else {
796                         for ( key in elems ) {
797                                 value = callback( elems[ key ], key, arg );
798
799                                 if ( value != null ) {
800                                         ret[ ret.length ] = value;
801                                 }
802                         }
803                 }
804
805                 // Flatten any nested arrays
806                 return ret.concat.apply( [], ret );
807         },
808
809         // A global GUID counter for objects
810         guid: 1,
811
812         // Bind a function to a context, optionally partially applying any
813         // arguments.
814         proxy: function( fn, context ) {
815                 if ( typeof context === "string" ) {
816                         var tmp = fn[ context ];
817                         context = fn;
818                         fn = tmp;
819                 }
820
821                 // Quick check to determine if target is callable, in the spec
822                 // this throws a TypeError, but we will just return undefined.
823                 if ( !jQuery.isFunction( fn ) ) {
824                         return undefined;
825                 }
826
827                 // Simulated bind
828                 var args = slice.call( arguments, 2 ),
829                         proxy = function() {
830                                 return fn.apply( context, args.concat( slice.call( arguments ) ) );
831                         };
832
833                 // Set the guid of unique handler to the same of original handler, so it can be removed
834                 proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
835
836                 return proxy;
837         },
838
839         // Mutifunctional method to get and set values to a collection
840         // The value/s can optionally be executed if it's a function
841         access: function( elems, key, value, exec, fn, pass ) {
842                 var length = elems.length;
843
844                 // Setting many attributes
845                 if ( typeof key === "object" ) {
846                         for ( var k in key ) {
847                                 jQuery.access( elems, k, key[k], exec, fn, value );
848                         }
849                         return elems;
850                 }
851
852                 // Setting one attribute
853                 if ( value !== undefined ) {
854                         // Optionally, function values get executed if exec is true
855                         exec = !pass && exec && jQuery.isFunction(value);
856
857                         for ( var i = 0; i < length; i++ ) {
858                                 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
859                         }
860
861                         return elems;
862                 }
863
864                 // Getting an attribute
865                 return length ? fn( elems[0], key ) : undefined;
866         },
867
868         now: function() {
869                 return (new Date()).getTime();
870         },
871
872         // Use of jQuery.browser is frowned upon.
873         // More details: http://docs.jquery.com/Utilities/jQuery.browser
874         uaMatch: function( ua ) {
875                 ua = ua.toLowerCase();
876
877                 var match = rwebkit.exec( ua ) ||
878                         ropera.exec( ua ) ||
879                         rmsie.exec( ua ) ||
880                         ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
881                         [];
882
883                 return { browser: match[1] || "", version: match[2] || "0" };
884         },
885
886         sub: function() {
887                 function jQuerySub( selector, context ) {
888                         return new jQuerySub.fn.init( selector, context );
889                 }
890                 jQuery.extend( true, jQuerySub, this );
891                 jQuerySub.superclass = this;
892                 jQuerySub.fn = jQuerySub.prototype = this();
893                 jQuerySub.fn.constructor = jQuerySub;
894                 jQuerySub.sub = this.sub;
895                 jQuerySub.fn.init = function init( selector, context ) {
896                         if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
897                                 context = jQuerySub( context );
898                         }
899
900                         return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
901                 };
902                 jQuerySub.fn.init.prototype = jQuerySub.fn;
903                 var rootjQuerySub = jQuerySub(document);
904                 return jQuerySub;
905         },
906
907         browser: {}
908 });
909
910 // Populate the class2type map
911 jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
912         class2type[ "[object " + name + "]" ] = name.toLowerCase();
913 });
914
915 browserMatch = jQuery.uaMatch( userAgent );
916 if ( browserMatch.browser ) {
917         jQuery.browser[ browserMatch.browser ] = true;
918         jQuery.browser.version = browserMatch.version;
919 }
920
921 // Deprecated, use jQuery.browser.webkit instead
922 if ( jQuery.browser.webkit ) {
923         jQuery.browser.safari = true;
924 }
925
926 // IE doesn't match non-breaking spaces with \s
927 if ( rnotwhite.test( "\xA0" ) ) {
928         trimLeft = /^[\s\xA0]+/;
929         trimRight = /[\s\xA0]+$/;
930 }
931
932 // All jQuery objects should point back to these
933 rootjQuery = jQuery(document);
934
935 // Cleanup functions for the document ready method
936 if ( document.addEventListener ) {
937         DOMContentLoaded = function() {
938                 document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
939                 jQuery.ready();
940         };
941
942 } else if ( document.attachEvent ) {
943         DOMContentLoaded = function() {
944                 // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
945                 if ( document.readyState === "complete" ) {
946                         document.detachEvent( "onreadystatechange", DOMContentLoaded );
947                         jQuery.ready();
948                 }
949         };
950 }
951
952 // The DOM ready check for Internet Explorer
953 function doScrollCheck() {
954         if ( jQuery.isReady ) {
955                 return;
956         }
957
958         try {
959                 // If IE is used, use the trick by Diego Perini
960                 // http://javascript.nwbox.com/IEContentLoaded/
961                 document.documentElement.doScroll("left");
962         } catch(e) {
963                 setTimeout( doScrollCheck, 1 );
964                 return;
965         }
966
967         // and execute any waiting functions
968         jQuery.ready();
969 }
970
971 return jQuery;
972
973 })();
974
975
976 var // Promise methods
977         promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
978         // Static reference to slice
979         sliceDeferred = [].slice;
980
981 jQuery.extend({
982         // Create a simple deferred (one callbacks list)
983         _Deferred: function() {
984                 var // callbacks list
985                         callbacks = [],
986                         // stored [ context , args ]
987                         fired,
988                         // to avoid firing when already doing so
989                         firing,
990                         // flag to know if the deferred has been cancelled
991                         cancelled,
992                         // the deferred itself
993                         deferred  = {
994
995                                 // done( f1, f2, ...)
996                                 done: function() {
997                                         if ( !cancelled ) {
998                                                 var args = arguments,
999                                                         i,
1000                                                         length,
1001                                                         elem,
1002                                                         type,
1003                                                         _fired;
1004                                                 if ( fired ) {
1005                                                         _fired = fired;
1006                                                         fired = 0;
1007                                                 }
1008                                                 for ( i = 0, length = args.length; i < length; i++ ) {
1009                                                         elem = args[ i ];
1010                                                         type = jQuery.type( elem );
1011                                                         if ( type === "array" ) {
1012                                                                 deferred.done.apply( deferred, elem );
1013                                                         } else if ( type === "function" ) {
1014                                                                 callbacks.push( elem );
1015                                                         }
1016                                                 }
1017                                                 if ( _fired ) {
1018                                                         deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
1019                                                 }
1020                                         }
1021                                         return this;
1022                                 },
1023
1024                                 // resolve with given context and args
1025                                 resolveWith: function( context, args ) {
1026                                         if ( !cancelled && !fired && !firing ) {
1027                                                 // make sure args are available (#8421)
1028                                                 args = args || [];
1029                                                 firing = 1;
1030                                                 try {
1031                                                         while( callbacks[ 0 ] ) {
1032                                                                 callbacks.shift().apply( context, args );
1033                                                         }
1034                                                 }
1035                                                 finally {
1036                                                         fired = [ context, args ];
1037                                                         firing = 0;
1038                                                 }
1039                                         }
1040                                         return this;
1041                                 },
1042
1043                                 // resolve with this as context and given arguments
1044                                 resolve: function() {
1045                                         deferred.resolveWith( this, arguments );
1046                                         return this;
1047                                 },
1048
1049                                 // Has this deferred been resolved?
1050                                 isResolved: function() {
1051                                         return !!( firing || fired );
1052                                 },
1053
1054                                 // Cancel
1055                                 cancel: function() {
1056                                         cancelled = 1;
1057                                         callbacks = [];
1058                                         return this;
1059                                 }
1060                         };
1061
1062                 return deferred;
1063         },
1064
1065         // Full fledged deferred (two callbacks list)
1066         Deferred: function( func ) {
1067                 var deferred = jQuery._Deferred(),
1068                         failDeferred = jQuery._Deferred(),
1069                         promise;
1070                 // Add errorDeferred methods, then and promise
1071                 jQuery.extend( deferred, {
1072                         then: function( doneCallbacks, failCallbacks ) {
1073                                 deferred.done( doneCallbacks ).fail( failCallbacks );
1074                                 return this;
1075                         },
1076                         always: function() {
1077                                 return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
1078                         },
1079                         fail: failDeferred.done,
1080                         rejectWith: failDeferred.resolveWith,
1081                         reject: failDeferred.resolve,
1082                         isRejected: failDeferred.isResolved,
1083                         pipe: function( fnDone, fnFail ) {
1084                                 return jQuery.Deferred(function( newDefer ) {
1085                                         jQuery.each( {
1086                                                 done: [ fnDone, "resolve" ],
1087                                                 fail: [ fnFail, "reject" ]
1088                                         }, function( handler, data ) {
1089                                                 var fn = data[ 0 ],
1090                                                         action = data[ 1 ],
1091                                                         returned;
1092                                                 if ( jQuery.isFunction( fn ) ) {
1093                                                         deferred[ handler ](function() {
1094                                                                 returned = fn.apply( this, arguments );
1095                                                                 if ( returned && jQuery.isFunction( returned.promise ) ) {
1096                                                                         returned.promise().then( newDefer.resolve, newDefer.reject );
1097                                                                 } else {
1098                                                                         newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
1099                                                                 }
1100                                                         });
1101                                                 } else {
1102                                                         deferred[ handler ]( newDefer[ action ] );
1103                                                 }
1104                                         });
1105                                 }).promise();
1106                         },
1107                         // Get a promise for this deferred
1108                         // If obj is provided, the promise aspect is added to the object
1109                         promise: function( obj ) {
1110                                 if ( obj == null ) {
1111                                         if ( promise ) {
1112                                                 return promise;
1113                                         }
1114                                         promise = obj = {};
1115                                 }
1116                                 var i = promiseMethods.length;
1117                                 while( i-- ) {
1118                                         obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
1119                                 }
1120                                 return obj;
1121                         }
1122                 });
1123                 // Make sure only one callback list will be used
1124                 deferred.done( failDeferred.cancel ).fail( deferred.cancel );
1125                 // Unexpose cancel
1126                 delete deferred.cancel;
1127                 // Call given func if any
1128                 if ( func ) {
1129                         func.call( deferred, deferred );
1130                 }
1131                 return deferred;
1132         },
1133
1134         // Deferred helper
1135         when: function( firstParam ) {
1136                 var args = arguments,
1137                         i = 0,
1138                         length = args.length,
1139                         count = length,
1140                         deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
1141                                 firstParam :
1142                                 jQuery.Deferred();
1143                 function resolveFunc( i ) {
1144                         return function( value ) {
1145                                 args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
1146                                 if ( !( --count ) ) {
1147                                         // Strange bug in FF4:
1148                                         // Values changed onto the arguments object sometimes end up as undefined values
1149                                         // outside the $.when method. Cloning the object into a fresh array solves the issue
1150                                         deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
1151                                 }
1152                         };
1153                 }
1154                 if ( length > 1 ) {
1155                         for( ; i < length; i++ ) {
1156                                 if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
1157                                         args[ i ].promise().then( resolveFunc(i), deferred.reject );
1158                                 } else {
1159                                         --count;
1160                                 }
1161                         }
1162                         if ( !count ) {
1163                                 deferred.resolveWith( deferred, args );
1164                         }
1165                 } else if ( deferred !== firstParam ) {
1166                         deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
1167                 }
1168                 return deferred.promise();
1169         }
1170 });
1171
1172
1173
1174 jQuery.support = (function() {
1175
1176         var div = document.createElement( "div" ),
1177                 documentElement = document.documentElement,
1178                 all,
1179                 a,
1180                 select,
1181                 opt,
1182                 input,
1183                 marginDiv,
1184                 support,
1185                 fragment,
1186                 body,
1187                 testElementParent,
1188                 testElement,
1189                 testElementStyle,
1190                 tds,
1191                 events,
1192                 eventName,
1193                 i,
1194                 isSupported;
1195
1196         // Preliminary tests
1197         div.setAttribute("className", "t");
1198         div.innerHTML = "   <link><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type=checkbox>";
1199
1200
1201         all = div.getElementsByTagName( "*" );
1202         a = div.getElementsByTagName( "a" )[ 0 ];
1203
1204         // Can't get basic test support
1205         if ( !all || !all.length || !a ) {
1206                 return {};
1207         }
1208
1209         // First batch of supports tests
1210         select = document.createElement( "select" );
1211         opt = select.appendChild( document.createElement("option") );
1212         input = div.getElementsByTagName( "input" )[ 0 ];
1213
1214         support = {
1215                 // IE strips leading whitespace when .innerHTML is used
1216                 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
1217
1218                 // Make sure that tbody elements aren't automatically inserted
1219                 // IE will insert them into empty tables
1220                 tbody: !div.getElementsByTagName( "tbody" ).length,
1221
1222                 // Make sure that link elements get serialized correctly by innerHTML
1223                 // This requires a wrapper element in IE
1224                 htmlSerialize: !!div.getElementsByTagName( "link" ).length,
1225
1226                 // Get the style information from getAttribute
1227                 // (IE uses .cssText instead)
1228                 style: /top/.test( a.getAttribute("style") ),
1229
1230                 // Make sure that URLs aren't manipulated
1231                 // (IE normalizes it by default)
1232                 hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
1233
1234                 // Make sure that element opacity exists
1235                 // (IE uses filter instead)
1236                 // Use a regex to work around a WebKit issue. See #5145
1237                 opacity: /^0.55$/.test( a.style.opacity ),
1238
1239                 // Verify style float existence
1240                 // (IE uses styleFloat instead of cssFloat)
1241                 cssFloat: !!a.style.cssFloat,
1242
1243                 // Make sure that if no value is specified for a checkbox
1244                 // that it defaults to "on".
1245                 // (WebKit defaults to "" instead)
1246                 checkOn: ( input.value === "on" ),
1247
1248                 // Make sure that a selected-by-default option has a working selected property.
1249                 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
1250                 optSelected: opt.selected,
1251
1252                 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
1253                 getSetAttribute: div.className !== "t",
1254
1255                 // Will be defined later
1256                 submitBubbles: true,
1257                 changeBubbles: true,
1258                 focusinBubbles: false,
1259                 deleteExpando: true,
1260                 noCloneEvent: true,
1261                 inlineBlockNeedsLayout: false,
1262                 shrinkWrapBlocks: false,
1263                 reliableMarginRight: true
1264         };
1265
1266         // Make sure checked status is properly cloned
1267         input.checked = true;
1268         support.noCloneChecked = input.cloneNode( true ).checked;
1269
1270         // Make sure that the options inside disabled selects aren't marked as disabled
1271         // (WebKit marks them as disabled)
1272         select.disabled = true;
1273         support.optDisabled = !opt.disabled;
1274
1275         // Test to see if it's possible to delete an expando from an element
1276         // Fails in Internet Explorer
1277         try {
1278                 delete div.test;
1279         } catch( e ) {
1280                 support.deleteExpando = false;
1281         }
1282
1283         if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
1284                 div.attachEvent( "onclick", function() {
1285                         // Cloning a node shouldn't copy over any
1286                         // bound event handlers (IE does this)
1287                         support.noCloneEvent = false;
1288                 });
1289                 div.cloneNode( true ).fireEvent( "onclick" );
1290         }
1291
1292         // Check if a radio maintains it's value
1293         // after being appended to the DOM
1294         input = document.createElement("input");
1295         input.value = "t";
1296         input.setAttribute("type", "radio");
1297         support.radioValue = input.value === "t";
1298
1299         input.setAttribute("checked", "checked");
1300         div.appendChild( input );
1301         fragment = document.createDocumentFragment();
1302         fragment.appendChild( div.firstChild );
1303
1304         // WebKit doesn't clone checked state correctly in fragments
1305         support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
1306
1307         div.innerHTML = "";
1308
1309         // Figure out if the W3C box model works as expected
1310         div.style.width = div.style.paddingLeft = "1px";
1311
1312         body = document.getElementsByTagName( "body" )[ 0 ];
1313         // We use our own, invisible, body unless the body is already present
1314         // in which case we use a div (#9239)
1315         testElement = document.createElement( body ? "div" : "body" );
1316         testElementStyle = {
1317                 visibility: "hidden",
1318                 width: 0,
1319                 height: 0,
1320                 border: 0,
1321                 margin: 0,
1322                 background: "none"
1323         };
1324         if ( body ) {
1325                 jQuery.extend( testElementStyle, {
1326                         position: "absolute",
1327                         left: "-1000px",
1328                         top: "-1000px"
1329                 });
1330         }
1331         for ( i in testElementStyle ) {
1332                 testElement.style[ i ] = testElementStyle[ i ];
1333         }
1334         testElement.appendChild( div );
1335         testElementParent = body || documentElement;
1336         testElementParent.insertBefore( testElement, testElementParent.firstChild );
1337
1338         // Check if a disconnected checkbox will retain its checked
1339         // value of true after appended to the DOM (IE6/7)
1340         support.appendChecked = input.checked;
1341
1342         support.boxModel = div.offsetWidth === 2;
1343
1344         if ( "zoom" in div.style ) {
1345                 // Check if natively block-level elements act like inline-block
1346                 // elements when setting their display to 'inline' and giving
1347                 // them layout
1348                 // (IE < 8 does this)
1349                 div.style.display = "inline";
1350                 div.style.zoom = 1;
1351                 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
1352
1353                 // Check if elements with layout shrink-wrap their children
1354                 // (IE 6 does this)
1355                 div.style.display = "";
1356                 div.innerHTML = "<div style='width:4px;'></div>";
1357                 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
1358         }
1359
1360         div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
1361         tds = div.getElementsByTagName( "td" );
1362
1363         // Check if table cells still have offsetWidth/Height when they are set
1364         // to display:none and there are still other visible table cells in a
1365         // table row; if so, offsetWidth/Height are not reliable for use when
1366         // determining if an element has been hidden directly using
1367         // display:none (it is still safe to use offsets if a parent element is
1368         // hidden; don safety goggles and see bug #4512 for more information).
1369         // (only IE 8 fails this test)
1370         isSupported = ( tds[ 0 ].offsetHeight === 0 );
1371
1372         tds[ 0 ].style.display = "";
1373         tds[ 1 ].style.display = "none";
1374
1375         // Check if empty table cells still have offsetWidth/Height
1376         // (IE < 8 fail this test)
1377         support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
1378         div.innerHTML = "";
1379
1380         // Check if div with explicit width and no margin-right incorrectly
1381         // gets computed margin-right based on width of container. For more
1382         // info see bug #3333
1383         // Fails in WebKit before Feb 2011 nightlies
1384         // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
1385         if ( document.defaultView && document.defaultView.getComputedStyle ) {
1386                 marginDiv = document.createElement( "div" );
1387                 marginDiv.style.width = "0";
1388                 marginDiv.style.marginRight = "0";
1389                 div.appendChild( marginDiv );
1390                 support.reliableMarginRight =
1391                         ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
1392         }
1393
1394         // Remove the body element we added
1395         testElement.innerHTML = "";
1396         testElementParent.removeChild( testElement );
1397
1398         // Technique from Juriy Zaytsev
1399         // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
1400         // We only care about the case where non-standard event systems
1401         // are used, namely in IE. Short-circuiting here helps us to
1402         // avoid an eval call (in setAttribute) which can cause CSP
1403         // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
1404         if ( div.attachEvent ) {
1405                 for( i in {
1406                         submit: 1,
1407                         change: 1,
1408                         focusin: 1
1409                 } ) {
1410                         eventName = "on" + i;
1411                         isSupported = ( eventName in div );
1412                         if ( !isSupported ) {
1413                                 div.setAttribute( eventName, "return;" );
1414                                 isSupported = ( typeof div[ eventName ] === "function" );
1415                         }
1416                         support[ i + "Bubbles" ] = isSupported;
1417                 }
1418         }
1419
1420         // Null connected elements to avoid leaks in IE
1421         testElement = fragment = select = opt = body = marginDiv = div = input = null;
1422
1423         return support;
1424 })();
1425
1426 // Keep track of boxModel
1427 jQuery.boxModel = jQuery.support.boxModel;
1428
1429
1430
1431
1432 var rbrace = /^(?:\{.*\}|\[.*\])$/,
1433         rmultiDash = /([a-z])([A-Z])/g;
1434
1435 jQuery.extend({
1436         cache: {},
1437
1438         // Please use with caution
1439         uuid: 0,
1440
1441         // Unique for each copy of jQuery on the page
1442         // Non-digits removed to match rinlinejQuery
1443         expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
1444
1445         // The following elements throw uncatchable exceptions if you
1446         // attempt to add expando properties to them.
1447         noData: {
1448                 "embed": true,
1449                 // Ban all objects except for Flash (which handle expandos)
1450                 "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
1451                 "applet": true
1452         },
1453
1454         hasData: function( elem ) {
1455                 elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
1456
1457                 return !!elem && !isEmptyDataObject( elem );
1458         },
1459
1460         data: function( elem, name, data, pvt /* Internal Use Only */ ) {
1461                 if ( !jQuery.acceptData( elem ) ) {
1462                         return;
1463                 }
1464
1465                 var thisCache, ret,
1466                         internalKey = jQuery.expando,
1467                         getByName = typeof name === "string",
1468
1469                         // We have to handle DOM nodes and JS objects differently because IE6-7
1470                         // can't GC object references properly across the DOM-JS boundary
1471                         isNode = elem.nodeType,
1472
1473                         // Only DOM nodes need the global jQuery cache; JS object data is
1474                         // attached directly to the object so GC can occur automatically
1475                         cache = isNode ? jQuery.cache : elem,
1476
1477                         // Only defining an ID for JS objects if its cache already exists allows
1478                         // the code to shortcut on the same path as a DOM node with no cache
1479                         id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
1480
1481                 // Avoid doing any more work than we need to when trying to get data on an
1482                 // object that has no data at all
1483                 if ( (!id || (pvt && id && (cache[ id ] && !cache[ id ][ internalKey ]))) && getByName && data === undefined ) {
1484                         return;
1485                 }
1486
1487                 if ( !id ) {
1488                         // Only DOM nodes need a new unique ID for each element since their data
1489                         // ends up in the global cache
1490                         if ( isNode ) {
1491                                 elem[ jQuery.expando ] = id = ++jQuery.uuid;
1492                         } else {
1493                                 id = jQuery.expando;
1494                         }
1495                 }
1496
1497                 if ( !cache[ id ] ) {
1498                         cache[ id ] = {};
1499
1500                         // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1501                         // metadata on plain JS objects when the object is serialized using
1502                         // JSON.stringify
1503                         if ( !isNode ) {
1504                                 cache[ id ].toJSON = jQuery.noop;
1505                         }
1506                 }
1507
1508                 // An object can be passed to jQuery.data instead of a key/value pair; this gets
1509                 // shallow copied over onto the existing cache
1510                 if ( typeof name === "object" || typeof name === "function" ) {
1511                         if ( pvt ) {
1512                                 cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
1513                         } else {
1514                                 cache[ id ] = jQuery.extend(cache[ id ], name);
1515                         }
1516                 }
1517
1518                 thisCache = cache[ id ];
1519
1520                 // Internal jQuery data is stored in a separate object inside the object's data
1521                 // cache in order to avoid key collisions between internal data and user-defined
1522                 // data
1523                 if ( pvt ) {
1524                         if ( !thisCache[ internalKey ] ) {
1525                                 thisCache[ internalKey ] = {};
1526                         }
1527
1528                         thisCache = thisCache[ internalKey ];
1529                 }
1530
1531                 if ( data !== undefined ) {
1532                         thisCache[ jQuery.camelCase( name ) ] = data;
1533                 }
1534
1535                 // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
1536                 // not attempt to inspect the internal events object using jQuery.data, as this
1537                 // internal data object is undocumented and subject to change.
1538                 if ( name === "events" && !thisCache[name] ) {
1539                         return thisCache[ internalKey ] && thisCache[ internalKey ].events;
1540                 }
1541
1542                 // Check for both converted-to-camel and non-converted data property names
1543                 // If a data property was specified
1544                 if ( getByName ) {
1545
1546                         // First Try to find as-is property data
1547                         ret = thisCache[ name ];
1548
1549                         // Test for null|undefined property data
1550                         if ( ret == null ) {
1551
1552                                 // Try to find the camelCased property
1553                                 ret = thisCache[ jQuery.camelCase( name ) ];
1554                         }
1555                 } else {
1556                         ret = thisCache;
1557                 }
1558
1559                 return ret;
1560         },
1561
1562         removeData: function( elem, name, pvt /* Internal Use Only */ ) {
1563                 if ( !jQuery.acceptData( elem ) ) {
1564                         return;
1565                 }
1566
1567                 var thisCache,
1568
1569                         // Reference to internal data cache key
1570                         internalKey = jQuery.expando,
1571
1572                         isNode = elem.nodeType,
1573
1574                         // See jQuery.data for more information
1575                         cache = isNode ? jQuery.cache : elem,
1576
1577                         // See jQuery.data for more information
1578                         id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
1579
1580                 // If there is already no cache entry for this object, there is no
1581                 // purpose in continuing
1582                 if ( !cache[ id ] ) {
1583                         return;
1584                 }
1585
1586                 if ( name ) {
1587
1588                         thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
1589
1590                         if ( thisCache ) {
1591
1592                                 // Support interoperable removal of hyphenated or camelcased keys
1593                                 if ( !thisCache[ name ] ) {
1594                                         name = jQuery.camelCase( name );
1595                                 }
1596
1597                                 delete thisCache[ name ];
1598
1599                                 // If there is no data left in the cache, we want to continue
1600                                 // and let the cache object itself get destroyed
1601                                 if ( !isEmptyDataObject(thisCache) ) {
1602                                         return;
1603                                 }
1604                         }
1605                 }
1606
1607                 // See jQuery.data for more information
1608                 if ( pvt ) {
1609                         delete cache[ id ][ internalKey ];
1610
1611                         // Don't destroy the parent cache unless the internal data object
1612                         // had been the only thing left in it
1613                         if ( !isEmptyDataObject(cache[ id ]) ) {
1614                                 return;
1615                         }
1616                 }
1617
1618                 var internalCache = cache[ id ][ internalKey ];
1619
1620                 // Browsers that fail expando deletion also refuse to delete expandos on
1621                 // the window, but it will allow it on all other JS objects; other browsers
1622                 // don't care
1623                 // Ensure that `cache` is not a window object #10080
1624                 if ( jQuery.support.deleteExpando || !cache.setInterval ) {
1625                         delete cache[ id ];
1626                 } else {
1627                         cache[ id ] = null;
1628                 }
1629
1630                 // We destroyed the entire user cache at once because it's faster than
1631                 // iterating through each key, but we need to continue to persist internal
1632                 // data if it existed
1633                 if ( internalCache ) {
1634                         cache[ id ] = {};
1635                         // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
1636                         // metadata on plain JS objects when the object is serialized using
1637                         // JSON.stringify
1638                         if ( !isNode ) {
1639                                 cache[ id ].toJSON = jQuery.noop;
1640                         }
1641
1642                         cache[ id ][ internalKey ] = internalCache;
1643
1644                 // Otherwise, we need to eliminate the expando on the node to avoid
1645                 // false lookups in the cache for entries that no longer exist
1646                 } else if ( isNode ) {
1647                         // IE does not allow us to delete expando properties from nodes,
1648                         // nor does it have a removeAttribute function on Document nodes;
1649                         // we must handle all of these cases
1650                         if ( jQuery.support.deleteExpando ) {
1651                                 delete elem[ jQuery.expando ];
1652                         } else if ( elem.removeAttribute ) {
1653                                 elem.removeAttribute( jQuery.expando );
1654                         } else {
1655                                 elem[ jQuery.expando ] = null;
1656                         }
1657                 }
1658         },
1659
1660         // For internal use only.
1661         _data: function( elem, name, data ) {
1662                 return jQuery.data( elem, name, data, true );
1663         },
1664
1665         // A method for determining if a DOM node can handle the data expando
1666         acceptData: function( elem ) {
1667                 if ( elem.nodeName ) {
1668                         var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
1669
1670                         if ( match ) {
1671                                 return !(match === true || elem.getAttribute("classid") !== match);
1672                         }
1673                 }
1674
1675                 return true;
1676         }
1677 });
1678
1679 jQuery.fn.extend({
1680         data: function( key, value ) {
1681                 var data = null;
1682
1683                 if ( typeof key === "undefined" ) {
1684                         if ( this.length ) {
1685                                 data = jQuery.data( this[0] );
1686
1687                                 if ( this[0].nodeType === 1 ) {
1688                             var attr = this[0].attributes, name;
1689                                         for ( var i = 0, l = attr.length; i < l; i++ ) {
1690                                                 name = attr[i].name;
1691
1692                                                 if ( name.indexOf( "data-" ) === 0 ) {
1693                                                         name = jQuery.camelCase( name.substring(5) );
1694
1695                                                         dataAttr( this[0], name, data[ name ] );
1696                                                 }
1697                                         }
1698                                 }
1699                         }
1700
1701                         return data;
1702
1703                 } else if ( typeof key === "object" ) {
1704                         return this.each(function() {
1705                                 jQuery.data( this, key );
1706                         });
1707                 }
1708
1709                 var parts = key.split(".");
1710                 parts[1] = parts[1] ? "." + parts[1] : "";
1711
1712                 if ( value === undefined ) {
1713                         data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
1714
1715                         // Try to fetch any internally stored data first
1716                         if ( data === undefined && this.length ) {
1717                                 data = jQuery.data( this[0], key );
1718                                 data = dataAttr( this[0], key, data );
1719                         }
1720
1721                         return data === undefined && parts[1] ?
1722                                 this.data( parts[0] ) :
1723                                 data;
1724
1725                 } else {
1726                         return this.each(function() {
1727                                 var $this = jQuery( this ),
1728                                         args = [ parts[0], value ];
1729
1730                                 $this.triggerHandler( "setData" + parts[1] + "!", args );
1731                                 jQuery.data( this, key, value );
1732                                 $this.triggerHandler( "changeData" + parts[1] + "!", args );
1733                         });
1734                 }
1735         },
1736
1737         removeData: function( key ) {
1738                 return this.each(function() {
1739                         jQuery.removeData( this, key );
1740                 });
1741         }
1742 });
1743
1744 function dataAttr( elem, key, data ) {
1745         // If nothing was found internally, try to fetch any
1746         // data from the HTML5 data-* attribute
1747         if ( data === undefined && elem.nodeType === 1 ) {
1748                 var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
1749
1750                 data = elem.getAttribute( name );
1751
1752                 if ( typeof data === "string" ) {
1753                         try {
1754                                 data = data === "true" ? true :
1755                                 data === "false" ? false :
1756                                 data === "null" ? null :
1757                                 !jQuery.isNaN( data ) ? parseFloat( data ) :
1758                                         rbrace.test( data ) ? jQuery.parseJSON( data ) :
1759                                         data;
1760                         } catch( e ) {}
1761
1762                         // Make sure we set the data so it isn't changed later
1763                         jQuery.data( elem, key, data );
1764
1765                 } else {
1766                         data = undefined;
1767                 }
1768         }
1769
1770         return data;
1771 }
1772
1773 // TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
1774 // property to be considered empty objects; this property always exists in
1775 // order to make sure JSON.stringify does not expose internal metadata
1776 function isEmptyDataObject( obj ) {
1777         for ( var name in obj ) {
1778                 if ( name !== "toJSON" ) {
1779                         return false;
1780                 }
1781         }
1782
1783         return true;
1784 }
1785
1786
1787
1788
1789 function handleQueueMarkDefer( elem, type, src ) {
1790         var deferDataKey = type + "defer",
1791                 queueDataKey = type + "queue",
1792                 markDataKey = type + "mark",
1793                 defer = jQuery.data( elem, deferDataKey, undefined, true );
1794         if ( defer &&
1795                 ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
1796                 ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
1797                 // Give room for hard-coded callbacks to fire first
1798                 // and eventually mark/queue something else on the element
1799                 setTimeout( function() {
1800                         if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
1801                                 !jQuery.data( elem, markDataKey, undefined, true ) ) {
1802                                 jQuery.removeData( elem, deferDataKey, true );
1803                                 defer.resolve();
1804                         }
1805                 }, 0 );
1806         }
1807 }
1808
1809 jQuery.extend({
1810
1811         _mark: function( elem, type ) {
1812                 if ( elem ) {
1813                         type = (type || "fx") + "mark";
1814                         jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
1815                 }
1816         },
1817
1818         _unmark: function( force, elem, type ) {
1819                 if ( force !== true ) {
1820                         type = elem;
1821                         elem = force;
1822                         force = false;
1823                 }
1824                 if ( elem ) {
1825                         type = type || "fx";
1826                         var key = type + "mark",
1827                                 count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
1828                         if ( count ) {
1829                                 jQuery.data( elem, key, count, true );
1830                         } else {
1831                                 jQuery.removeData( elem, key, true );
1832                                 handleQueueMarkDefer( elem, type, "mark" );
1833                         }
1834                 }
1835         },
1836
1837         queue: function( elem, type, data ) {
1838                 if ( elem ) {
1839                         type = (type || "fx") + "queue";
1840                         var q = jQuery.data( elem, type, undefined, true );
1841                         // Speed up dequeue by getting out quickly if this is just a lookup
1842                         if ( data ) {
1843                                 if ( !q || jQuery.isArray(data) ) {
1844                                         q = jQuery.data( elem, type, jQuery.makeArray(data), true );
1845                                 } else {
1846                                         q.push( data );
1847                                 }
1848                         }
1849                         return q || [];
1850                 }
1851         },
1852
1853         dequeue: function( elem, type ) {
1854                 type = type || "fx";
1855
1856                 var queue = jQuery.queue( elem, type ),
1857                         fn = queue.shift(),
1858                         defer;
1859
1860                 // If the fx queue is dequeued, always remove the progress sentinel
1861                 if ( fn === "inprogress" ) {
1862                         fn = queue.shift();
1863                 }
1864
1865                 if ( fn ) {
1866                         // Add a progress sentinel to prevent the fx queue from being
1867                         // automatically dequeued
1868                         if ( type === "fx" ) {
1869                                 queue.unshift("inprogress");
1870                         }
1871
1872                         fn.call(elem, function() {
1873                                 jQuery.dequeue(elem, type);
1874                         });
1875                 }
1876
1877                 if ( !queue.length ) {
1878                         jQuery.removeData( elem, type + "queue", true );
1879                         handleQueueMarkDefer( elem, type, "queue" );
1880                 }
1881         }
1882 });
1883
1884 jQuery.fn.extend({
1885         queue: function( type, data ) {
1886                 if ( typeof type !== "string" ) {
1887                         data = type;
1888                         type = "fx";
1889                 }
1890
1891                 if ( data === undefined ) {
1892                         return jQuery.queue( this[0], type );
1893                 }
1894                 return this.each(function() {
1895                         var queue = jQuery.queue( this, type, data );
1896
1897                         if ( type === "fx" && queue[0] !== "inprogress" ) {
1898                                 jQuery.dequeue( this, type );
1899                         }
1900                 });
1901         },
1902         dequeue: function( type ) {
1903                 return this.each(function() {
1904                         jQuery.dequeue( this, type );
1905                 });
1906         },
1907         // Based off of the plugin by Clint Helfers, with permission.
1908         // http://blindsignals.com/index.php/2009/07/jquery-delay/
1909         delay: function( time, type ) {
1910                 time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
1911                 type = type || "fx";
1912
1913                 return this.queue( type, function() {
1914                         var elem = this;
1915                         setTimeout(function() {
1916                                 jQuery.dequeue( elem, type );
1917                         }, time );
1918                 });
1919         },
1920         clearQueue: function( type ) {
1921                 return this.queue( type || "fx", [] );
1922         },
1923         // Get a promise resolved when queues of a certain type
1924         // are emptied (fx is the type by default)
1925         promise: function( type, object ) {
1926                 if ( typeof type !== "string" ) {
1927                         object = type;
1928                         type = undefined;
1929                 }
1930                 type = type || "fx";
1931                 var defer = jQuery.Deferred(),
1932                         elements = this,
1933                         i = elements.length,
1934                         count = 1,
1935                         deferDataKey = type + "defer",
1936                         queueDataKey = type + "queue",
1937                         markDataKey = type + "mark",
1938                         tmp;
1939                 function resolve() {
1940                         if ( !( --count ) ) {
1941                                 defer.resolveWith( elements, [ elements ] );
1942                         }
1943                 }
1944                 while( i-- ) {
1945                         if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
1946                                         ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
1947                                                 jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
1948                                         jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
1949                                 count++;
1950                                 tmp.done( resolve );
1951                         }
1952                 }
1953                 resolve();
1954                 return defer.promise();
1955         }
1956 });
1957
1958
1959
1960
1961 var rclass = /[\n\t\r]/g,
1962         rspace = /\s+/,
1963         rreturn = /\r/g,
1964         rtype = /^(?:button|input)$/i,
1965         rfocusable = /^(?:button|input|object|select|textarea)$/i,
1966         rclickable = /^a(?:rea)?$/i,
1967         rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
1968         nodeHook, boolHook;
1969
1970 jQuery.fn.extend({
1971         attr: function( name, value ) {
1972                 return jQuery.access( this, name, value, true, jQuery.attr );
1973         },
1974
1975         removeAttr: function( name ) {
1976                 return this.each(function() {
1977                         jQuery.removeAttr( this, name );
1978                 });
1979         },
1980         
1981         prop: function( name, value ) {
1982                 return jQuery.access( this, name, value, true, jQuery.prop );
1983         },
1984         
1985         removeProp: function( name ) {
1986                 name = jQuery.propFix[ name ] || name;
1987                 return this.each(function() {
1988                         // try/catch handles cases where IE balks (such as removing a property on window)
1989                         try {
1990                                 this[ name ] = undefined;
1991                                 delete this[ name ];
1992                         } catch( e ) {}
1993                 });
1994         },
1995
1996         addClass: function( value ) {
1997                 var classNames, i, l, elem,
1998                         setClass, c, cl;
1999
2000                 if ( jQuery.isFunction( value ) ) {
2001                         return this.each(function( j ) {
2002                                 jQuery( this ).addClass( value.call(this, j, this.className) );
2003                         });
2004                 }
2005
2006                 if ( value && typeof value === "string" ) {
2007                         classNames = value.split( rspace );
2008
2009                         for ( i = 0, l = this.length; i < l; i++ ) {
2010                                 elem = this[ i ];
2011
2012                                 if ( elem.nodeType === 1 ) {
2013                                         if ( !elem.className && classNames.length === 1 ) {
2014                                                 elem.className = value;
2015
2016                                         } else {
2017                                                 setClass = " " + elem.className + " ";
2018
2019                                                 for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2020                                                         if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
2021                                                                 setClass += classNames[ c ] + " ";
2022                                                         }
2023                                                 }
2024                                                 elem.className = jQuery.trim( setClass );
2025                                         }
2026                                 }
2027                         }
2028                 }
2029
2030                 return this;
2031         },
2032
2033         removeClass: function( value ) {
2034                 var classNames, i, l, elem, className, c, cl;
2035
2036                 if ( jQuery.isFunction( value ) ) {
2037                         return this.each(function( j ) {
2038                                 jQuery( this ).removeClass( value.call(this, j, this.className) );
2039                         });
2040                 }
2041
2042                 if ( (value && typeof value === "string") || value === undefined ) {
2043                         classNames = (value || "").split( rspace );
2044
2045                         for ( i = 0, l = this.length; i < l; i++ ) {
2046                                 elem = this[ i ];
2047
2048                                 if ( elem.nodeType === 1 && elem.className ) {
2049                                         if ( value ) {
2050                                                 className = (" " + elem.className + " ").replace( rclass, " " );
2051                                                 for ( c = 0, cl = classNames.length; c < cl; c++ ) {
2052                                                         className = className.replace(" " + classNames[ c ] + " ", " ");
2053                                                 }
2054                                                 elem.className = jQuery.trim( className );
2055
2056                                         } else {
2057                                                 elem.className = "";
2058                                         }
2059                                 }
2060                         }
2061                 }
2062
2063                 return this;
2064         },
2065
2066         toggleClass: function( value, stateVal ) {
2067                 var type = typeof value,
2068                         isBool = typeof stateVal === "boolean";
2069
2070                 if ( jQuery.isFunction( value ) ) {
2071                         return this.each(function( i ) {
2072                                 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
2073                         });
2074                 }
2075
2076                 return this.each(function() {
2077                         if ( type === "string" ) {
2078                                 // toggle individual class names
2079                                 var className,
2080                                         i = 0,
2081                                         self = jQuery( this ),
2082                                         state = stateVal,
2083                                         classNames = value.split( rspace );
2084
2085                                 while ( (className = classNames[ i++ ]) ) {
2086                                         // check each className given, space seperated list
2087                                         state = isBool ? state : !self.hasClass( className );
2088                                         self[ state ? "addClass" : "removeClass" ]( className );
2089                                 }
2090
2091                         } else if ( type === "undefined" || type === "boolean" ) {
2092                                 if ( this.className ) {
2093                                         // store className if set
2094                                         jQuery._data( this, "__className__", this.className );
2095                                 }
2096
2097                                 // toggle whole className
2098                                 this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
2099                         }
2100                 });
2101         },
2102
2103         hasClass: function( selector ) {
2104                 var className = " " + selector + " ";
2105                 for ( var i = 0, l = this.length; i < l; i++ ) {
2106                         if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
2107                                 return true;
2108                         }
2109                 }
2110
2111                 return false;
2112         },
2113
2114         val: function( value ) {
2115                 var hooks, ret,
2116                         elem = this[0];
2117                 
2118                 if ( !arguments.length ) {
2119                         if ( elem ) {
2120                                 hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
2121
2122                                 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
2123                                         return ret;
2124                                 }
2125
2126                                 ret = elem.value;
2127
2128                                 return typeof ret === "string" ? 
2129                                         // handle most common string cases
2130                                         ret.replace(rreturn, "") : 
2131                                         // handle cases where value is null/undef or number
2132                                         ret == null ? "" : ret;
2133                         }
2134
2135                         return undefined;
2136                 }
2137
2138                 var isFunction = jQuery.isFunction( value );
2139
2140                 return this.each(function( i ) {
2141                         var self = jQuery(this), val;
2142
2143                         if ( this.nodeType !== 1 ) {
2144                                 return;
2145                         }
2146
2147                         if ( isFunction ) {
2148                                 val = value.call( this, i, self.val() );
2149                         } else {
2150                                 val = value;
2151                         }
2152
2153                         // Treat null/undefined as ""; convert numbers to string
2154                         if ( val == null ) {
2155                                 val = "";
2156                         } else if ( typeof val === "number" ) {
2157                                 val += "";
2158                         } else if ( jQuery.isArray( val ) ) {
2159                                 val = jQuery.map(val, function ( value ) {
2160                                         return value == null ? "" : value + "";
2161                                 });
2162                         }
2163
2164                         hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
2165
2166                         // If set returns undefined, fall back to normal setting
2167                         if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
2168                                 this.value = val;
2169                         }
2170                 });
2171         }
2172 });
2173
2174 jQuery.extend({
2175         valHooks: {
2176                 option: {
2177                         get: function( elem ) {
2178                                 // attributes.value is undefined in Blackberry 4.7 but
2179                                 // uses .value. See #6932
2180                                 var val = elem.attributes.value;
2181                                 return !val || val.specified ? elem.value : elem.text;
2182                         }
2183                 },
2184                 select: {
2185                         get: function( elem ) {
2186                                 var value,
2187                                         index = elem.selectedIndex,
2188                                         values = [],
2189                                         options = elem.options,
2190                                         one = elem.type === "select-one";
2191
2192                                 // Nothing was selected
2193                                 if ( index < 0 ) {
2194                                         return null;
2195                                 }
2196
2197                                 // Loop through all the selected options
2198                                 for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
2199                                         var option = options[ i ];
2200
2201                                         // Don't return options that are disabled or in a disabled optgroup
2202                                         if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
2203                                                         (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
2204
2205                                                 // Get the specific value for the option
2206                                                 value = jQuery( option ).val();
2207
2208                                                 // We don't need an array for one selects
2209                                                 if ( one ) {
2210                                                         return value;
2211                                                 }
2212
2213                                                 // Multi-Selects return an array
2214                                                 values.push( value );
2215                                         }
2216                                 }
2217
2218                                 // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
2219                                 if ( one && !values.length && options.length ) {
2220                                         return jQuery( options[ index ] ).val();
2221                                 }
2222
2223                                 return values;
2224                         },
2225
2226                         set: function( elem, value ) {
2227                                 var values = jQuery.makeArray( value );
2228
2229                                 jQuery(elem).find("option").each(function() {
2230                                         this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
2231                                 });
2232
2233                                 if ( !values.length ) {
2234                                         elem.selectedIndex = -1;
2235                                 }
2236                                 return values;
2237                         }
2238                 }
2239         },
2240
2241         attrFn: {
2242                 val: true,
2243                 css: true,
2244                 html: true,
2245                 text: true,
2246                 data: true,
2247                 width: true,
2248                 height: true,
2249                 offset: true
2250         },
2251         
2252         attrFix: {
2253                 // Always normalize to ensure hook usage
2254                 tabindex: "tabIndex"
2255         },
2256         
2257         attr: function( elem, name, value, pass ) {
2258                 var nType = elem.nodeType;
2259                 
2260                 // don't get/set attributes on text, comment and attribute nodes
2261                 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2262                         return undefined;
2263                 }
2264
2265                 if ( pass && name in jQuery.attrFn ) {
2266                         return jQuery( elem )[ name ]( value );
2267                 }
2268
2269                 // Fallback to prop when attributes are not supported
2270                 if ( !("getAttribute" in elem) ) {
2271                         return jQuery.prop( elem, name, value );
2272                 }
2273
2274                 var ret, hooks,
2275                         notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2276
2277                 // Normalize the name if needed
2278                 if ( notxml ) {
2279                         name = jQuery.attrFix[ name ] || name;
2280
2281                         hooks = jQuery.attrHooks[ name ];
2282
2283                         if ( !hooks ) {
2284                                 // Use boolHook for boolean attributes
2285                                 if ( rboolean.test( name ) ) {
2286                                         hooks = boolHook;
2287
2288                                 // Use nodeHook if available( IE6/7 )
2289                                 } else if ( nodeHook ) {
2290                                         hooks = nodeHook;
2291                                 }
2292                         }
2293                 }
2294
2295                 if ( value !== undefined ) {
2296
2297                         if ( value === null ) {
2298                                 jQuery.removeAttr( elem, name );
2299                                 return undefined;
2300
2301                         } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
2302                                 return ret;
2303
2304                         } else {
2305                                 elem.setAttribute( name, "" + value );
2306                                 return value;
2307                         }
2308
2309                 } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
2310                         return ret;
2311
2312                 } else {
2313
2314                         ret = elem.getAttribute( name );
2315
2316                         // Non-existent attributes return null, we normalize to undefined
2317                         return ret === null ?
2318                                 undefined :
2319                                 ret;
2320                 }
2321         },
2322
2323         removeAttr: function( elem, name ) {
2324                 var propName;
2325                 if ( elem.nodeType === 1 ) {
2326                         name = jQuery.attrFix[ name ] || name;
2327
2328                         jQuery.attr( elem, name, "" );
2329                         elem.removeAttribute( name );
2330
2331                         // Set corresponding property to false for boolean attributes
2332                         if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
2333                                 elem[ propName ] = false;
2334                         }
2335                 }
2336         },
2337
2338         attrHooks: {
2339                 type: {
2340                         set: function( elem, value ) {
2341                                 // We can't allow the type property to be changed (since it causes problems in IE)
2342                                 if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
2343                                         jQuery.error( "type property can't be changed" );
2344                                 } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
2345                                         // Setting the type on a radio button after the value resets the value in IE6-9
2346                                         // Reset value to it's default in case type is set after value
2347                                         // This is for element creation
2348                                         var val = elem.value;
2349                                         elem.setAttribute( "type", value );
2350                                         if ( val ) {
2351                                                 elem.value = val;
2352                                         }
2353                                         return value;
2354                                 }
2355                         }
2356                 },
2357                 // Use the value property for back compat
2358                 // Use the nodeHook for button elements in IE6/7 (#1954)
2359                 value: {
2360                         get: function( elem, name ) {
2361                                 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2362                                         return nodeHook.get( elem, name );
2363                                 }
2364                                 return name in elem ?
2365                                         elem.value :
2366                                         null;
2367                         },
2368                         set: function( elem, value, name ) {
2369                                 if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
2370                                         return nodeHook.set( elem, value, name );
2371                                 }
2372                                 // Does not return so that setAttribute is also used
2373                                 elem.value = value;
2374                         }
2375                 }
2376         },
2377
2378         propFix: {
2379                 tabindex: "tabIndex",
2380                 readonly: "readOnly",
2381                 "for": "htmlFor",
2382                 "class": "className",
2383                 maxlength: "maxLength",
2384                 cellspacing: "cellSpacing",
2385                 cellpadding: "cellPadding",
2386                 rowspan: "rowSpan",
2387                 colspan: "colSpan",
2388                 usemap: "useMap",
2389                 frameborder: "frameBorder",
2390                 contenteditable: "contentEditable"
2391         },
2392         
2393         prop: function( elem, name, value ) {
2394                 var nType = elem.nodeType;
2395
2396                 // don't get/set properties on text, comment and attribute nodes
2397                 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
2398                         return undefined;
2399                 }
2400
2401                 var ret, hooks,
2402                         notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
2403
2404                 if ( notxml ) {
2405                         // Fix name and attach hooks
2406                         name = jQuery.propFix[ name ] || name;
2407                         hooks = jQuery.propHooks[ name ];
2408                 }
2409
2410                 if ( value !== undefined ) {
2411                         if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
2412                                 return ret;
2413
2414                         } else {
2415                                 return (elem[ name ] = value);
2416                         }
2417
2418                 } else {
2419                         if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
2420                                 return ret;
2421
2422                         } else {
2423                                 return elem[ name ];
2424                         }
2425                 }
2426         },
2427         
2428         propHooks: {
2429                 tabIndex: {
2430                         get: function( elem ) {
2431                                 // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
2432                                 // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
2433                                 var attributeNode = elem.getAttributeNode("tabindex");
2434
2435                                 return attributeNode && attributeNode.specified ?
2436                                         parseInt( attributeNode.value, 10 ) :
2437                                         rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
2438                                                 0 :
2439                                                 undefined;
2440                         }
2441                 }
2442         }
2443 });
2444
2445 // Add the tabindex propHook to attrHooks for back-compat
2446 jQuery.attrHooks.tabIndex = jQuery.propHooks.tabIndex;
2447
2448 // Hook for boolean attributes
2449 boolHook = {
2450         get: function( elem, name ) {
2451                 // Align boolean attributes with corresponding properties
2452                 // Fall back to attribute presence where some booleans are not supported
2453                 var attrNode;
2454                 return jQuery.prop( elem, name ) === true || ( attrNode = elem.getAttributeNode( name ) ) && attrNode.nodeValue !== false ?
2455                         name.toLowerCase() :
2456                         undefined;
2457         },
2458         set: function( elem, value, name ) {
2459                 var propName;
2460                 if ( value === false ) {
2461                         // Remove boolean attributes when set to false
2462                         jQuery.removeAttr( elem, name );
2463                 } else {
2464                         // value is true since we know at this point it's type boolean and not false
2465                         // Set boolean attributes to the same name and set the DOM property
2466                         propName = jQuery.propFix[ name ] || name;
2467                         if ( propName in elem ) {
2468                                 // Only set the IDL specifically if it already exists on the element
2469                                 elem[ propName ] = true;
2470                         }
2471
2472                         elem.setAttribute( name, name.toLowerCase() );
2473                 }
2474                 return name;
2475         }
2476 };
2477
2478 // IE6/7 do not support getting/setting some attributes with get/setAttribute
2479 if ( !jQuery.support.getSetAttribute ) {
2480         
2481         // Use this for any attribute in IE6/7
2482         // This fixes almost every IE6/7 issue
2483         nodeHook = jQuery.valHooks.button = {
2484                 get: function( elem, name ) {
2485                         var ret;
2486                         ret = elem.getAttributeNode( name );
2487                         // Return undefined if nodeValue is empty string
2488                         return ret && ret.nodeValue !== "" ?
2489                                 ret.nodeValue :
2490                                 undefined;
2491                 },
2492                 set: function( elem, value, name ) {
2493                         // Set the existing or create a new attribute node
2494                         var ret = elem.getAttributeNode( name );
2495                         if ( !ret ) {
2496                                 ret = document.createAttribute( name );
2497                                 elem.setAttributeNode( ret );
2498                         }
2499                         return (ret.nodeValue = value + "");
2500                 }
2501         };
2502
2503         // Set width and height to auto instead of 0 on empty string( Bug #8150 )
2504         // This is for removals
2505         jQuery.each([ "width", "height" ], function( i, name ) {
2506                 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2507                         set: function( elem, value ) {
2508                                 if ( value === "" ) {
2509                                         elem.setAttribute( name, "auto" );
2510                                         return value;
2511                                 }
2512                         }
2513                 });
2514         });
2515 }
2516
2517
2518 // Some attributes require a special call on IE
2519 if ( !jQuery.support.hrefNormalized ) {
2520         jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
2521                 jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
2522                         get: function( elem ) {
2523                                 var ret = elem.getAttribute( name, 2 );
2524                                 return ret === null ? undefined : ret;
2525                         }
2526                 });
2527         });
2528 }
2529
2530 if ( !jQuery.support.style ) {
2531         jQuery.attrHooks.style = {
2532                 get: function( elem ) {
2533                         // Return undefined in the case of empty string
2534                         // Normalize to lowercase since IE uppercases css property names
2535                         return elem.style.cssText.toLowerCase() || undefined;
2536                 },
2537                 set: function( elem, value ) {
2538                         return (elem.style.cssText = "" + value);
2539                 }
2540         };
2541 }
2542
2543 // Safari mis-reports the default selected property of an option
2544 // Accessing the parent's selectedIndex property fixes it
2545 if ( !jQuery.support.optSelected ) {
2546         jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
2547                 get: function( elem ) {
2548                         var parent = elem.parentNode;
2549
2550                         if ( parent ) {
2551                                 parent.selectedIndex;
2552
2553                                 // Make sure that it also works with optgroups, see #5701
2554                                 if ( parent.parentNode ) {
2555                                         parent.parentNode.selectedIndex;
2556                                 }
2557                         }
2558                         return null;
2559                 }
2560         });
2561 }
2562
2563 // Radios and checkboxes getter/setter
2564 if ( !jQuery.support.checkOn ) {
2565         jQuery.each([ "radio", "checkbox" ], function() {
2566                 jQuery.valHooks[ this ] = {
2567                         get: function( elem ) {
2568                                 // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
2569                                 return elem.getAttribute("value") === null ? "on" : elem.value;
2570                         }
2571                 };
2572         });
2573 }
2574 jQuery.each([ "radio", "checkbox" ], function() {
2575         jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
2576                 set: function( elem, value ) {
2577                         if ( jQuery.isArray( value ) ) {
2578                                 return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
2579                         }
2580                 }
2581         });
2582 });
2583
2584
2585
2586
2587 var rnamespaces = /\.(.*)$/,
2588         rformElems = /^(?:textarea|input|select)$/i,
2589         rperiod = /\./g,
2590         rspaces = / /g,
2591         rescape = /[^\w\s.|`]/g,
2592         fcleanup = function( nm ) {
2593                 return nm.replace(rescape, "\\$&");
2594         };
2595
2596 /*
2597  * A number of helper functions used for managing events.
2598  * Many of the ideas behind this code originated from
2599  * Dean Edwards' addEvent library.
2600  */
2601 jQuery.event = {
2602
2603         // Bind an event to an element
2604         // Original by Dean Edwards
2605         add: function( elem, types, handler, data ) {
2606                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2607                         return;
2608                 }
2609
2610                 if ( handler === false ) {
2611                         handler = returnFalse;
2612                 } else if ( !handler ) {
2613                         // Fixes bug #7229. Fix recommended by jdalton
2614                         return;
2615                 }
2616
2617                 var handleObjIn, handleObj;
2618
2619                 if ( handler.handler ) {
2620                         handleObjIn = handler;
2621                         handler = handleObjIn.handler;
2622                 }
2623
2624                 // Make sure that the function being executed has a unique ID
2625                 if ( !handler.guid ) {
2626                         handler.guid = jQuery.guid++;
2627                 }
2628
2629                 // Init the element's event structure
2630                 var elemData = jQuery._data( elem );
2631
2632                 // If no elemData is found then we must be trying to bind to one of the
2633                 // banned noData elements
2634                 if ( !elemData ) {
2635                         return;
2636                 }
2637
2638                 var events = elemData.events,
2639                         eventHandle = elemData.handle;
2640
2641                 if ( !events ) {
2642                         elemData.events = events = {};
2643                 }
2644
2645                 if ( !eventHandle ) {
2646                         elemData.handle = eventHandle = function( e ) {
2647                                 // Discard the second event of a jQuery.event.trigger() and
2648                                 // when an event is called after a page has unloaded
2649                                 return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
2650                                         jQuery.event.handle.apply( eventHandle.elem, arguments ) :
2651                                         undefined;
2652                         };
2653                 }
2654
2655                 // Add elem as a property of the handle function
2656                 // This is to prevent a memory leak with non-native events in IE.
2657                 eventHandle.elem = elem;
2658
2659                 // Handle multiple events separated by a space
2660                 // jQuery(...).bind("mouseover mouseout", fn);
2661                 types = types.split(" ");
2662
2663                 var type, i = 0, namespaces;
2664
2665                 while ( (type = types[ i++ ]) ) {
2666                         handleObj = handleObjIn ?
2667                                 jQuery.extend({}, handleObjIn) :
2668                                 { handler: handler, data: data };
2669
2670                         // Namespaced event handlers
2671                         if ( type.indexOf(".") > -1 ) {
2672                                 namespaces = type.split(".");
2673                                 type = namespaces.shift();
2674                                 handleObj.namespace = namespaces.slice(0).sort().join(".");
2675
2676                         } else {
2677                                 namespaces = [];
2678                                 handleObj.namespace = "";
2679                         }
2680
2681                         handleObj.type = type;
2682                         if ( !handleObj.guid ) {
2683                                 handleObj.guid = handler.guid;
2684                         }
2685
2686                         // Get the current list of functions bound to this event
2687                         var handlers = events[ type ],
2688                                 special = jQuery.event.special[ type ] || {};
2689
2690                         // Init the event handler queue
2691                         if ( !handlers ) {
2692                                 handlers = events[ type ] = [];
2693
2694                                 // Check for a special event handler
2695                                 // Only use addEventListener/attachEvent if the special
2696                                 // events handler returns false
2697                                 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
2698                                         // Bind the global event handler to the element
2699                                         if ( elem.addEventListener ) {
2700                                                 elem.addEventListener( type, eventHandle, false );
2701
2702                                         } else if ( elem.attachEvent ) {
2703                                                 elem.attachEvent( "on" + type, eventHandle );
2704                                         }
2705                                 }
2706                         }
2707
2708                         if ( special.add ) {
2709                                 special.add.call( elem, handleObj );
2710
2711                                 if ( !handleObj.handler.guid ) {
2712                                         handleObj.handler.guid = handler.guid;
2713                                 }
2714                         }
2715
2716                         // Add the function to the element's handler list
2717                         handlers.push( handleObj );
2718
2719                         // Keep track of which events have been used, for event optimization
2720                         jQuery.event.global[ type ] = true;
2721                 }
2722
2723                 // Nullify elem to prevent memory leaks in IE
2724                 elem = null;
2725         },
2726
2727         global: {},
2728
2729         // Detach an event or set of events from an element
2730         remove: function( elem, types, handler, pos ) {
2731                 // don't do events on text and comment nodes
2732                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2733                         return;
2734                 }
2735
2736                 if ( handler === false ) {
2737                         handler = returnFalse;
2738                 }
2739
2740                 var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
2741                         elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
2742                         events = elemData && elemData.events;
2743
2744                 if ( !elemData || !events ) {
2745                         return;
2746                 }
2747
2748                 // types is actually an event object here
2749                 if ( types && types.type ) {
2750                         handler = types.handler;
2751                         types = types.type;
2752                 }
2753
2754                 // Unbind all events for the element
2755                 if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
2756                         types = types || "";
2757
2758                         for ( type in events ) {
2759                                 jQuery.event.remove( elem, type + types );
2760                         }
2761
2762                         return;
2763                 }
2764
2765                 // Handle multiple events separated by a space
2766                 // jQuery(...).unbind("mouseover mouseout", fn);
2767                 types = types.split(" ");
2768
2769                 while ( (type = types[ i++ ]) ) {
2770                         origType = type;
2771                         handleObj = null;
2772                         all = type.indexOf(".") < 0;
2773                         namespaces = [];
2774
2775                         if ( !all ) {
2776                                 // Namespaced event handlers
2777                                 namespaces = type.split(".");
2778                                 type = namespaces.shift();
2779
2780                                 namespace = new RegExp("(^|\\.)" +
2781                                         jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
2782                         }
2783
2784                         eventType = events[ type ];
2785
2786                         if ( !eventType ) {
2787                                 continue;
2788                         }
2789
2790                         if ( !handler ) {
2791                                 for ( j = 0; j < eventType.length; j++ ) {
2792                                         handleObj = eventType[ j ];
2793
2794                                         if ( all || namespace.test( handleObj.namespace ) ) {
2795                                                 jQuery.event.remove( elem, origType, handleObj.handler, j );
2796                                                 eventType.splice( j--, 1 );
2797                                         }
2798                                 }
2799
2800                                 continue;
2801                         }
2802
2803                         special = jQuery.event.special[ type ] || {};
2804
2805                         for ( j = pos || 0; j < eventType.length; j++ ) {
2806                                 handleObj = eventType[ j ];
2807
2808                                 if ( handler.guid === handleObj.guid ) {
2809                                         // remove the given handler for the given type
2810                                         if ( all || namespace.test( handleObj.namespace ) ) {
2811                                                 if ( pos == null ) {
2812                                                         eventType.splice( j--, 1 );
2813                                                 }
2814
2815                                                 if ( special.remove ) {
2816                                                         special.remove.call( elem, handleObj );
2817                                                 }
2818                                         }
2819
2820                                         if ( pos != null ) {
2821                                                 break;
2822                                         }
2823                                 }
2824                         }
2825
2826                         // remove generic event handler if no more handlers exist
2827                         if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
2828                                 if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
2829                                         jQuery.removeEvent( elem, type, elemData.handle );
2830                                 }
2831
2832                                 ret = null;
2833                                 delete events[ type ];
2834                         }
2835                 }
2836
2837                 // Remove the expando if it's no longer used
2838                 if ( jQuery.isEmptyObject( events ) ) {
2839                         var handle = elemData.handle;
2840                         if ( handle ) {
2841                                 handle.elem = null;
2842                         }
2843
2844                         delete elemData.events;
2845                         delete elemData.handle;
2846
2847                         if ( jQuery.isEmptyObject( elemData ) ) {
2848                                 jQuery.removeData( elem, undefined, true );
2849                         }
2850                 }
2851         },
2852         
2853         // Events that are safe to short-circuit if no handlers are attached.
2854         // Native DOM events should not be added, they may have inline handlers.
2855         customEvent: {
2856                 "getData": true,
2857                 "setData": true,
2858                 "changeData": true
2859         },
2860
2861         trigger: function( event, data, elem, onlyHandlers ) {
2862                 // Event object or event type
2863                 var type = event.type || event,
2864                         namespaces = [],
2865                         exclusive;
2866
2867                 if ( type.indexOf("!") >= 0 ) {
2868                         // Exclusive events trigger only for the exact event (no namespaces)
2869                         type = type.slice(0, -1);
2870                         exclusive = true;
2871                 }
2872
2873                 if ( type.indexOf(".") >= 0 ) {
2874                         // Namespaced trigger; create a regexp to match event type in handle()
2875                         namespaces = type.split(".");
2876                         type = namespaces.shift();
2877                         namespaces.sort();
2878                 }
2879
2880                 if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
2881                         // No jQuery handlers for this event type, and it can't have inline handlers
2882                         return;
2883                 }
2884
2885                 // Caller can pass in an Event, Object, or just an event type string
2886                 event = typeof event === "object" ?
2887                         // jQuery.Event object
2888                         event[ jQuery.expando ] ? event :
2889                         // Object literal
2890                         new jQuery.Event( type, event ) :
2891                         // Just the event type (string)
2892                         new jQuery.Event( type );
2893
2894                 event.type = type;
2895                 event.exclusive = exclusive;
2896                 event.namespace = namespaces.join(".");
2897                 event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
2898                 
2899                 // triggerHandler() and global events don't bubble or run the default action
2900                 if ( onlyHandlers || !elem ) {
2901                         event.preventDefault();
2902                         event.stopPropagation();
2903                 }
2904
2905                 // Handle a global trigger
2906                 if ( !elem ) {
2907                         // TODO: Stop taunting the data cache; remove global events and always attach to document
2908                         jQuery.each( jQuery.cache, function() {
2909                                 // internalKey variable is just used to make it easier to find
2910                                 // and potentially change this stuff later; currently it just
2911                                 // points to jQuery.expando
2912                                 var internalKey = jQuery.expando,
2913                                         internalCache = this[ internalKey ];
2914                                 if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
2915                                         jQuery.event.trigger( event, data, internalCache.handle.elem );
2916                                 }
2917                         });
2918                         return;
2919                 }
2920
2921                 // Don't do events on text and comment nodes
2922                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
2923                         return;
2924                 }
2925
2926                 // Clean up the event in case it is being reused
2927                 event.result = undefined;
2928                 event.target = elem;
2929
2930                 // Clone any incoming data and prepend the event, creating the handler arg list
2931                 data = data != null ? jQuery.makeArray( data ) : [];
2932                 data.unshift( event );
2933
2934                 var cur = elem,
2935                         // IE doesn't like method names with a colon (#3533, #8272)
2936                         ontype = type.indexOf(":") < 0 ? "on" + type : "";
2937
2938                 // Fire event on the current element, then bubble up the DOM tree
2939                 do {
2940                         var handle = jQuery._data( cur, "handle" );
2941
2942                         event.currentTarget = cur;
2943                         if ( handle ) {
2944                                 handle.apply( cur, data );
2945                         }
2946
2947                         // Trigger an inline bound script
2948                         if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
2949                                 event.result = false;
2950                                 event.preventDefault();
2951                         }
2952
2953                         // Bubble up to document, then to window
2954                         cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
2955                 } while ( cur && !event.isPropagationStopped() );
2956
2957                 // If nobody prevented the default action, do it now
2958                 if ( !event.isDefaultPrevented() ) {
2959                         var old,
2960                                 special = jQuery.event.special[ type ] || {};
2961
2962                         if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
2963                                 !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
2964
2965                                 // Call a native DOM method on the target with the same name name as the event.
2966                                 // Can't use an .isFunction)() check here because IE6/7 fails that test.
2967                                 // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
2968                                 try {
2969                                         if ( ontype && elem[ type ] ) {
2970                                                 // Don't re-trigger an onFOO event when we call its FOO() method
2971                                                 old = elem[ ontype ];
2972
2973                                                 if ( old ) {
2974                                                         elem[ ontype ] = null;
2975                                                 }
2976
2977                                                 jQuery.event.triggered = type;
2978                                                 elem[ type ]();
2979                                         }
2980                                 } catch ( ieError ) {}
2981
2982                                 if ( old ) {
2983                                         elem[ ontype ] = old;
2984                                 }
2985
2986                                 jQuery.event.triggered = undefined;
2987                         }
2988                 }
2989                 
2990                 return event.result;
2991         },
2992
2993         handle: function( event ) {
2994                 event = jQuery.event.fix( event || window.event );
2995                 // Snapshot the handlers list since a called handler may add/remove events.
2996                 var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
2997                         run_all = !event.exclusive && !event.namespace,
2998                         args = Array.prototype.slice.call( arguments, 0 );
2999
3000                 // Use the fix-ed Event rather than the (read-only) native event
3001                 args[0] = event;
3002                 event.currentTarget = this;
3003
3004                 for ( var j = 0, l = handlers.length; j < l; j++ ) {
3005                         var handleObj = handlers[ j ];
3006
3007                         // Triggered event must 1) be non-exclusive and have no namespace, or
3008                         // 2) have namespace(s) a subset or equal to those in the bound event.
3009                         if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
3010                                 // Pass in a reference to the handler function itself
3011                                 // So that we can later remove it
3012                                 event.handler = handleObj.handler;
3013                                 event.data = handleObj.data;
3014                                 event.handleObj = handleObj;
3015
3016                                 var ret = handleObj.handler.apply( this, args );
3017
3018                                 if ( ret !== undefined ) {
3019                                         event.result = ret;
3020                                         if ( ret === false ) {
3021                                                 event.preventDefault();
3022                                                 event.stopPropagation();
3023                                         }
3024                                 }
3025
3026                                 if ( event.isImmediatePropagationStopped() ) {
3027                                         break;
3028                                 }
3029                         }
3030                 }
3031                 return event.result;
3032         },
3033
3034         props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
3035
3036         fix: function( event ) {
3037                 if ( event[ jQuery.expando ] ) {
3038                         return event;
3039                 }
3040
3041                 // store a copy of the original event object
3042                 // and "clone" to set read-only properties
3043                 var originalEvent = event;
3044                 event = jQuery.Event( originalEvent );
3045
3046                 for ( var i = this.props.length, prop; i; ) {
3047                         prop = this.props[ --i ];
3048                         event[ prop ] = originalEvent[ prop ];
3049                 }
3050
3051                 // Fix target property, if necessary
3052                 if ( !event.target ) {
3053                         // Fixes #1925 where srcElement might not be defined either
3054                         event.target = event.srcElement || document;
3055                 }
3056
3057                 // check if target is a textnode (safari)
3058                 if ( event.target.nodeType === 3 ) {
3059                         event.target = event.target.parentNode;
3060                 }
3061
3062                 // Add relatedTarget, if necessary
3063                 if ( !event.relatedTarget && event.fromElement ) {
3064                         event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
3065                 }
3066
3067                 // Calculate pageX/Y if missing and clientX/Y available
3068                 if ( event.pageX == null && event.clientX != null ) {
3069                         var eventDocument = event.target.ownerDocument || document,
3070                                 doc = eventDocument.documentElement,
3071                                 body = eventDocument.body;
3072
3073                         event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
3074                         event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
3075                 }
3076
3077                 // Add which for key events
3078                 if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
3079                         event.which = event.charCode != null ? event.charCode : event.keyCode;
3080                 }
3081
3082                 // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
3083                 if ( !event.metaKey && event.ctrlKey ) {
3084                         event.metaKey = event.ctrlKey;
3085                 }
3086
3087                 // Add which for click: 1 === left; 2 === middle; 3 === right
3088                 // Note: button is not normalized, so don't use it
3089                 if ( !event.which && event.button !== undefined ) {
3090                         event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
3091                 }
3092
3093                 return event;
3094         },
3095
3096         // Deprecated, use jQuery.guid instead
3097         guid: 1E8,
3098
3099         // Deprecated, use jQuery.proxy instead
3100         proxy: jQuery.proxy,
3101
3102         special: {
3103                 ready: {
3104                         // Make sure the ready event is setup
3105                         setup: jQuery.bindReady,
3106                         teardown: jQuery.noop
3107                 },
3108
3109                 live: {
3110                         add: function( handleObj ) {
3111                                 jQuery.event.add( this,
3112                                         liveConvert( handleObj.origType, handleObj.selector ),
3113                                         jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
3114                         },
3115
3116                         remove: function( handleObj ) {
3117                                 jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
3118                         }
3119                 },
3120
3121                 beforeunload: {
3122                         setup: function( data, namespaces, eventHandle ) {
3123                                 // We only want to do this special case on windows
3124                                 if ( jQuery.isWindow( this ) ) {
3125                                         this.onbeforeunload = eventHandle;
3126                                 }
3127                         },
3128
3129                         teardown: function( namespaces, eventHandle ) {
3130                                 if ( this.onbeforeunload === eventHandle ) {
3131                                         this.onbeforeunload = null;
3132                                 }
3133                         }
3134                 }
3135         }
3136 };
3137
3138 jQuery.removeEvent = document.removeEventListener ?
3139         function( elem, type, handle ) {
3140                 if ( elem.removeEventListener ) {
3141                         elem.removeEventListener( type, handle, false );
3142                 }
3143         } :
3144         function( elem, type, handle ) {
3145                 if ( elem.detachEvent ) {
3146                         elem.detachEvent( "on" + type, handle );
3147                 }
3148         };
3149
3150 jQuery.Event = function( src, props ) {
3151         // Allow instantiation without the 'new' keyword
3152         if ( !this.preventDefault ) {
3153                 return new jQuery.Event( src, props );
3154         }
3155
3156         // Event object
3157         if ( src && src.type ) {
3158                 this.originalEvent = src;
3159                 this.type = src.type;
3160
3161                 // Events bubbling up the document may have been marked as prevented
3162                 // by a handler lower down the tree; reflect the correct value.
3163                 this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
3164                         src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
3165
3166         // Event type
3167         } else {
3168                 this.type = src;
3169         }
3170
3171         // Put explicitly provided properties onto the event object
3172         if ( props ) {
3173                 jQuery.extend( this, props );
3174         }
3175
3176         // timeStamp is buggy for some events on Firefox(#3843)
3177         // So we won't rely on the native value
3178         this.timeStamp = jQuery.now();
3179
3180         // Mark it as fixed
3181         this[ jQuery.expando ] = true;
3182 };
3183
3184 function returnFalse() {
3185         return false;
3186 }
3187 function returnTrue() {
3188         return true;
3189 }
3190
3191 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
3192 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
3193 jQuery.Event.prototype = {
3194         preventDefault: function() {
3195                 this.isDefaultPrevented = returnTrue;
3196
3197                 var e = this.originalEvent;
3198                 if ( !e ) {
3199                         return;
3200                 }
3201
3202                 // if preventDefault exists run it on the original event
3203                 if ( e.preventDefault ) {
3204                         e.preventDefault();
3205
3206                 // otherwise set the returnValue property of the original event to false (IE)
3207                 } else {
3208                         e.returnValue = false;
3209                 }
3210         },
3211         stopPropagation: function() {
3212                 this.isPropagationStopped = returnTrue;
3213
3214                 var e = this.originalEvent;
3215                 if ( !e ) {
3216                         return;
3217                 }
3218                 // if stopPropagation exists run it on the original event
3219                 if ( e.stopPropagation ) {
3220                         e.stopPropagation();
3221                 }
3222                 // otherwise set the cancelBubble property of the original event to true (IE)
3223                 e.cancelBubble = true;
3224         },
3225         stopImmediatePropagation: function() {
3226                 this.isImmediatePropagationStopped = returnTrue;
3227                 this.stopPropagation();
3228         },
3229         isDefaultPrevented: returnFalse,
3230         isPropagationStopped: returnFalse,
3231         isImmediatePropagationStopped: returnFalse
3232 };
3233
3234 // Checks if an event happened on an element within another element
3235 // Used in jQuery.event.special.mouseenter and mouseleave handlers
3236 var withinElement = function( event ) {
3237
3238         // Check if mouse(over|out) are still within the same parent element
3239         var related = event.relatedTarget,
3240                 inside = false,
3241                 eventType = event.type;
3242
3243         event.type = event.data;
3244
3245         if ( related !== this ) {
3246
3247                 if ( related ) {
3248                         inside = jQuery.contains( this, related );
3249                 }
3250
3251                 if ( !inside ) {
3252
3253                         jQuery.event.handle.apply( this, arguments );
3254
3255                         event.type = eventType;
3256                 }
3257         }
3258 },
3259
3260 // In case of event delegation, we only need to rename the event.type,
3261 // liveHandler will take care of the rest.
3262 delegate = function( event ) {
3263         event.type = event.data;
3264         jQuery.event.handle.apply( this, arguments );
3265 };
3266
3267 // Create mouseenter and mouseleave events
3268 jQuery.each({
3269         mouseenter: "mouseover",
3270         mouseleave: "mouseout"
3271 }, function( orig, fix ) {
3272         jQuery.event.special[ orig ] = {
3273                 setup: function( data ) {
3274                         jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
3275                 },
3276                 teardown: function( data ) {
3277                         jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
3278                 }
3279         };
3280 });
3281
3282 // submit delegation
3283 if ( !jQuery.support.submitBubbles ) {
3284
3285         jQuery.event.special.submit = {
3286                 setup: function( data, namespaces ) {
3287                         if ( !jQuery.nodeName( this, "form" ) ) {
3288                                 jQuery.event.add(this, "click.specialSubmit", function( e ) {
3289                                         var elem = e.target,
3290                                                 type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3291
3292                                         if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
3293                                                 trigger( "submit", this, arguments );
3294                                         }
3295                                 });
3296
3297                                 jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
3298                                         var elem = e.target,
3299                                                 type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3300
3301                                         if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
3302                                                 trigger( "submit", this, arguments );
3303                                         }
3304                                 });
3305
3306                         } else {
3307                                 return false;
3308                         }
3309                 },
3310
3311                 teardown: function( namespaces ) {
3312                         jQuery.event.remove( this, ".specialSubmit" );
3313                 }
3314         };
3315
3316 }
3317
3318 // change delegation, happens here so we have bind.
3319 if ( !jQuery.support.changeBubbles ) {
3320
3321         var changeFilters,
3322
3323         getVal = function( elem ) {
3324                 var type = jQuery.nodeName( elem, "input" ) ? elem.type : "",
3325                         val = elem.value;
3326
3327                 if ( type === "radio" || type === "checkbox" ) {
3328                         val = elem.checked;
3329
3330                 } else if ( type === "select-multiple" ) {
3331                         val = elem.selectedIndex > -1 ?
3332                                 jQuery.map( elem.options, function( elem ) {
3333                                         return elem.selected;
3334                                 }).join("-") :
3335                                 "";
3336
3337                 } else if ( jQuery.nodeName( elem, "select" ) ) {
3338                         val = elem.selectedIndex;
3339                 }
3340
3341                 return val;
3342         },
3343
3344         testChange = function testChange( e ) {
3345                 var elem = e.target, data, val;
3346
3347                 if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
3348                         return;
3349                 }
3350
3351                 data = jQuery._data( elem, "_change_data" );
3352                 val = getVal(elem);
3353
3354                 // the current data will be also retrieved by beforeactivate
3355                 if ( e.type !== "focusout" || elem.type !== "radio" ) {
3356                         jQuery._data( elem, "_change_data", val );
3357                 }
3358
3359                 if ( data === undefined || val === data ) {
3360                         return;
3361                 }
3362
3363                 if ( data != null || val ) {
3364                         e.type = "change";
3365                         e.liveFired = undefined;
3366                         jQuery.event.trigger( e, arguments[1], elem );
3367                 }
3368         };
3369
3370         jQuery.event.special.change = {
3371                 filters: {
3372                         focusout: testChange,
3373
3374                         beforedeactivate: testChange,
3375
3376                         click: function( e ) {
3377                                 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3378
3379                                 if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
3380                                         testChange.call( this, e );
3381                                 }
3382                         },
3383
3384                         // Change has to be called before submit
3385                         // Keydown will be called before keypress, which is used in submit-event delegation
3386                         keydown: function( e ) {
3387                                 var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
3388
3389                                 if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
3390                                         (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
3391                                         type === "select-multiple" ) {
3392                                         testChange.call( this, e );
3393                                 }
3394                         },
3395
3396                         // Beforeactivate happens also before the previous element is blurred
3397                         // with this event you can't trigger a change event, but you can store
3398                         // information
3399                         beforeactivate: function( e ) {
3400                                 var elem = e.target;
3401                                 jQuery._data( elem, "_change_data", getVal(elem) );
3402                         }
3403                 },
3404
3405                 setup: function( data, namespaces ) {
3406                         if ( this.type === "file" ) {
3407                                 return false;
3408                         }
3409
3410                         for ( var type in changeFilters ) {
3411                                 jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
3412                         }
3413
3414                         return rformElems.test( this.nodeName );
3415                 },
3416
3417                 teardown: function( namespaces ) {
3418                         jQuery.event.remove( this, ".specialChange" );
3419
3420                         return rformElems.test( this.nodeName );
3421                 }
3422         };
3423
3424         changeFilters = jQuery.event.special.change.filters;
3425
3426         // Handle when the input is .focus()'d
3427         changeFilters.focus = changeFilters.beforeactivate;
3428 }
3429
3430 function trigger( type, elem, args ) {
3431         // Piggyback on a donor event to simulate a different one.
3432         // Fake originalEvent to avoid donor's stopPropagation, but if the
3433         // simulated event prevents default then we do the same on the donor.
3434         // Don't pass args or remember liveFired; they apply to the donor event.
3435         var event = jQuery.extend( {}, args[ 0 ] );
3436         event.type = type;
3437         event.originalEvent = {};
3438         event.liveFired = undefined;
3439         jQuery.event.handle.call( elem, event );
3440         if ( event.isDefaultPrevented() ) {
3441                 args[ 0 ].preventDefault();
3442         }
3443 }
3444
3445 // Create "bubbling" focus and blur events
3446 if ( !jQuery.support.focusinBubbles ) {
3447         jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
3448
3449                 // Attach a single capturing handler while someone wants focusin/focusout
3450                 var attaches = 0;
3451
3452                 jQuery.event.special[ fix ] = {
3453                         setup: function() {
3454                                 if ( attaches++ === 0 ) {
3455                                         document.addEventListener( orig, handler, true );
3456                                 }
3457                         },
3458                         teardown: function() {
3459                                 if ( --attaches === 0 ) {
3460                                         document.removeEventListener( orig, handler, true );
3461                                 }
3462                         }
3463                 };
3464
3465                 function handler( donor ) {
3466                         // Donor event is always a native one; fix it and switch its type.
3467                         // Let focusin/out handler cancel the donor focus/blur event.
3468                         var e = jQuery.event.fix( donor );
3469                         e.type = fix;
3470                         e.originalEvent = {};
3471                         jQuery.event.trigger( e, null, e.target );
3472                         if ( e.isDefaultPrevented() ) {
3473                                 donor.preventDefault();
3474                         }
3475                 }
3476         });
3477 }
3478
3479 jQuery.each(["bind", "one"], function( i, name ) {
3480         jQuery.fn[ name ] = function( type, data, fn ) {
3481                 var handler;
3482
3483                 // Handle object literals
3484                 if ( typeof type === "object" ) {
3485                         for ( var key in type ) {
3486                                 this[ name ](key, data, type[key], fn);
3487                         }
3488                         return this;
3489                 }
3490
3491                 if ( arguments.length === 2 || data === false ) {
3492                         fn = data;
3493                         data = undefined;
3494                 }
3495
3496                 if ( name === "one" ) {
3497                         handler = function( event ) {
3498                                 jQuery( this ).unbind( event, handler );
3499                                 return fn.apply( this, arguments );
3500                         };
3501                         handler.guid = fn.guid || jQuery.guid++;
3502                 } else {
3503                         handler = fn;
3504                 }
3505
3506                 if ( type === "unload" && name !== "one" ) {
3507                         this.one( type, data, fn );
3508
3509                 } else {
3510                         for ( var i = 0, l = this.length; i < l; i++ ) {
3511                                 jQuery.event.add( this[i], type, handler, data );
3512                         }
3513                 }
3514
3515                 return this;
3516         };
3517 });
3518
3519 jQuery.fn.extend({
3520         unbind: function( type, fn ) {
3521                 // Handle object literals
3522                 if ( typeof type === "object" && !type.preventDefault ) {
3523                         for ( var key in type ) {
3524                                 this.unbind(key, type[key]);
3525                         }
3526
3527                 } else {
3528                         for ( var i = 0, l = this.length; i < l; i++ ) {
3529                                 jQuery.event.remove( this[i], type, fn );
3530                         }
3531                 }
3532
3533                 return this;
3534         },
3535
3536         delegate: function( selector, types, data, fn ) {
3537                 return this.live( types, data, fn, selector );
3538         },
3539
3540         undelegate: function( selector, types, fn ) {
3541                 if ( arguments.length === 0 ) {
3542                         return this.unbind( "live" );
3543
3544                 } else {
3545                         return this.die( types, null, fn, selector );
3546                 }
3547         },
3548
3549         trigger: function( type, data ) {
3550                 return this.each(function() {
3551                         jQuery.event.trigger( type, data, this );
3552                 });
3553         },
3554
3555         triggerHandler: function( type, data ) {
3556                 if ( this[0] ) {
3557                         return jQuery.event.trigger( type, data, this[0], true );
3558                 }
3559         },
3560
3561         toggle: function( fn ) {
3562                 // Save reference to arguments for access in closure
3563                 var args = arguments,
3564                         guid = fn.guid || jQuery.guid++,
3565                         i = 0,
3566                         toggler = function( event ) {
3567                                 // Figure out which function to execute
3568                                 var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
3569                                 jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
3570
3571                                 // Make sure that clicks stop
3572                                 event.preventDefault();
3573
3574                                 // and execute the function
3575                                 return args[ lastToggle ].apply( this, arguments ) || false;
3576                         };
3577
3578                 // link all the functions, so any of them can unbind this click handler
3579                 toggler.guid = guid;
3580                 while ( i < args.length ) {
3581                         args[ i++ ].guid = guid;
3582                 }
3583
3584                 return this.click( toggler );
3585         },
3586
3587         hover: function( fnOver, fnOut ) {
3588                 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
3589         }
3590 });
3591
3592 var liveMap = {
3593         focus: "focusin",
3594         blur: "focusout",
3595         mouseenter: "mouseover",
3596         mouseleave: "mouseout"
3597 };
3598
3599 jQuery.each(["live", "die"], function( i, name ) {
3600         jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
3601                 var type, i = 0, match, namespaces, preType,
3602                         selector = origSelector || this.selector,
3603                         context = origSelector ? this : jQuery( this.context );
3604
3605                 if ( typeof types === "object" && !types.preventDefault ) {
3606                         for ( var key in types ) {
3607                                 context[ name ]( key, data, types[key], selector );
3608                         }
3609
3610                         return this;
3611                 }
3612
3613                 if ( name === "die" && !types &&
3614                                         origSelector && origSelector.charAt(0) === "." ) {
3615
3616                         context.unbind( origSelector );
3617
3618                         return this;
3619                 }
3620
3621                 if ( data === false || jQuery.isFunction( data ) ) {
3622                         fn = data || returnFalse;
3623                         data = undefined;
3624                 }
3625
3626                 types = (types || "").split(" ");
3627
3628                 while ( (type = types[ i++ ]) != null ) {
3629                         match = rnamespaces.exec( type );
3630                         namespaces = "";
3631
3632                         if ( match )  {
3633                                 namespaces = match[0];
3634                                 type = type.replace( rnamespaces, "" );
3635                         }
3636
3637                         if ( type === "hover" ) {
3638                                 types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
3639                                 continue;
3640                         }
3641
3642                         preType = type;
3643
3644                         if ( liveMap[ type ] ) {
3645                                 types.push( liveMap[ type ] + namespaces );
3646                                 type = type + namespaces;
3647
3648                         } else {
3649                                 type = (liveMap[ type ] || type) + namespaces;
3650                         }
3651
3652                         if ( name === "live" ) {
3653                                 // bind live handler
3654                                 for ( var j = 0, l = context.length; j < l; j++ ) {
3655                                         jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
3656                                                 { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
3657                                 }
3658
3659                         } else {
3660                                 // unbind live handler
3661                                 context.unbind( "live." + liveConvert( type, selector ), fn );
3662                         }
3663                 }
3664
3665                 return this;
3666         };
3667 });
3668
3669 function liveHandler( event ) {
3670         var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
3671                 elems = [],
3672                 selectors = [],
3673                 events = jQuery._data( this, "events" );
3674
3675         // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
3676         if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
3677                 return;
3678         }
3679
3680         if ( event.namespace ) {
3681                 namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
3682         }
3683
3684         event.liveFired = this;
3685
3686         var live = events.live.slice(0);
3687
3688         for ( j = 0; j < live.length; j++ ) {
3689                 handleObj = live[j];
3690
3691                 if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
3692                         selectors.push( handleObj.selector );
3693
3694                 } else {
3695                         live.splice( j--, 1 );
3696                 }
3697         }
3698
3699         match = jQuery( event.target ).closest( selectors, event.currentTarget );
3700
3701         for ( i = 0, l = match.length; i < l; i++ ) {
3702                 close = match[i];
3703
3704                 for ( j = 0; j < live.length; j++ ) {
3705                         handleObj = live[j];
3706
3707                         if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
3708                                 elem = close.elem;
3709                                 related = null;
3710
3711                                 // Those two events require additional checking
3712                                 if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
3713                                         event.type = handleObj.preType;
3714                                         related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
3715
3716                                         // Make sure not to accidentally match a child element with the same selector
3717                                         if ( related && jQuery.contains( elem, related ) ) {
3718                                                 related = elem;
3719                                         }
3720                                 }
3721
3722                                 if ( !related || related !== elem ) {
3723                                         elems.push({ elem: elem, handleObj: handleObj, level: close.level });
3724                                 }
3725                         }
3726                 }
3727         }
3728
3729         for ( i = 0, l = elems.length; i < l; i++ ) {
3730                 match = elems[i];
3731
3732                 if ( maxLevel && match.level > maxLevel ) {
3733                         break;
3734                 }
3735
3736                 event.currentTarget = match.elem;
3737                 event.data = match.handleObj.data;
3738                 event.handleObj = match.handleObj;
3739
3740                 ret = match.handleObj.origHandler.apply( match.elem, arguments );
3741
3742                 if ( ret === false || event.isPropagationStopped() ) {
3743                         maxLevel = match.level;
3744
3745                         if ( ret === false ) {
3746                                 stop = false;
3747                         }
3748                         if ( event.isImmediatePropagationStopped() ) {
3749                                 break;
3750                         }
3751                 }
3752         }
3753
3754         return stop;
3755 }
3756
3757 function liveConvert( type, selector ) {
3758         return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
3759 }
3760
3761 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
3762         "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
3763         "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
3764
3765         // Handle event binding
3766         jQuery.fn[ name ] = function( data, fn ) {
3767                 if ( fn == null ) {
3768                         fn = data;
3769                         data = null;
3770                 }
3771
3772                 return arguments.length > 0 ?
3773                         this.bind( name, data, fn ) :
3774                         this.trigger( name );
3775         };
3776
3777         if ( jQuery.attrFn ) {
3778                 jQuery.attrFn[ name ] = true;
3779         }
3780 });
3781
3782
3783
3784 /*!
3785  * Sizzle CSS Selector Engine
3786  *  Copyright 2011, The Dojo Foundation
3787  *  Released under the MIT, BSD, and GPL Licenses.
3788  *  More information: http://sizzlejs.com/
3789  */
3790 (function(){
3791
3792 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3793         done = 0,
3794         toString = Object.prototype.toString,
3795         hasDuplicate = false,
3796         baseHasDuplicate = true,
3797         rBackslash = /\\/g,
3798         rNonWord = /\W/;
3799
3800 // Here we check if the JavaScript engine is using some sort of
3801 // optimization where it does not always call our comparision
3802 // function. If that is the case, discard the hasDuplicate value.
3803 //   Thus far that includes Google Chrome.
3804 [0, 0].sort(function() {
3805         baseHasDuplicate = false;
3806         return 0;
3807 });
3808
3809 var Sizzle = function( selector, context, results, seed ) {
3810         results = results || [];
3811         context = context || document;
3812
3813         var origContext = context;
3814
3815         if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3816                 return [];
3817         }
3818         
3819         if ( !selector || typeof selector !== "string" ) {
3820                 return results;
3821         }
3822
3823         var m, set, checkSet, extra, ret, cur, pop, i,
3824                 prune = true,
3825                 contextXML = Sizzle.isXML( context ),
3826                 parts = [],
3827                 soFar = selector;
3828         
3829         // Reset the position of the chunker regexp (start from head)
3830         do {
3831                 chunker.exec( "" );
3832                 m = chunker.exec( soFar );
3833
3834                 if ( m ) {
3835                         soFar = m[3];
3836                 
3837                         parts.push( m[1] );
3838                 
3839                         if ( m[2] ) {
3840                                 extra = m[3];
3841                                 break;
3842                         }
3843                 }
3844         } while ( m );
3845
3846         if ( parts.length > 1 && origPOS.exec( selector ) ) {
3847
3848                 if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
3849                         set = posProcess( parts[0] + parts[1], context );
3850
3851                 } else {
3852                         set = Expr.relative[ parts[0] ] ?
3853                                 [ context ] :
3854                                 Sizzle( parts.shift(), context );
3855
3856                         while ( parts.length ) {
3857                                 selector = parts.shift();
3858
3859                                 if ( Expr.relative[ selector ] ) {
3860                                         selector += parts.shift();
3861                                 }
3862                                 
3863                                 set = posProcess( selector, set );
3864                         }
3865                 }
3866
3867         } else {
3868                 // Take a shortcut and set the context if the root selector is an ID
3869                 // (but not if it'll be faster if the inner selector is an ID)
3870                 if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
3871                                 Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
3872
3873                         ret = Sizzle.find( parts.shift(), context, contextXML );
3874                         context = ret.expr ?
3875                                 Sizzle.filter( ret.expr, ret.set )[0] :
3876                                 ret.set[0];
3877                 }
3878
3879                 if ( context ) {
3880                         ret = seed ?
3881                                 { expr: parts.pop(), set: makeArray(seed) } :
3882                                 Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
3883
3884                         set = ret.expr ?
3885                                 Sizzle.filter( ret.expr, ret.set ) :
3886                                 ret.set;
3887
3888                         if ( parts.length > 0 ) {
3889                                 checkSet = makeArray( set );
3890
3891                         } else {
3892                                 prune = false;
3893                         }
3894
3895                         while ( parts.length ) {
3896                                 cur = parts.pop();
3897                                 pop = cur;
3898
3899                                 if ( !Expr.relative[ cur ] ) {
3900                                         cur = "";
3901                                 } else {
3902                                         pop = parts.pop();
3903                                 }
3904
3905                                 if ( pop == null ) {
3906                                         pop = context;
3907                                 }
3908
3909                                 Expr.relative[ cur ]( checkSet, pop, contextXML );
3910                         }
3911
3912                 } else {
3913                         checkSet = parts = [];
3914                 }
3915         }
3916
3917         if ( !checkSet ) {
3918                 checkSet = set;
3919         }
3920
3921         if ( !checkSet ) {
3922                 Sizzle.error( cur || selector );
3923         }
3924
3925         if ( toString.call(checkSet) === "[object Array]" ) {
3926                 if ( !prune ) {
3927                         results.push.apply( results, checkSet );
3928
3929                 } else if ( context && context.nodeType === 1 ) {
3930                         for ( i = 0; checkSet[i] != null; i++ ) {
3931                                 if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
3932                                         results.push( set[i] );
3933                                 }
3934                         }
3935
3936                 } else {
3937                         for ( i = 0; checkSet[i] != null; i++ ) {
3938                                 if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
3939                                         results.push( set[i] );
3940                                 }
3941                         }
3942                 }
3943
3944         } else {
3945                 makeArray( checkSet, results );
3946         }
3947
3948         if ( extra ) {
3949                 Sizzle( extra, origContext, results, seed );
3950                 Sizzle.uniqueSort( results );
3951         }
3952
3953         return results;
3954 };
3955
3956 Sizzle.uniqueSort = function( results ) {
3957         if ( sortOrder ) {
3958                 hasDuplicate = baseHasDuplicate;
3959                 results.sort( sortOrder );
3960
3961                 if ( hasDuplicate ) {
3962                         for ( var i = 1; i < results.length; i++ ) {
3963                                 if ( results[i] === results[ i - 1 ] ) {
3964                                         results.splice( i--, 1 );
3965                                 }
3966                         }
3967                 }
3968         }
3969
3970         return results;
3971 };
3972
3973 Sizzle.matches = function( expr, set ) {
3974         return Sizzle( expr, null, null, set );
3975 };
3976
3977 Sizzle.matchesSelector = function( node, expr ) {
3978         return Sizzle( expr, null, null, [node] ).length > 0;
3979 };
3980
3981 Sizzle.find = function( expr, context, isXML ) {
3982         var set;
3983
3984         if ( !expr ) {
3985                 return [];
3986         }
3987
3988         for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
3989                 var match,
3990                         type = Expr.order[i];
3991                 
3992                 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
3993                         var left = match[1];
3994                         match.splice( 1, 1 );
3995
3996                         if ( left.substr( left.length - 1 ) !== "\\" ) {
3997                                 match[1] = (match[1] || "").replace( rBackslash, "" );
3998                                 set = Expr.find[ type ]( match, context, isXML );
3999
4000                                 if ( set != null ) {
4001                                         expr = expr.replace( Expr.match[ type ], "" );
4002                                         break;
4003                                 }
4004                         }
4005                 }
4006         }
4007
4008         if ( !set ) {
4009                 set = typeof context.getElementsByTagName !== "undefined" ?
4010                         context.getElementsByTagName( "*" ) :
4011                         [];
4012         }
4013
4014         return { set: set, expr: expr };
4015 };
4016
4017 Sizzle.filter = function( expr, set, inplace, not ) {
4018         var match, anyFound,
4019                 old = expr,
4020                 result = [],
4021                 curLoop = set,
4022                 isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
4023
4024         while ( expr && set.length ) {
4025                 for ( var type in Expr.filter ) {
4026                         if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
4027                                 var found, item,
4028                                         filter = Expr.filter[ type ],
4029                                         left = match[1];
4030
4031                                 anyFound = false;
4032
4033                                 match.splice(1,1);
4034
4035                                 if ( left.substr( left.length - 1 ) === "\\" ) {
4036                                         continue;
4037                                 }
4038
4039                                 if ( curLoop === result ) {
4040                                         result = [];
4041                                 }
4042
4043                                 if ( Expr.preFilter[ type ] ) {
4044                                         match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4045
4046                                         if ( !match ) {
4047                                                 anyFound = found = true;
4048
4049                                         } else if ( match === true ) {
4050                                                 continue;
4051                                         }
4052                                 }
4053
4054                                 if ( match ) {
4055                                         for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
4056                                                 if ( item ) {
4057                                                         found = filter( item, match, i, curLoop );
4058                                                         var pass = not ^ !!found;
4059
4060                                                         if ( inplace && found != null ) {
4061                                                                 if ( pass ) {
4062                                                                         anyFound = true;
4063
4064                                                                 } else {
4065                                                                         curLoop[i] = false;
4066                                                                 }
4067
4068                                                         } else if ( pass ) {
4069                                                                 result.push( item );
4070                                                                 anyFound = true;
4071                                                         }
4072                                                 }
4073                                         }
4074                                 }
4075
4076                                 if ( found !== undefined ) {
4077                                         if ( !inplace ) {
4078                                                 curLoop = result;
4079                                         }
4080
4081                                         expr = expr.replace( Expr.match[ type ], "" );
4082
4083                                         if ( !anyFound ) {
4084                                                 return [];
4085                                         }
4086
4087                                         break;
4088                                 }
4089                         }
4090                 }
4091
4092                 // Improper expression
4093                 if ( expr === old ) {
4094                         if ( anyFound == null ) {
4095                                 Sizzle.error( expr );
4096
4097                         } else {
4098                                 break;
4099                         }
4100                 }
4101
4102                 old = expr;
4103         }
4104
4105         return curLoop;
4106 };
4107
4108 Sizzle.error = function( msg ) {
4109         throw "Syntax error, unrecognized expression: " + msg;
4110 };
4111
4112 var Expr = Sizzle.selectors = {
4113         order: [ "ID", "NAME", "TAG" ],
4114
4115         match: {
4116                 ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4117                 CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4118                 NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4119                 ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4120                 TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4121                 CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4122                 POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4123                 PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4124         },
4125
4126         leftMatch: {},
4127
4128         attrMap: {
4129                 "class": "className",
4130                 "for": "htmlFor"
4131         },
4132
4133         attrHandle: {
4134                 href: function( elem ) {
4135                         return elem.getAttribute( "href" );
4136                 },
4137                 type: function( elem ) {
4138                         return elem.getAttribute( "type" );
4139                 }
4140         },
4141
4142         relative: {
4143                 "+": function(checkSet, part){
4144                         var isPartStr = typeof part === "string",
4145                                 isTag = isPartStr && !rNonWord.test( part ),
4146                                 isPartStrNotTag = isPartStr && !isTag;
4147
4148                         if ( isTag ) {
4149                                 part = part.toLowerCase();
4150                         }
4151
4152                         for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4153                                 if ( (elem = checkSet[i]) ) {
4154                                         while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4155
4156                                         checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4157                                                 elem || false :
4158                                                 elem === part;
4159                                 }
4160                         }
4161
4162                         if ( isPartStrNotTag ) {
4163                                 Sizzle.filter( part, checkSet, true );
4164                         }
4165                 },
4166
4167                 ">": function( checkSet, part ) {
4168                         var elem,
4169                                 isPartStr = typeof part === "string",
4170                                 i = 0,
4171                                 l = checkSet.length;
4172
4173                         if ( isPartStr && !rNonWord.test( part ) ) {
4174                                 part = part.toLowerCase();
4175
4176                                 for ( ; i < l; i++ ) {
4177                                         elem = checkSet[i];
4178
4179                                         if ( elem ) {
4180                                                 var parent = elem.parentNode;
4181                                                 checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4182                                         }
4183                                 }
4184
4185                         } else {
4186                                 for ( ; i < l; i++ ) {
4187                                         elem = checkSet[i];
4188
4189                                         if ( elem ) {
4190                                                 checkSet[i] = isPartStr ?
4191                                                         elem.parentNode :
4192                                                         elem.parentNode === part;
4193                                         }
4194                                 }
4195
4196                                 if ( isPartStr ) {
4197                                         Sizzle.filter( part, checkSet, true );
4198                                 }
4199                         }
4200                 },
4201
4202                 "": function(checkSet, part, isXML){
4203                         var nodeCheck,
4204                                 doneName = done++,
4205                                 checkFn = dirCheck;
4206
4207                         if ( typeof part === "string" && !rNonWord.test( part ) ) {
4208                                 part = part.toLowerCase();
4209                                 nodeCheck = part;
4210                                 checkFn = dirNodeCheck;
4211                         }
4212
4213                         checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4214                 },
4215
4216                 "~": function( checkSet, part, isXML ) {
4217                         var nodeCheck,
4218                                 doneName = done++,
4219                                 checkFn = dirCheck;
4220
4221                         if ( typeof part === "string" && !rNonWord.test( part ) ) {
4222                                 part = part.toLowerCase();
4223                                 nodeCheck = part;
4224                                 checkFn = dirNodeCheck;
4225                         }
4226
4227                         checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4228                 }
4229         },
4230
4231         find: {
4232                 ID: function( match, context, isXML ) {
4233                         if ( typeof context.getElementById !== "undefined" && !isXML ) {
4234                                 var m = context.getElementById(match[1]);
4235                                 // Check parentNode to catch when Blackberry 4.6 returns
4236                                 // nodes that are no longer in the document #6963
4237                                 return m && m.parentNode ? [m] : [];
4238                         }
4239                 },
4240
4241                 NAME: function( match, context ) {
4242                         if ( typeof context.getElementsByName !== "undefined" ) {
4243                                 var ret = [],
4244                                         results = context.getElementsByName( match[1] );
4245
4246                                 for ( var i = 0, l = results.length; i < l; i++ ) {
4247                                         if ( results[i].getAttribute("name") === match[1] ) {
4248                                                 ret.push( results[i] );
4249                                         }
4250                                 }
4251
4252                                 return ret.length === 0 ? null : ret;
4253                         }
4254                 },
4255
4256                 TAG: function( match, context ) {
4257                         if ( typeof context.getElementsByTagName !== "undefined" ) {
4258                                 return context.getElementsByTagName( match[1] );
4259                         }
4260                 }
4261         },
4262         preFilter: {
4263                 CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4264                         match = " " + match[1].replace( rBackslash, "" ) + " ";
4265
4266                         if ( isXML ) {
4267                                 return match;
4268                         }
4269
4270                         for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4271                                 if ( elem ) {
4272                                         if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4273                                                 if ( !inplace ) {
4274                                                         result.push( elem );
4275                                                 }
4276
4277                                         } else if ( inplace ) {
4278                                                 curLoop[i] = false;
4279                                         }
4280                                 }
4281                         }
4282
4283                         return false;
4284                 },
4285
4286                 ID: function( match ) {
4287                         return match[1].replace( rBackslash, "" );
4288                 },
4289
4290                 TAG: function( match, curLoop ) {
4291                         return match[1].replace( rBackslash, "" ).toLowerCase();
4292                 },
4293
4294                 CHILD: function( match ) {
4295                         if ( match[1] === "nth" ) {
4296                                 if ( !match[2] ) {
4297                                         Sizzle.error( match[0] );
4298                                 }
4299
4300                                 match[2] = match[2].replace(/^\+|\s*/g, '');
4301
4302                                 // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
4303                                 var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4304                                         match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4305                                         !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4306
4307                                 // calculate the numbers (first)n+(last) including if they are negative
4308                                 match[2] = (test[1] + (test[2] || 1)) - 0;
4309                                 match[3] = test[3] - 0;
4310                         }
4311                         else if ( match[2] ) {
4312                                 Sizzle.error( match[0] );
4313                         }
4314
4315                         // TODO: Move to normal caching system
4316                         match[0] = done++;
4317
4318                         return match;
4319                 },
4320
4321                 ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4322                         var name = match[1] = match[1].replace( rBackslash, "" );
4323                         
4324                         if ( !isXML && Expr.attrMap[name] ) {
4325                                 match[1] = Expr.attrMap[name];
4326                         }
4327
4328                         // Handle if an un-quoted value was used
4329                         match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4330
4331                         if ( match[2] === "~=" ) {
4332                                 match[4] = " " + match[4] + " ";
4333                         }
4334
4335                         return match;
4336                 },
4337
4338                 PSEUDO: function( match, curLoop, inplace, result, not ) {
4339                         if ( match[1] === "not" ) {
4340                                 // If we're dealing with a complex expression, or a simple one
4341                                 if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4342                                         match[3] = Sizzle(match[3], null, null, curLoop);
4343
4344                                 } else {
4345                                         var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4346
4347                                         if ( !inplace ) {
4348                                                 result.push.apply( result, ret );
4349                                         }
4350
4351                                         return false;
4352                                 }
4353
4354                         } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4355                                 return true;
4356                         }
4357                         
4358                         return match;
4359                 },
4360
4361                 POS: function( match ) {
4362                         match.unshift( true );
4363
4364                         return match;
4365                 }
4366         },
4367         
4368         filters: {
4369                 enabled: function( elem ) {
4370                         return elem.disabled === false && elem.type !== "hidden";
4371                 },
4372
4373                 disabled: function( elem ) {
4374                         return elem.disabled === true;
4375                 },
4376
4377                 checked: function( elem ) {
4378                         return elem.checked === true;
4379                 },
4380                 
4381                 selected: function( elem ) {
4382                         // Accessing this property makes selected-by-default
4383                         // options in Safari work properly
4384                         if ( elem.parentNode ) {
4385                                 elem.parentNode.selectedIndex;
4386                         }
4387                         
4388                         return elem.selected === true;
4389                 },
4390
4391                 parent: function( elem ) {
4392                         return !!elem.firstChild;
4393                 },
4394
4395                 empty: function( elem ) {
4396                         return !elem.firstChild;
4397                 },
4398
4399                 has: function( elem, i, match ) {
4400                         return !!Sizzle( match[3], elem ).length;
4401                 },
4402
4403                 header: function( elem ) {
4404                         return (/h\d/i).test( elem.nodeName );
4405                 },
4406
4407                 text: function( elem ) {
4408                         var attr = elem.getAttribute( "type" ), type = elem.type;
4409                         // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) 
4410                         // use getAttribute instead to test this case
4411                         return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
4412                 },
4413
4414                 radio: function( elem ) {
4415                         return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
4416                 },
4417
4418                 checkbox: function( elem ) {
4419                         return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
4420                 },
4421
4422                 file: function( elem ) {
4423                         return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
4424                 },
4425
4426                 password: function( elem ) {
4427                         return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
4428                 },
4429
4430                 submit: function( elem ) {
4431                         var name = elem.nodeName.toLowerCase();
4432                         return (name === "input" || name === "button") && "submit" === elem.type;
4433                 },
4434
4435                 image: function( elem ) {
4436                         return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
4437                 },
4438
4439                 reset: function( elem ) {
4440                         var name = elem.nodeName.toLowerCase();
4441                         return (name === "input" || name === "button") && "reset" === elem.type;
4442                 },
4443
4444                 button: function( elem ) {
4445                         var name = elem.nodeName.toLowerCase();
4446                         return name === "input" && "button" === elem.type || name === "button";
4447                 },
4448
4449                 input: function( elem ) {
4450                         return (/input|select|textarea|button/i).test( elem.nodeName );
4451                 },
4452
4453                 focus: function( elem ) {
4454                         return elem === elem.ownerDocument.activeElement;
4455                 }
4456         },
4457         setFilters: {
4458                 first: function( elem, i ) {
4459                         return i === 0;
4460                 },
4461
4462                 last: function( elem, i, match, array ) {
4463                         return i === array.length - 1;
4464                 },
4465
4466                 even: function( elem, i ) {
4467                         return i % 2 === 0;
4468                 },
4469
4470                 odd: function( elem, i ) {
4471                         return i % 2 === 1;
4472                 },
4473
4474                 lt: function( elem, i, match ) {
4475                         return i < match[3] - 0;
4476                 },
4477
4478                 gt: function( elem, i, match ) {
4479                         return i > match[3] - 0;
4480                 },
4481
4482                 nth: function( elem, i, match ) {
4483                         return match[3] - 0 === i;
4484                 },
4485
4486                 eq: function( elem, i, match ) {
4487                         return match[3] - 0 === i;
4488                 }
4489         },
4490         filter: {
4491                 PSEUDO: function( elem, match, i, array ) {
4492                         var name = match[1],
4493                                 filter = Expr.filters[ name ];
4494
4495                         if ( filter ) {
4496                                 return filter( elem, i, match, array );
4497
4498                         } else if ( name === "contains" ) {
4499                                 return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
4500
4501                         } else if ( name === "not" ) {
4502                                 var not = match[3];
4503
4504                                 for ( var j = 0, l = not.length; j < l; j++ ) {
4505                                         if ( not[j] === elem ) {
4506                                                 return false;
4507                                         }
4508                                 }
4509
4510                                 return true;
4511
4512                         } else {
4513                                 Sizzle.error( name );
4514                         }
4515                 },
4516
4517                 CHILD: function( elem, match ) {
4518                         var type = match[1],
4519                                 node = elem;
4520
4521                         switch ( type ) {
4522                                 case "only":
4523                                 case "first":
4524                                         while ( (node = node.previousSibling) )  {
4525                                                 if ( node.nodeType === 1 ) { 
4526                                                         return false; 
4527                                                 }
4528                                         }
4529
4530                                         if ( type === "first" ) { 
4531                                                 return true; 
4532                                         }
4533
4534                                         node = elem;
4535
4536                                 case "last":
4537                                         while ( (node = node.nextSibling) )      {
4538                                                 if ( node.nodeType === 1 ) { 
4539                                                         return false; 
4540                                                 }
4541                                         }
4542
4543                                         return true;
4544
4545                                 case "nth":
4546                                         var first = match[2],
4547                                                 last = match[3];
4548
4549                                         if ( first === 1 && last === 0 ) {
4550                                                 return true;
4551                                         }
4552                                         
4553                                         var doneName = match[0],
4554                                                 parent = elem.parentNode;
4555         
4556                                         if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4557                                                 var count = 0;
4558                                                 
4559                                                 for ( node = parent.firstChild; node; node = node.nextSibling ) {
4560                                                         if ( node.nodeType === 1 ) {
4561                                                                 node.nodeIndex = ++count;
4562                                                         }
4563                                                 } 
4564
4565                                                 parent.sizcache = doneName;
4566                                         }
4567                                         
4568                                         var diff = elem.nodeIndex - last;
4569
4570                                         if ( first === 0 ) {
4571                                                 return diff === 0;
4572
4573                                         } else {
4574                                                 return ( diff % first === 0 && diff / first >= 0 );
4575                                         }
4576                         }
4577                 },
4578
4579                 ID: function( elem, match ) {
4580                         return elem.nodeType === 1 && elem.getAttribute("id") === match;
4581                 },
4582
4583                 TAG: function( elem, match ) {
4584                         return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
4585                 },
4586                 
4587                 CLASS: function( elem, match ) {
4588                         return (" " + (elem.className || elem.getAttribute("class")) + " ")
4589                                 .indexOf( match ) > -1;
4590                 },
4591
4592                 ATTR: function( elem, match ) {
4593                         var name = match[1],
4594                                 result = Expr.attrHandle[ name ] ?
4595                                         Expr.attrHandle[ name ]( elem ) :
4596                                         elem[ name ] != null ?
4597                                                 elem[ name ] :
4598                                                 elem.getAttribute( name ),
4599                                 value = result + "",
4600                                 type = match[2],
4601                                 check = match[4];
4602
4603                         return result == null ?
4604                                 type === "!=" :
4605                                 type === "=" ?
4606                                 value === check :
4607                                 type === "*=" ?
4608                                 value.indexOf(check) >= 0 :
4609                                 type === "~=" ?
4610                                 (" " + value + " ").indexOf(check) >= 0 :
4611                                 !check ?
4612                                 value && result !== false :
4613                                 type === "!=" ?
4614                                 value !== check :
4615                                 type === "^=" ?
4616                                 value.indexOf(check) === 0 :
4617                                 type === "$=" ?
4618                                 value.substr(value.length - check.length) === check :
4619                                 type === "|=" ?
4620                                 value === check || value.substr(0, check.length + 1) === check + "-" :
4621                                 false;
4622                 },
4623
4624                 POS: function( elem, match, i, array ) {
4625                         var name = match[2],
4626                                 filter = Expr.setFilters[ name ];
4627
4628                         if ( filter ) {
4629                                 return filter( elem, i, match, array );
4630                         }
4631                 }
4632         }
4633 };
4634
4635 var origPOS = Expr.match.POS,
4636         fescape = function(all, num){
4637                 return "\\" + (num - 0 + 1);
4638         };
4639
4640 for ( var type in Expr.match ) {
4641         Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
4642         Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
4643 }
4644
4645 var makeArray = function( array, results ) {
4646         array = Array.prototype.slice.call( array, 0 );
4647
4648         if ( results ) {
4649                 results.push.apply( results, array );
4650                 return results;
4651         }
4652         
4653         return array;
4654 };
4655
4656 // Perform a simple check to determine if the browser is capable of
4657 // converting a NodeList to an array using builtin methods.
4658 // Also verifies that the returned array holds DOM nodes
4659 // (which is not the case in the Blackberry browser)
4660 try {
4661         Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
4662
4663 // Provide a fallback method if it does not work
4664 } catch( e ) {
4665         makeArray = function( array, results ) {
4666                 var i = 0,
4667                         ret = results || [];
4668
4669                 if ( toString.call(array) === "[object Array]" ) {
4670                         Array.prototype.push.apply( ret, array );
4671
4672                 } else {
4673                         if ( typeof array.length === "number" ) {
4674                                 for ( var l = array.length; i < l; i++ ) {
4675                                         ret.push( array[i] );
4676                                 }
4677
4678                         } else {
4679                                 for ( ; array[i]; i++ ) {
4680                                         ret.push( array[i] );
4681                                 }
4682                         }
4683                 }
4684
4685                 return ret;
4686         };
4687 }
4688
4689 var sortOrder, siblingCheck;
4690
4691 if ( document.documentElement.compareDocumentPosition ) {
4692         sortOrder = function( a, b ) {
4693                 if ( a === b ) {
4694                         hasDuplicate = true;
4695                         return 0;
4696                 }
4697
4698                 if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4699                         return a.compareDocumentPosition ? -1 : 1;
4700                 }
4701
4702                 return a.compareDocumentPosition(b) & 4 ? -1 : 1;
4703         };
4704
4705 } else {
4706         sortOrder = function( a, b ) {
4707                 // The nodes are identical, we can exit early
4708                 if ( a === b ) {
4709                         hasDuplicate = true;
4710                         return 0;
4711
4712                 // Fallback to using sourceIndex (in IE) if it's available on both nodes
4713                 } else if ( a.sourceIndex && b.sourceIndex ) {
4714                         return a.sourceIndex - b.sourceIndex;
4715                 }
4716
4717                 var al, bl,
4718                         ap = [],
4719                         bp = [],
4720                         aup = a.parentNode,
4721                         bup = b.parentNode,
4722                         cur = aup;
4723
4724                 // If the nodes are siblings (or identical) we can do a quick check
4725                 if ( aup === bup ) {
4726                         return siblingCheck( a, b );
4727
4728                 // If no parents were found then the nodes are disconnected
4729                 } else if ( !aup ) {
4730                         return -1;
4731
4732                 } else if ( !bup ) {
4733                         return 1;
4734                 }
4735
4736                 // Otherwise they're somewhere else in the tree so we need
4737                 // to build up a full list of the parentNodes for comparison
4738                 while ( cur ) {
4739                         ap.unshift( cur );
4740                         cur = cur.parentNode;
4741                 }
4742
4743                 cur = bup;
4744
4745                 while ( cur ) {
4746                         bp.unshift( cur );
4747                         cur = cur.parentNode;
4748                 }
4749
4750                 al = ap.length;
4751                 bl = bp.length;
4752
4753                 // Start walking down the tree looking for a discrepancy
4754                 for ( var i = 0; i < al && i < bl; i++ ) {
4755                         if ( ap[i] !== bp[i] ) {
4756                                 return siblingCheck( ap[i], bp[i] );
4757                         }
4758                 }
4759
4760                 // We ended someplace up the tree so do a sibling check
4761                 return i === al ?
4762                         siblingCheck( a, bp[i], -1 ) :
4763                         siblingCheck( ap[i], b, 1 );
4764         };
4765
4766         siblingCheck = function( a, b, ret ) {
4767                 if ( a === b ) {
4768                         return ret;
4769                 }
4770
4771                 var cur = a.nextSibling;
4772
4773                 while ( cur ) {
4774                         if ( cur === b ) {
4775                                 return -1;
4776                         }
4777
4778                         cur = cur.nextSibling;
4779                 }
4780
4781                 return 1;
4782         };
4783 }
4784
4785 // Utility function for retreiving the text value of an array of DOM nodes
4786 Sizzle.getText = function( elems ) {
4787         var ret = "", elem;
4788
4789         for ( var i = 0; elems[i]; i++ ) {
4790                 elem = elems[i];
4791
4792                 // Get the text from text nodes and CDATA nodes
4793                 if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
4794                         ret += elem.nodeValue;
4795
4796                 // Traverse everything else, except comment nodes
4797                 } else if ( elem.nodeType !== 8 ) {
4798                         ret += Sizzle.getText( elem.childNodes );
4799                 }
4800         }
4801
4802         return ret;
4803 };
4804
4805 // Check to see if the browser returns elements by name when
4806 // querying by getElementById (and provide a workaround)
4807 (function(){
4808         // We're going to inject a fake input element with a specified name
4809         var form = document.createElement("div"),
4810                 id = "script" + (new Date()).getTime(),
4811                 root = document.documentElement;
4812
4813         form.innerHTML = "<a name='" + id + "'/>";
4814
4815         // Inject it into the root element, check its status, and remove it quickly
4816         root.insertBefore( form, root.firstChild );
4817
4818         // The workaround has to do additional checks after a getElementById
4819         // Which slows things down for other browsers (hence the branching)
4820         if ( document.getElementById( id ) ) {
4821                 Expr.find.ID = function( match, context, isXML ) {
4822                         if ( typeof context.getElementById !== "undefined" && !isXML ) {
4823                                 var m = context.getElementById(match[1]);
4824
4825                                 return m ?
4826                                         m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
4827                                                 [m] :
4828                                                 undefined :
4829                                         [];
4830                         }
4831                 };
4832
4833                 Expr.filter.ID = function( elem, match ) {
4834                         var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4835
4836                         return elem.nodeType === 1 && node && node.nodeValue === match;
4837                 };
4838         }
4839
4840         root.removeChild( form );
4841
4842         // release memory in IE
4843         root = form = null;
4844 })();
4845
4846 (function(){
4847         // Check to see if the browser returns only elements
4848         // when doing getElementsByTagName("*")
4849
4850         // Create a fake element
4851         var div = document.createElement("div");
4852         div.appendChild( document.createComment("") );
4853
4854         // Make sure no comments are found
4855         if ( div.getElementsByTagName("*").length > 0 ) {
4856                 Expr.find.TAG = function( match, context ) {
4857                         var results = context.getElementsByTagName( match[1] );
4858
4859                         // Filter out possible comments
4860                         if ( match[1] === "*" ) {
4861                                 var tmp = [];
4862
4863                                 for ( var i = 0; results[i]; i++ ) {
4864                                         if ( results[i].nodeType === 1 ) {
4865                                                 tmp.push( results[i] );
4866                                         }
4867                                 }
4868
4869                                 results = tmp;
4870                         }
4871
4872                         return results;
4873                 };
4874         }
4875
4876         // Check to see if an attribute returns normalized href attributes
4877         div.innerHTML = "<a href='#'></a>";
4878
4879         if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4880                         div.firstChild.getAttribute("href") !== "#" ) {
4881
4882                 Expr.attrHandle.href = function( elem ) {
4883                         return elem.getAttribute( "href", 2 );
4884                 };
4885         }
4886
4887         // release memory in IE
4888         div = null;
4889 })();
4890
4891 if ( document.querySelectorAll ) {
4892         (function(){
4893                 var oldSizzle = Sizzle,
4894                         div = document.createElement("div"),
4895                         id = "__sizzle__";
4896
4897                 div.innerHTML = "<p class='TEST'></p>";
4898
4899                 // Safari can't handle uppercase or unicode characters when
4900                 // in quirks mode.
4901                 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4902                         return;
4903                 }
4904         
4905                 Sizzle = function( query, context, extra, seed ) {
4906                         context = context || document;
4907
4908                         // Only use querySelectorAll on non-XML documents
4909                         // (ID selectors don't work in non-HTML documents)
4910                         if ( !seed && !Sizzle.isXML(context) ) {
4911                                 // See if we find a selector to speed up
4912                                 var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
4913                                 
4914                                 if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
4915                                         // Speed-up: Sizzle("TAG")
4916                                         if ( match[1] ) {
4917                                                 return makeArray( context.getElementsByTagName( query ), extra );
4918                                         
4919                                         // Speed-up: Sizzle(".CLASS")
4920                                         } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
4921                                                 return makeArray( context.getElementsByClassName( match[2] ), extra );
4922                                         }
4923                                 }
4924                                 
4925                                 if ( context.nodeType === 9 ) {
4926                                         // Speed-up: Sizzle("body")
4927                                         // The body element only exists once, optimize finding it
4928                                         if ( query === "body" && context.body ) {
4929                                                 return makeArray( [ context.body ], extra );
4930                                                 
4931                                         // Speed-up: Sizzle("#ID")
4932                                         } else if ( match && match[3] ) {
4933                                                 var elem = context.getElementById( match[3] );
4934
4935                                                 // Check parentNode to catch when Blackberry 4.6 returns
4936                                                 // nodes that are no longer in the document #6963
4937                                                 if ( elem && elem.parentNode ) {
4938                                                         // Handle the case where IE and Opera return items
4939                                                         // by name instead of ID
4940                                                         if ( elem.id === match[3] ) {
4941                                                                 return makeArray( [ elem ], extra );
4942                                                         }
4943                                                         
4944                                                 } else {
4945                                                         return makeArray( [], extra );
4946                                                 }
4947                                         }
4948                                         
4949                                         try {
4950                                                 return makeArray( context.querySelectorAll(query), extra );
4951                                         } catch(qsaError) {}
4952
4953                                 // qSA works strangely on Element-rooted queries
4954                                 // We can work around this by specifying an extra ID on the root
4955                                 // and working up from there (Thanks to Andrew Dupont for the technique)
4956                                 // IE 8 doesn't work on object elements
4957                                 } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
4958                                         var oldContext = context,
4959                                                 old = context.getAttribute( "id" ),
4960                                                 nid = old || id,
4961                                                 hasParent = context.parentNode,
4962                                                 relativeHierarchySelector = /^\s*[+~]/.test( query );
4963
4964                                         if ( !old ) {
4965                                                 context.setAttribute( "id", nid );
4966                                         } else {
4967                                                 nid = nid.replace( /'/g, "\\$&" );
4968                                         }
4969                                         if ( relativeHierarchySelector && hasParent ) {
4970                                                 context = context.parentNode;
4971                                         }
4972
4973                                         try {
4974                                                 if ( !relativeHierarchySelector || hasParent ) {
4975                                                         return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
4976                                                 }
4977
4978                                         } catch(pseudoError) {
4979                                         } finally {
4980                                                 if ( !old ) {
4981                                                         oldContext.removeAttribute( "id" );
4982                                                 }
4983                                         }
4984                                 }
4985                         }
4986                 
4987                         return oldSizzle(query, context, extra, seed);
4988                 };
4989
4990                 for ( var prop in oldSizzle ) {
4991                         Sizzle[ prop ] = oldSizzle[ prop ];
4992                 }
4993
4994                 // release memory in IE
4995                 div = null;
4996         })();
4997 }
4998
4999 (function(){
5000         var html = document.documentElement,
5001                 matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
5002
5003         if ( matches ) {
5004                 // Check to see if it's possible to do matchesSelector
5005                 // on a disconnected node (IE 9 fails this)
5006                 var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
5007                         pseudoWorks = false;
5008
5009                 try {
5010                         // This should fail with an exception
5011                         // Gecko does not error, returns false instead
5012                         matches.call( document.documentElement, "[test!='']:sizzle" );
5013         
5014                 } catch( pseudoError ) {
5015                         pseudoWorks = true;
5016                 }
5017
5018                 Sizzle.matchesSelector = function( node, expr ) {
5019                         // Make sure that attribute selectors are quoted
5020                         expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
5021
5022                         if ( !Sizzle.isXML( node ) ) {
5023                                 try { 
5024                                         if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
5025                                                 var ret = matches.call( node, expr );
5026
5027                                                 // IE 9's matchesSelector returns false on disconnected nodes
5028                                                 if ( ret || !disconnectedMatch ||
5029                                                                 // As well, disconnected nodes are said to be in a document
5030                                                                 // fragment in IE 9, so check for that
5031                                                                 node.document && node.document.nodeType !== 11 ) {
5032                                                         return ret;
5033                                                 }
5034                                         }
5035                                 } catch(e) {}
5036                         }
5037
5038                         return Sizzle(expr, null, null, [node]).length > 0;
5039                 };
5040         }
5041 })();
5042
5043 (function(){
5044         var div = document.createElement("div");
5045
5046         div.innerHTML = "<div class='test e'></div><div class='test'></div>";
5047
5048         // Opera can't find a second classname (in 9.6)
5049         // Also, make sure that getElementsByClassName actually exists
5050         if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
5051                 return;
5052         }
5053
5054         // Safari caches class attributes, doesn't catch changes (in 3.2)
5055         div.lastChild.className = "e";
5056
5057         if ( div.getElementsByClassName("e").length === 1 ) {
5058                 return;
5059         }
5060         
5061         Expr.order.splice(1, 0, "CLASS");
5062         Expr.find.CLASS = function( match, context, isXML ) {
5063                 if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
5064                         return context.getElementsByClassName(match[1]);
5065                 }
5066         };
5067
5068         // release memory in IE
5069         div = null;
5070 })();
5071
5072 function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5073         for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5074                 var elem = checkSet[i];
5075
5076                 if ( elem ) {
5077                         var match = false;
5078
5079                         elem = elem[dir];
5080
5081                         while ( elem ) {
5082                                 if ( elem.sizcache === doneName ) {
5083                                         match = checkSet[elem.sizset];
5084                                         break;
5085                                 }
5086
5087                                 if ( elem.nodeType === 1 && !isXML ){
5088                                         elem.sizcache = doneName;
5089                                         elem.sizset = i;
5090                                 }
5091
5092                                 if ( elem.nodeName.toLowerCase() === cur ) {
5093                                         match = elem;
5094                                         break;
5095                                 }
5096
5097                                 elem = elem[dir];
5098                         }
5099
5100                         checkSet[i] = match;
5101                 }
5102         }
5103 }
5104
5105 function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5106         for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5107                 var elem = checkSet[i];
5108
5109                 if ( elem ) {
5110                         var match = false;
5111                         
5112                         elem = elem[dir];
5113
5114                         while ( elem ) {
5115                                 if ( elem.sizcache === doneName ) {
5116                                         match = checkSet[elem.sizset];
5117                                         break;
5118                                 }
5119
5120                                 if ( elem.nodeType === 1 ) {
5121                                         if ( !isXML ) {
5122                                                 elem.sizcache = doneName;
5123                                                 elem.sizset = i;
5124                                         }
5125
5126                                         if ( typeof cur !== "string" ) {
5127                                                 if ( elem === cur ) {
5128                                                         match = true;
5129                                                         break;
5130                                                 }
5131
5132                                         } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5133                                                 match = elem;
5134                                                 break;
5135                                         }
5136                                 }
5137
5138                                 elem = elem[dir];
5139                         }
5140
5141                         checkSet[i] = match;
5142                 }
5143         }
5144 }
5145
5146 if ( document.documentElement.contains ) {
5147         Sizzle.contains = function( a, b ) {
5148                 return a !== b && (a.contains ? a.contains(b) : true);
5149         };
5150
5151 } else if ( document.documentElement.compareDocumentPosition ) {
5152         Sizzle.contains = function( a, b ) {
5153                 return !!(a.compareDocumentPosition(b) & 16);
5154         };
5155
5156 } else {
5157         Sizzle.contains = function() {
5158                 return false;
5159         };
5160 }
5161
5162 Sizzle.isXML = function( elem ) {
5163         // documentElement is verified for cases where it doesn't yet exist
5164         // (such as loading iframes in IE - #4833) 
5165         var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5166
5167         return documentElement ? documentElement.nodeName !== "HTML" : false;
5168 };
5169
5170 var posProcess = function( selector, context ) {
5171         var match,
5172                 tmpSet = [],
5173                 later = "",
5174                 root = context.nodeType ? [context] : context;
5175
5176         // Position selectors must be done after the filter
5177         // And so must :not(positional) so we move all PSEUDOs to the end
5178         while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5179                 later += match[0];
5180                 selector = selector.replace( Expr.match.PSEUDO, "" );
5181         }
5182
5183         selector = Expr.relative[selector] ? selector + "*" : selector;
5184
5185         for ( var i = 0, l = root.length; i < l; i++ ) {
5186                 Sizzle( selector, root[i], tmpSet );
5187         }
5188
5189         return Sizzle.filter( later, tmpSet );
5190 };
5191
5192 // EXPOSE
5193 jQuery.find = Sizzle;
5194 jQuery.expr = Sizzle.selectors;
5195 jQuery.expr[":"] = jQuery.expr.filters;
5196 jQuery.unique = Sizzle.uniqueSort;
5197 jQuery.text = Sizzle.getText;
5198 jQuery.isXMLDoc = Sizzle.isXML;
5199 jQuery.contains = Sizzle.contains;
5200
5201
5202 })();
5203
5204
5205 var runtil = /Until$/,
5206         rparentsprev = /^(?:parents|prevUntil|prevAll)/,
5207         // Note: This RegExp should be improved, or likely pulled from Sizzle
5208         rmultiselector = /,/,
5209         isSimple = /^.[^:#\[\.,]*$/,
5210         slice = Array.prototype.slice,
5211         POS = jQuery.expr.match.POS,
5212         // methods guaranteed to produce a unique set when starting from a unique set
5213         guaranteedUnique = {
5214                 children: true,
5215                 contents: true,
5216                 next: true,
5217                 prev: true
5218         };
5219
5220 jQuery.fn.extend({
5221         find: function( selector ) {
5222                 var self = this,
5223                         i, l;
5224
5225                 if ( typeof selector !== "string" ) {
5226                         return jQuery( selector ).filter(function() {
5227                                 for ( i = 0, l = self.length; i < l; i++ ) {
5228                                         if ( jQuery.contains( self[ i ], this ) ) {
5229                                                 return true;
5230                                         }
5231                                 }
5232                         });
5233                 }
5234
5235                 var ret = this.pushStack( "", "find", selector ),
5236                         length, n, r;
5237
5238                 for ( i = 0, l = this.length; i < l; i++ ) {
5239                         length = ret.length;
5240                         jQuery.find( selector, this[i], ret );
5241
5242                         if ( i > 0 ) {
5243                                 // Make sure that the results are unique
5244                                 for ( n = length; n < ret.length; n++ ) {
5245                                         for ( r = 0; r < length; r++ ) {
5246                                                 if ( ret[r] === ret[n] ) {
5247                                                         ret.splice(n--, 1);
5248                                                         break;
5249                                                 }
5250                                         }
5251                                 }
5252                         }
5253                 }
5254
5255                 return ret;
5256         },
5257
5258         has: function( target ) {
5259                 var targets = jQuery( target );
5260                 return this.filter(function() {
5261                         for ( var i = 0, l = targets.length; i < l; i++ ) {
5262                                 if ( jQuery.contains( this, targets[i] ) ) {
5263                                         return true;
5264                                 }
5265                         }
5266                 });
5267         },
5268
5269         not: function( selector ) {
5270                 return this.pushStack( winnow(this, selector, false), "not", selector);
5271         },
5272
5273         filter: function( selector ) {
5274                 return this.pushStack( winnow(this, selector, true), "filter", selector );
5275         },
5276
5277         is: function( selector ) {
5278                 return !!selector && ( typeof selector === "string" ?
5279                         jQuery.filter( selector, this ).length > 0 :
5280                         this.filter( selector ).length > 0 );
5281         },
5282
5283         closest: function( selectors, context ) {
5284                 var ret = [], i, l, cur = this[0];
5285                 
5286                 // Array
5287                 if ( jQuery.isArray( selectors ) ) {
5288                         var match, selector,
5289                                 matches = {},
5290                                 level = 1;
5291
5292                         if ( cur && selectors.length ) {
5293                                 for ( i = 0, l = selectors.length; i < l; i++ ) {
5294                                         selector = selectors[i];
5295
5296                                         if ( !matches[ selector ] ) {
5297                                                 matches[ selector ] = POS.test( selector ) ?
5298                                                         jQuery( selector, context || this.context ) :
5299                                                         selector;
5300                                         }
5301                                 }
5302
5303                                 while ( cur && cur.ownerDocument && cur !== context ) {
5304                                         for ( selector in matches ) {
5305                                                 match = matches[ selector ];
5306
5307                                                 if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
5308                                                         ret.push({ selector: selector, elem: cur, level: level });
5309                                                 }
5310                                         }
5311
5312                                         cur = cur.parentNode;
5313                                         level++;
5314                                 }
5315                         }
5316
5317                         return ret;
5318                 }
5319
5320                 // String
5321                 var pos = POS.test( selectors ) || typeof selectors !== "string" ?
5322                                 jQuery( selectors, context || this.context ) :
5323                                 0;
5324
5325                 for ( i = 0, l = this.length; i < l; i++ ) {
5326                         cur = this[i];
5327
5328                         while ( cur ) {
5329                                 if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
5330                                         ret.push( cur );
5331                                         break;
5332
5333                                 } else {
5334                                         cur = cur.parentNode;
5335                                         if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
5336                                                 break;
5337                                         }
5338                                 }
5339                         }
5340                 }
5341
5342                 ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
5343
5344                 return this.pushStack( ret, "closest", selectors );
5345         },
5346
5347         // Determine the position of an element within
5348         // the matched set of elements
5349         index: function( elem ) {
5350
5351                 // No argument, return index in parent
5352                 if ( !elem ) {
5353                         return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
5354                 }
5355
5356                 // index in selector
5357                 if ( typeof elem === "string" ) {
5358                         return jQuery.inArray( this[0], jQuery( elem ) );
5359                 }
5360
5361                 // Locate the position of the desired element
5362                 return jQuery.inArray(
5363                         // If it receives a jQuery object, the first element is used
5364                         elem.jquery ? elem[0] : elem, this );
5365         },
5366
5367         add: function( selector, context ) {
5368                 var set = typeof selector === "string" ?
5369                                 jQuery( selector, context ) :
5370                                 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5371                         all = jQuery.merge( this.get(), set );
5372
5373                 return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
5374                         all :
5375                         jQuery.unique( all ) );
5376         },
5377
5378         andSelf: function() {
5379                 return this.add( this.prevObject );
5380         }
5381 });
5382
5383 // A painfully simple check to see if an element is disconnected
5384 // from a document (should be improved, where feasible).
5385 function isDisconnected( node ) {
5386         return !node || !node.parentNode || node.parentNode.nodeType === 11;
5387 }
5388
5389 jQuery.each({
5390         parent: function( elem ) {
5391                 var parent = elem.parentNode;
5392                 return parent && parent.nodeType !== 11 ? parent : null;
5393         },
5394         parents: function( elem ) {
5395                 return jQuery.dir( elem, "parentNode" );
5396         },
5397         parentsUntil: function( elem, i, until ) {
5398                 return jQuery.dir( elem, "parentNode", until );
5399         },
5400         next: function( elem ) {
5401                 return jQuery.nth( elem, 2, "nextSibling" );
5402         },
5403         prev: function( elem ) {
5404                 return jQuery.nth( elem, 2, "previousSibling" );
5405         },
5406         nextAll: function( elem ) {
5407                 return jQuery.dir( elem, "nextSibling" );
5408         },
5409         prevAll: function( elem ) {
5410                 return jQuery.dir( elem, "previousSibling" );
5411         },
5412         nextUntil: function( elem, i, until ) {
5413                 return jQuery.dir( elem, "nextSibling", until );
5414         },
5415         prevUntil: function( elem, i, until ) {
5416                 return jQuery.dir( elem, "previousSibling", until );
5417         },
5418         siblings: function( elem ) {
5419                 return jQuery.sibling( elem.parentNode.firstChild, elem );
5420         },
5421         children: function( elem ) {
5422                 return jQuery.sibling( elem.firstChild );
5423         },
5424         contents: function( elem ) {
5425                 return jQuery.nodeName( elem, "iframe" ) ?
5426                         elem.contentDocument || elem.contentWindow.document :
5427                         jQuery.makeArray( elem.childNodes );
5428         }
5429 }, function( name, fn ) {
5430         jQuery.fn[ name ] = function( until, selector ) {
5431                 var ret = jQuery.map( this, fn, until ),
5432                         // The variable 'args' was introduced in
5433                         // https://github.com/jquery/jquery/commit/52a0238
5434                         // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
5435                         // http://code.google.com/p/v8/issues/detail?id=1050
5436                         args = slice.call(arguments);
5437
5438                 if ( !runtil.test( name ) ) {
5439                         selector = until;
5440                 }
5441
5442                 if ( selector && typeof selector === "string" ) {
5443                         ret = jQuery.filter( selector, ret );
5444                 }
5445
5446                 ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
5447
5448                 if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
5449                         ret = ret.reverse();
5450                 }
5451
5452                 return this.pushStack( ret, name, args.join(",") );
5453         };
5454 });
5455
5456 jQuery.extend({
5457         filter: function( expr, elems, not ) {
5458                 if ( not ) {
5459                         expr = ":not(" + expr + ")";
5460                 }
5461
5462                 return elems.length === 1 ?
5463                         jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
5464                         jQuery.find.matches(expr, elems);
5465         },
5466
5467         dir: function( elem, dir, until ) {
5468                 var matched = [],
5469                         cur = elem[ dir ];
5470
5471                 while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
5472                         if ( cur.nodeType === 1 ) {
5473                                 matched.push( cur );
5474                         }
5475                         cur = cur[dir];
5476                 }
5477                 return matched;
5478         },
5479
5480         nth: function( cur, result, dir, elem ) {
5481                 result = result || 1;
5482                 var num = 0;
5483
5484                 for ( ; cur; cur = cur[dir] ) {
5485                         if ( cur.nodeType === 1 && ++num === result ) {
5486                                 break;
5487                         }
5488                 }
5489
5490                 return cur;
5491         },
5492
5493         sibling: function( n, elem ) {
5494                 var r = [];
5495
5496                 for ( ; n; n = n.nextSibling ) {
5497                         if ( n.nodeType === 1 && n !== elem ) {
5498                                 r.push( n );
5499                         }
5500                 }
5501
5502                 return r;
5503         }
5504 });
5505
5506 // Implement the identical functionality for filter and not
5507 function winnow( elements, qualifier, keep ) {
5508
5509         // Can't pass null or undefined to indexOf in Firefox 4
5510         // Set to 0 to skip string check
5511         qualifier = qualifier || 0;
5512
5513         if ( jQuery.isFunction( qualifier ) ) {
5514                 return jQuery.grep(elements, function( elem, i ) {
5515                         var retVal = !!qualifier.call( elem, i, elem );
5516                         return retVal === keep;
5517                 });
5518
5519         } else if ( qualifier.nodeType ) {
5520                 return jQuery.grep(elements, function( elem, i ) {
5521                         return (elem === qualifier) === keep;
5522                 });
5523
5524         } else if ( typeof qualifier === "string" ) {
5525                 var filtered = jQuery.grep(elements, function( elem ) {
5526                         return elem.nodeType === 1;
5527                 });
5528
5529                 if ( isSimple.test( qualifier ) ) {
5530                         return jQuery.filter(qualifier, filtered, !keep);
5531                 } else {
5532                         qualifier = jQuery.filter( qualifier, filtered );
5533                 }
5534         }
5535
5536         return jQuery.grep(elements, function( elem, i ) {
5537                 return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
5538         });
5539 }
5540
5541
5542
5543
5544 var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
5545         rleadingWhitespace = /^\s+/,
5546         rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
5547         rtagName = /<([\w:]+)/,
5548         rtbody = /<tbody/i,
5549         rhtml = /<|&#?\w+;/,
5550         rnocache = /<(?:script|object|embed|option|style)/i,
5551         // checked="checked" or checked
5552         rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5553         rscriptType = /\/(java|ecma)script/i,
5554         rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
5555         wrapMap = {
5556                 option: [ 1, "<select multiple='multiple'>", "</select>" ],
5557                 legend: [ 1, "<fieldset>", "</fieldset>" ],
5558                 thead: [ 1, "<table>", "</table>" ],
5559                 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5560                 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5561                 col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
5562                 area: [ 1, "<map>", "</map>" ],
5563                 _default: [ 0, "", "" ]
5564         };
5565
5566 wrapMap.optgroup = wrapMap.option;
5567 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5568 wrapMap.th = wrapMap.td;
5569
5570 // IE can't serialize <link> and <script> tags normally
5571 if ( !jQuery.support.htmlSerialize ) {
5572         wrapMap._default = [ 1, "div<div>", "</div>" ];
5573 }
5574
5575 jQuery.fn.extend({
5576         text: function( text ) {
5577                 if ( jQuery.isFunction(text) ) {
5578                         return this.each(function(i) {
5579                                 var self = jQuery( this );
5580
5581                                 self.text( text.call(this, i, self.text()) );
5582                         });
5583                 }
5584
5585                 if ( typeof text !== "object" && text !== undefined ) {
5586                         return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
5587                 }
5588
5589                 return jQuery.text( this );
5590         },
5591
5592         wrapAll: function( html ) {
5593                 if ( jQuery.isFunction( html ) ) {
5594                         return this.each(function(i) {
5595                                 jQuery(this).wrapAll( html.call(this, i) );
5596                         });
5597                 }
5598
5599                 if ( this[0] ) {
5600                         // The elements to wrap the target around
5601                         var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
5602
5603                         if ( this[0].parentNode ) {
5604                                 wrap.insertBefore( this[0] );
5605                         }
5606
5607                         wrap.map(function() {
5608                                 var elem = this;
5609
5610                                 while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
5611                                         elem = elem.firstChild;
5612                                 }
5613
5614                                 return elem;
5615                         }).append( this );
5616                 }
5617
5618                 return this;
5619         },
5620
5621         wrapInner: function( html ) {
5622                 if ( jQuery.isFunction( html ) ) {
5623                         return this.each(function(i) {
5624                                 jQuery(this).wrapInner( html.call(this, i) );
5625                         });
5626                 }
5627
5628                 return this.each(function() {
5629                         var self = jQuery( this ),
5630                                 contents = self.contents();
5631
5632                         if ( contents.length ) {
5633                                 contents.wrapAll( html );
5634
5635                         } else {
5636                                 self.append( html );
5637                         }
5638                 });
5639         },
5640
5641         wrap: function( html ) {
5642                 return this.each(function() {
5643                         jQuery( this ).wrapAll( html );
5644                 });
5645         },
5646
5647         unwrap: function() {
5648                 return this.parent().each(function() {
5649                         if ( !jQuery.nodeName( this, "body" ) ) {
5650                                 jQuery( this ).replaceWith( this.childNodes );
5651                         }
5652                 }).end();
5653         },
5654
5655         append: function() {
5656                 return this.domManip(arguments, true, function( elem ) {
5657                         if ( this.nodeType === 1 ) {
5658                                 this.appendChild( elem );
5659                         }
5660                 });
5661         },
5662
5663         prepend: function() {
5664                 return this.domManip(arguments, true, function( elem ) {
5665                         if ( this.nodeType === 1 ) {
5666                                 this.insertBefore( elem, this.firstChild );
5667                         }
5668                 });
5669         },
5670
5671         before: function() {
5672                 if ( this[0] && this[0].parentNode ) {
5673                         return this.domManip(arguments, false, function( elem ) {
5674                                 this.parentNode.insertBefore( elem, this );
5675                         });
5676                 } else if ( arguments.length ) {
5677                         var set = jQuery(arguments[0]);
5678                         set.push.apply( set, this.toArray() );
5679                         return this.pushStack( set, "before", arguments );
5680                 }
5681         },
5682
5683         after: function() {
5684                 if ( this[0] && this[0].parentNode ) {
5685                         return this.domManip(arguments, false, function( elem ) {
5686                                 this.parentNode.insertBefore( elem, this.nextSibling );
5687                         });
5688                 } else if ( arguments.length ) {
5689                         var set = this.pushStack( this, "after", arguments );
5690                         set.push.apply( set, jQuery(arguments[0]).toArray() );
5691                         return set;
5692                 }
5693         },
5694
5695         // keepData is for internal use only--do not document
5696         remove: function( selector, keepData ) {
5697                 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5698                         if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
5699                                 if ( !keepData && elem.nodeType === 1 ) {
5700                                         jQuery.cleanData( elem.getElementsByTagName("*") );
5701                                         jQuery.cleanData( [ elem ] );
5702                                 }
5703
5704                                 if ( elem.parentNode ) {
5705                                         elem.parentNode.removeChild( elem );
5706                                 }
5707                         }
5708                 }
5709
5710                 return this;
5711         },
5712
5713         empty: function() {
5714                 for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
5715                         // Remove element nodes and prevent memory leaks
5716                         if ( elem.nodeType === 1 ) {
5717                                 jQuery.cleanData( elem.getElementsByTagName("*") );
5718                         }
5719
5720                         // Remove any remaining nodes
5721                         while ( elem.firstChild ) {
5722                                 elem.removeChild( elem.firstChild );
5723                         }
5724                 }
5725
5726                 return this;
5727         },
5728
5729         clone: function( dataAndEvents, deepDataAndEvents ) {
5730                 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5731                 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5732
5733                 return this.map( function () {
5734                         return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5735                 });
5736         },
5737
5738         html: function( value ) {
5739                 if ( value === undefined ) {
5740                         return this[0] && this[0].nodeType === 1 ?
5741                                 this[0].innerHTML.replace(rinlinejQuery, "") :
5742                                 null;
5743
5744                 // See if we can take a shortcut and just use innerHTML
5745                 } else if ( typeof value === "string" && !rnocache.test( value ) &&
5746                         (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
5747                         !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
5748
5749                         value = value.replace(rxhtmlTag, "<$1></$2>");
5750
5751                         try {
5752                                 for ( var i = 0, l = this.length; i < l; i++ ) {
5753                                         // Remove element nodes and prevent memory leaks
5754                                         if ( this[i].nodeType === 1 ) {
5755                                                 jQuery.cleanData( this[i].getElementsByTagName("*") );
5756                                                 this[i].innerHTML = value;
5757                                         }
5758                                 }
5759
5760                         // If using innerHTML throws an exception, use the fallback method
5761                         } catch(e) {
5762                                 this.empty().append( value );
5763                         }
5764
5765                 } else if ( jQuery.isFunction( value ) ) {
5766                         this.each(function(i){
5767                                 var self = jQuery( this );
5768
5769                                 self.html( value.call(this, i, self.html()) );
5770                         });
5771
5772                 } else {
5773                         this.empty().append( value );
5774                 }
5775
5776                 return this;
5777         },
5778
5779         replaceWith: function( value ) {
5780                 if ( this[0] && this[0].parentNode ) {
5781                         // Make sure that the elements are removed from the DOM before they are inserted
5782                         // this can help fix replacing a parent with child elements
5783                         if ( jQuery.isFunction( value ) ) {
5784                                 return this.each(function(i) {
5785                                         var self = jQuery(this), old = self.html();
5786                                         self.replaceWith( value.call( this, i, old ) );
5787                                 });
5788                         }
5789
5790                         if ( typeof value !== "string" ) {
5791                                 value = jQuery( value ).detach();
5792                         }
5793
5794                         return this.each(function() {
5795                                 var next = this.nextSibling,
5796                                         parent = this.parentNode;
5797
5798                                 jQuery( this ).remove();
5799
5800                                 if ( next ) {
5801                                         jQuery(next).before( value );
5802                                 } else {
5803                                         jQuery(parent).append( value );
5804                                 }
5805                         });
5806                 } else {
5807                         return this.length ?
5808                                 this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
5809                                 this;
5810                 }
5811         },
5812
5813         detach: function( selector ) {
5814                 return this.remove( selector, true );
5815         },
5816
5817         domManip: function( args, table, callback ) {
5818                 var results, first, fragment, parent,
5819                         value = args[0],
5820                         scripts = [];
5821
5822                 // We can't cloneNode fragments that contain checked, in WebKit
5823                 if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
5824                         return this.each(function() {
5825                                 jQuery(this).domManip( args, table, callback, true );
5826                         });
5827                 }
5828
5829                 if ( jQuery.isFunction(value) ) {
5830                         return this.each(function(i) {
5831                                 var self = jQuery(this);
5832                                 args[0] = value.call(this, i, table ? self.html() : undefined);
5833                                 self.domManip( args, table, callback );
5834                         });
5835                 }
5836
5837                 if ( this[0] ) {
5838                         parent = value && value.parentNode;
5839
5840                         // If we're in a fragment, just use that instead of building a new one
5841                         if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
5842                                 results = { fragment: parent };
5843
5844                         } else {
5845                                 results = jQuery.buildFragment( args, this, scripts );
5846                         }
5847
5848                         fragment = results.fragment;
5849
5850                         if ( fragment.childNodes.length === 1 ) {
5851                                 first = fragment = fragment.firstChild;
5852                         } else {
5853                                 first = fragment.firstChild;
5854                         }
5855
5856                         if ( first ) {
5857                                 table = table && jQuery.nodeName( first, "tr" );
5858
5859                                 for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
5860                                         callback.call(
5861                                                 table ?
5862                                                         root(this[i], first) :
5863                                                         this[i],
5864                                                 // Make sure that we do not leak memory by inadvertently discarding
5865                                                 // the original fragment (which might have attached data) instead of
5866                                                 // using it; in addition, use the original fragment object for the last
5867                                                 // item instead of first because it can end up being emptied incorrectly
5868                                                 // in certain situations (Bug #8070).
5869                                                 // Fragments from the fragment cache must always be cloned and never used
5870                                                 // in place.
5871                                                 results.cacheable || (l > 1 && i < lastIndex) ?
5872                                                         jQuery.clone( fragment, true, true ) :
5873                                                         fragment
5874                                         );
5875                                 }
5876                         }
5877
5878                         if ( scripts.length ) {
5879                                 jQuery.each( scripts, evalScript );
5880                         }
5881                 }
5882
5883                 return this;
5884         }
5885 });
5886
5887 function root( elem, cur ) {
5888         return jQuery.nodeName(elem, "table") ?
5889                 (elem.getElementsByTagName("tbody")[0] ||
5890                 elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
5891                 elem;
5892 }
5893
5894 function cloneCopyEvent( src, dest ) {
5895
5896         if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
5897                 return;
5898         }
5899
5900         var internalKey = jQuery.expando,
5901                 oldData = jQuery.data( src ),
5902                 curData = jQuery.data( dest, oldData );
5903
5904         // Switch to use the internal data object, if it exists, for the next
5905         // stage of data copying
5906         if ( (oldData = oldData[ internalKey ]) ) {
5907                 var events = oldData.events;
5908                                 curData = curData[ internalKey ] = jQuery.extend({}, oldData);
5909
5910                 if ( events ) {
5911                         delete curData.handle;
5912                         curData.events = {};
5913
5914                         for ( var type in events ) {
5915                                 for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
5916                                         jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
5917                                 }
5918                         }
5919                 }
5920         }
5921 }
5922
5923 function cloneFixAttributes( src, dest ) {
5924         var nodeName;
5925
5926         // We do not need to do anything for non-Elements
5927         if ( dest.nodeType !== 1 ) {
5928                 return;
5929         }
5930
5931         // clearAttributes removes the attributes, which we don't want,
5932         // but also removes the attachEvent events, which we *do* want
5933         if ( dest.clearAttributes ) {
5934                 dest.clearAttributes();
5935         }
5936
5937         // mergeAttributes, in contrast, only merges back on the
5938         // original attributes, not the events
5939         if ( dest.mergeAttributes ) {
5940                 dest.mergeAttributes( src );
5941         }
5942
5943         nodeName = dest.nodeName.toLowerCase();
5944
5945         // IE6-8 fail to clone children inside object elements that use
5946         // the proprietary classid attribute value (rather than the type
5947         // attribute) to identify the type of content to display
5948         if ( nodeName === "object" ) {
5949                 dest.outerHTML = src.outerHTML;
5950
5951         } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
5952                 // IE6-8 fails to persist the checked state of a cloned checkbox
5953                 // or radio button. Worse, IE6-7 fail to give the cloned element
5954                 // a checked appearance if the defaultChecked value isn't also set
5955                 if ( src.checked ) {
5956                         dest.defaultChecked = dest.checked = src.checked;
5957                 }
5958
5959                 // IE6-7 get confused and end up setting the value of a cloned
5960                 // checkbox/radio button to an empty string instead of "on"
5961                 if ( dest.value !== src.value ) {
5962                         dest.value = src.value;
5963                 }
5964
5965         // IE6-8 fails to return the selected option to the default selected
5966         // state when cloning options
5967         } else if ( nodeName === "option" ) {
5968                 dest.selected = src.defaultSelected;
5969
5970         // IE6-8 fails to set the defaultValue to the correct value when
5971         // cloning other types of input fields
5972         } else if ( nodeName === "input" || nodeName === "textarea" ) {
5973                 dest.defaultValue = src.defaultValue;
5974         }
5975
5976         // Event data gets referenced instead of copied if the expando
5977         // gets copied too
5978         dest.removeAttribute( jQuery.expando );
5979 }
5980
5981 jQuery.buildFragment = function( args, nodes, scripts ) {
5982         var fragment, cacheable, cacheresults, doc;
5983
5984   // nodes may contain either an explicit document object,
5985   // a jQuery collection or context object.
5986   // If nodes[0] contains a valid object to assign to doc
5987   if ( nodes && nodes[0] ) {
5988     doc = nodes[0].ownerDocument || nodes[0];
5989   }
5990
5991   // Ensure that an attr object doesn't incorrectly stand in as a document object
5992         // Chrome and Firefox seem to allow this to occur and will throw exception
5993         // Fixes #8950
5994         if ( !doc.createDocumentFragment ) {
5995                 doc = document;
5996         }
5997
5998         // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
5999         // Cloning options loses the selected state, so don't cache them
6000         // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
6001         // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
6002         if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
6003                 args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
6004
6005                 cacheable = true;
6006
6007                 cacheresults = jQuery.fragments[ args[0] ];
6008                 if ( cacheresults && cacheresults !== 1 ) {
6009                         fragment = cacheresults;
6010                 }
6011         }
6012
6013         if ( !fragment ) {
6014                 fragment = doc.createDocumentFragment();
6015                 jQuery.clean( args, doc, fragment, scripts );
6016         }
6017
6018         if ( cacheable ) {
6019                 jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
6020         }
6021
6022         return { fragment: fragment, cacheable: cacheable };
6023 };
6024
6025 jQuery.fragments = {};
6026
6027 jQuery.each({
6028         appendTo: "append",
6029         prependTo: "prepend",
6030         insertBefore: "before",
6031         insertAfter: "after",
6032         replaceAll: "replaceWith"
6033 }, function( name, original ) {
6034         jQuery.fn[ name ] = function( selector ) {
6035                 var ret = [],
6036                         insert = jQuery( selector ),
6037                         parent = this.length === 1 && this[0].parentNode;
6038
6039                 if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
6040                         insert[ original ]( this[0] );
6041                         return this;
6042
6043                 } else {
6044                         for ( var i = 0, l = insert.length; i < l; i++ ) {
6045                                 var elems = (i > 0 ? this.clone(true) : this).get();
6046                                 jQuery( insert[i] )[ original ]( elems );
6047                                 ret = ret.concat( elems );
6048                         }
6049
6050                         return this.pushStack( ret, name, insert.selector );
6051                 }
6052         };
6053 });
6054
6055 function getAll( elem ) {
6056         if ( "getElementsByTagName" in elem ) {
6057                 return elem.getElementsByTagName( "*" );
6058
6059         } else if ( "querySelectorAll" in elem ) {
6060                 return elem.querySelectorAll( "*" );
6061
6062         } else {
6063                 return [];
6064         }
6065 }
6066
6067 // Used in clean, fixes the defaultChecked property
6068 function fixDefaultChecked( elem ) {
6069         if ( elem.type === "checkbox" || elem.type === "radio" ) {
6070                 elem.defaultChecked = elem.checked;
6071         }
6072 }
6073 // Finds all inputs and passes them to fixDefaultChecked
6074 function findInputs( elem ) {
6075         if ( jQuery.nodeName( elem, "input" ) ) {
6076                 fixDefaultChecked( elem );
6077         } else if ( "getElementsByTagName" in elem ) {
6078                 jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
6079         }
6080 }
6081
6082 jQuery.extend({
6083         clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6084                 var clone = elem.cloneNode(true),
6085                                 srcElements,
6086                                 destElements,
6087                                 i;
6088
6089                 if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
6090                                 (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
6091                         // IE copies events bound via attachEvent when using cloneNode.
6092                         // Calling detachEvent on the clone will also remove the events
6093                         // from the original. In order to get around this, we use some
6094                         // proprietary methods to clear the events. Thanks to MooTools
6095                         // guys for this hotness.
6096
6097                         cloneFixAttributes( elem, clone );
6098
6099                         // Using Sizzle here is crazy slow, so we use getElementsByTagName
6100                         // instead
6101                         srcElements = getAll( elem );
6102                         destElements = getAll( clone );
6103
6104                         // Weird iteration because IE will replace the length property
6105                         // with an element if you are cloning the body and one of the
6106                         // elements on the page has a name or id of "length"
6107                         for ( i = 0; srcElements[i]; ++i ) {
6108                                 // Ensure that the destination node is not null; Fixes #9587
6109                                 if ( destElements[i] ) {
6110                                         cloneFixAttributes( srcElements[i], destElements[i] );
6111                                 }
6112                         }
6113                 }
6114
6115                 // Copy the events from the original to the clone
6116                 if ( dataAndEvents ) {
6117                         cloneCopyEvent( elem, clone );
6118
6119                         if ( deepDataAndEvents ) {
6120                                 srcElements = getAll( elem );
6121                                 destElements = getAll( clone );
6122
6123                                 for ( i = 0; srcElements[i]; ++i ) {
6124                                         cloneCopyEvent( srcElements[i], destElements[i] );
6125                                 }
6126                         }
6127                 }
6128
6129                 srcElements = destElements = null;
6130
6131                 // Return the cloned set
6132                 return clone;
6133         },
6134
6135         clean: function( elems, context, fragment, scripts ) {
6136                 var checkScriptType;
6137
6138                 context = context || document;
6139
6140                 // !context.createElement fails in IE with an error but returns typeof 'object'
6141                 if ( typeof context.createElement === "undefined" ) {
6142                         context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
6143                 }
6144
6145                 var ret = [], j;
6146
6147                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6148                         if ( typeof elem === "number" ) {
6149                                 elem += "";
6150                         }
6151
6152                         if ( !elem ) {
6153                                 continue;
6154                         }
6155
6156                         // Convert html string into DOM nodes
6157                         if ( typeof elem === "string" ) {
6158                                 if ( !rhtml.test( elem ) ) {
6159                                         elem = context.createTextNode( elem );
6160                                 } else {
6161                                         // Fix "XHTML"-style tags in all browsers
6162                                         elem = elem.replace(rxhtmlTag, "<$1></$2>");
6163
6164                                         // Trim whitespace, otherwise indexOf won't work as expected
6165                                         var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
6166                                                 wrap = wrapMap[ tag ] || wrapMap._default,
6167                                                 depth = wrap[0],
6168                                                 div = context.createElement("div");
6169
6170                                         // Go to html and back, then peel off extra wrappers
6171                                         div.innerHTML = wrap[1] + elem + wrap[2];
6172
6173                                         // Move to the right depth
6174                                         while ( depth-- ) {
6175                                                 div = div.lastChild;
6176                                         }
6177
6178                                         // Remove IE's autoinserted <tbody> from table fragments
6179                                         if ( !jQuery.support.tbody ) {
6180
6181                                                 // String was a <table>, *may* have spurious <tbody>
6182                                                 var hasBody = rtbody.test(elem),
6183                                                         tbody = tag === "table" && !hasBody ?
6184                                                                 div.firstChild && div.firstChild.childNodes :
6185
6186                                                                 // String was a bare <thead> or <tfoot>
6187                                                                 wrap[1] === "<table>" && !hasBody ?
6188                                                                         div.childNodes :
6189                                                                         [];
6190
6191                                                 for ( j = tbody.length - 1; j >= 0 ; --j ) {
6192                                                         if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
6193                                                                 tbody[ j ].parentNode.removeChild( tbody[ j ] );
6194                                                         }
6195                                                 }
6196                                         }
6197
6198                                         // IE completely kills leading whitespace when innerHTML is used
6199                                         if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
6200                                                 div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
6201                                         }
6202
6203                                         elem = div.childNodes;
6204                                 }
6205                         }
6206
6207                         // Resets defaultChecked for any radios and checkboxes
6208                         // about to be appended to the DOM in IE 6/7 (#8060)
6209                         var len;
6210                         if ( !jQuery.support.appendChecked ) {
6211                                 if ( elem[0] && typeof (len = elem.length) === "number" ) {
6212                                         for ( j = 0; j < len; j++ ) {
6213                                                 findInputs( elem[j] );
6214                                         }
6215                                 } else {
6216                                         findInputs( elem );
6217                                 }
6218                         }
6219
6220                         if ( elem.nodeType ) {
6221                                 ret.push( elem );
6222                         } else {
6223                                 ret = jQuery.merge( ret, elem );
6224                         }
6225                 }
6226
6227                 if ( fragment ) {
6228                         checkScriptType = function( elem ) {
6229                                 return !elem.type || rscriptType.test( elem.type );
6230                         };
6231                         for ( i = 0; ret[i]; i++ ) {
6232                                 if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
6233                                         scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
6234
6235                                 } else {
6236                                         if ( ret[i].nodeType === 1 ) {
6237                                                 var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
6238
6239                                                 ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
6240                                         }
6241                                         fragment.appendChild( ret[i] );
6242                                 }
6243                         }
6244                 }
6245
6246                 return ret;
6247         },
6248
6249         cleanData: function( elems ) {
6250                 var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
6251                         deleteExpando = jQuery.support.deleteExpando;
6252
6253                 for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
6254                         if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
6255                                 continue;
6256                         }
6257
6258                         id = elem[ jQuery.expando ];
6259
6260                         if ( id ) {
6261                                 data = cache[ id ] && cache[ id ][ internalKey ];
6262
6263                                 if ( data && data.events ) {
6264                                         for ( var type in data.events ) {
6265                                                 if ( special[ type ] ) {
6266                                                         jQuery.event.remove( elem, type );
6267
6268                                                 // This is a shortcut to avoid jQuery.event.remove's overhead
6269                                                 } else {
6270                                                         jQuery.removeEvent( elem, type, data.handle );
6271                                                 }
6272                                         }
6273
6274                                         // Null the DOM reference to avoid IE6/7/8 leak (#7054)
6275                                         if ( data.handle ) {
6276                                                 data.handle.elem = null;
6277                                         }
6278                                 }
6279
6280                                 if ( deleteExpando ) {
6281                                         delete elem[ jQuery.expando ];
6282
6283                                 } else if ( elem.removeAttribute ) {
6284                                         elem.removeAttribute( jQuery.expando );
6285                                 }
6286
6287                                 delete cache[ id ];
6288                         }
6289                 }
6290         }
6291 });
6292
6293 function evalScript( i, elem ) {
6294         if ( elem.src ) {
6295                 jQuery.ajax({
6296                         url: elem.src,
6297                         async: false,
6298                         dataType: "script"
6299                 });
6300         } else {
6301                 jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
6302         }
6303
6304         if ( elem.parentNode ) {
6305                 elem.parentNode.removeChild( elem );
6306         }
6307 }
6308
6309
6310
6311
6312 var ralpha = /alpha\([^)]*\)/i,
6313         ropacity = /opacity=([^)]*)/,
6314         // fixed for IE9, see #8346
6315         rupper = /([A-Z]|^ms)/g,
6316         rnumpx = /^-?\d+(?:px)?$/i,
6317         rnum = /^-?\d/,
6318         rrelNum = /^([\-+])=([\-+.\de]+)/,
6319
6320         cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6321         cssWidth = [ "Left", "Right" ],
6322         cssHeight = [ "Top", "Bottom" ],
6323         curCSS,
6324
6325         getComputedStyle,
6326         currentStyle;
6327
6328 jQuery.fn.css = function( name, value ) {
6329         // Setting 'undefined' is a no-op
6330         if ( arguments.length === 2 && value === undefined ) {
6331                 return this;
6332         }
6333
6334         return jQuery.access( this, name, value, true, function( elem, name, value ) {
6335                 return value !== undefined ?
6336                         jQuery.style( elem, name, value ) :
6337                         jQuery.css( elem, name );
6338         });
6339 };
6340
6341 jQuery.extend({
6342         // Add in style property hooks for overriding the default
6343         // behavior of getting and setting a style property
6344         cssHooks: {
6345                 opacity: {
6346                         get: function( elem, computed ) {
6347                                 if ( computed ) {
6348                                         // We should always get a number back from opacity
6349                                         var ret = curCSS( elem, "opacity", "opacity" );
6350                                         return ret === "" ? "1" : ret;
6351
6352                                 } else {
6353                                         return elem.style.opacity;
6354                                 }
6355                         }
6356                 }
6357         },
6358
6359         // Exclude the following css properties to add px
6360         cssNumber: {
6361                 "fillOpacity": true,
6362                 "fontWeight": true,
6363                 "lineHeight": true,
6364                 "opacity": true,
6365                 "orphans": true,
6366                 "widows": true,
6367                 "zIndex": true,
6368                 "zoom": true
6369         },
6370
6371         // Add in properties whose names you wish to fix before
6372         // setting or getting the value
6373         cssProps: {
6374                 // normalize float css property
6375                 "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
6376         },
6377
6378         // Get and set the style property on a DOM Node
6379         style: function( elem, name, value, extra ) {
6380                 // Don't set styles on text and comment nodes
6381                 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6382                         return;
6383                 }
6384
6385                 // Make sure that we're working with the right name
6386                 var ret, type, origName = jQuery.camelCase( name ),
6387                         style = elem.style, hooks = jQuery.cssHooks[ origName ];
6388
6389                 name = jQuery.cssProps[ origName ] || origName;
6390
6391                 // Check if we're setting a value
6392                 if ( value !== undefined ) {
6393                         type = typeof value;
6394
6395                         // convert relative number strings (+= or -=) to relative numbers. #7345
6396                         if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6397                                 value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
6398                                 // Fixes bug #9237
6399                                 type = "number";
6400                         }
6401
6402                         // Make sure that NaN and null values aren't set. See: #7116
6403                         if ( value == null || type === "number" && isNaN( value ) ) {
6404                                 return;
6405                         }
6406
6407                         // If a number was passed in, add 'px' to the (except for certain CSS properties)
6408                         if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6409                                 value += "px";
6410                         }
6411
6412                         // If a hook was provided, use that value, otherwise just set the specified value
6413                         if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
6414                                 // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
6415                                 // Fixes bug #5509
6416                                 try {
6417                                         style[ name ] = value;
6418                                 } catch(e) {}
6419                         }
6420
6421                 } else {
6422                         // If a hook was provided get the non-computed value from there
6423                         if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6424                                 return ret;
6425                         }
6426
6427                         // Otherwise just get the value from the style object
6428                         return style[ name ];
6429                 }
6430         },
6431
6432         css: function( elem, name, extra ) {
6433                 var ret, hooks;
6434
6435                 // Make sure that we're working with the right name
6436                 name = jQuery.camelCase( name );
6437                 hooks = jQuery.cssHooks[ name ];
6438                 name = jQuery.cssProps[ name ] || name;
6439
6440                 // cssFloat needs a special treatment
6441                 if ( name === "cssFloat" ) {
6442                         name = "float";
6443                 }
6444
6445                 // If a hook was provided get the computed value from there
6446                 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
6447                         return ret;
6448
6449                 // Otherwise, if a way to get the computed value exists, use that
6450                 } else if ( curCSS ) {
6451                         return curCSS( elem, name );
6452                 }
6453         },
6454
6455         // A method for quickly swapping in/out CSS properties to get correct calculations
6456         swap: function( elem, options, callback ) {
6457                 var old = {};
6458
6459                 // Remember the old values, and insert the new ones
6460                 for ( var name in options ) {
6461                         old[ name ] = elem.style[ name ];
6462                         elem.style[ name ] = options[ name ];
6463                 }
6464
6465                 callback.call( elem );
6466
6467                 // Revert the old values
6468                 for ( name in options ) {
6469                         elem.style[ name ] = old[ name ];
6470                 }
6471         }
6472 });
6473
6474 // DEPRECATED, Use jQuery.css() instead
6475 jQuery.curCSS = jQuery.css;
6476
6477 jQuery.each(["height", "width"], function( i, name ) {
6478         jQuery.cssHooks[ name ] = {
6479                 get: function( elem, computed, extra ) {
6480                         var val;
6481
6482                         if ( computed ) {
6483                                 if ( elem.offsetWidth !== 0 ) {
6484                                         return getWH( elem, name, extra );
6485                                 } else {
6486                                         jQuery.swap( elem, cssShow, function() {
6487                                                 val = getWH( elem, name, extra );
6488                                         });
6489                                 }
6490
6491                                 return val;
6492                         }
6493                 },
6494
6495                 set: function( elem, value ) {
6496                         if ( rnumpx.test( value ) ) {
6497                                 // ignore negative width and height values #1599
6498                                 value = parseFloat( value );
6499
6500                                 if ( value >= 0 ) {
6501                                         return value + "px";
6502                                 }
6503
6504                         } else {
6505                                 return value;
6506                         }
6507                 }
6508         };
6509 });
6510
6511 if ( !jQuery.support.opacity ) {
6512         jQuery.cssHooks.opacity = {
6513                 get: function( elem, computed ) {
6514                         // IE uses filters for opacity
6515                         return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
6516                                 ( parseFloat( RegExp.$1 ) / 100 ) + "" :
6517                                 computed ? "1" : "";
6518                 },
6519
6520                 set: function( elem, value ) {
6521                         var style = elem.style,
6522                                 currentStyle = elem.currentStyle,
6523                                 opacity = jQuery.isNaN( value ) ? "" : "alpha(opacity=" + value * 100 + ")",
6524                                 filter = currentStyle && currentStyle.filter || style.filter || "";
6525
6526                         // IE has trouble with opacity if it does not have layout
6527                         // Force it by setting the zoom level
6528                         style.zoom = 1;
6529
6530                         // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
6531                         if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
6532
6533                                 // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
6534                                 // if "filter:" is present at all, clearType is disabled, we want to avoid this
6535                                 // style.removeAttribute is IE Only, but so apparently is this code path...
6536                                 style.removeAttribute( "filter" );
6537
6538                                 // if there there is no filter style applied in a css rule, we are done
6539                                 if ( currentStyle && !currentStyle.filter ) {
6540                                         return;
6541                                 }
6542                         }
6543
6544                         // otherwise, set new filter values
6545                         style.filter = ralpha.test( filter ) ?
6546                                 filter.replace( ralpha, opacity ) :
6547                                 filter + " " + opacity;
6548                 }
6549         };
6550 }
6551
6552 jQuery(function() {
6553         // This hook cannot be added until DOM ready because the support test
6554         // for it is not run until after DOM ready
6555         if ( !jQuery.support.reliableMarginRight ) {
6556                 jQuery.cssHooks.marginRight = {
6557                         get: function( elem, computed ) {
6558                                 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6559                                 // Work around by temporarily setting element display to inline-block
6560                                 var ret;
6561                                 jQuery.swap( elem, { "display": "inline-block" }, function() {
6562                                         if ( computed ) {
6563                                                 ret = curCSS( elem, "margin-right", "marginRight" );
6564                                         } else {
6565                                                 ret = elem.style.marginRight;
6566                                         }
6567                                 });
6568                                 return ret;
6569                         }
6570                 };
6571         }
6572 });
6573
6574 if ( document.defaultView && document.defaultView.getComputedStyle ) {
6575         getComputedStyle = function( elem, name ) {
6576                 var ret, defaultView, computedStyle;
6577
6578                 name = name.replace( rupper, "-$1" ).toLowerCase();
6579
6580                 if ( !(defaultView = elem.ownerDocument.defaultView) ) {
6581                         return undefined;
6582                 }
6583
6584                 if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
6585                         ret = computedStyle.getPropertyValue( name );
6586                         if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
6587                                 ret = jQuery.style( elem, name );
6588                         }
6589                 }
6590
6591                 return ret;
6592         };
6593 }
6594
6595 if ( document.documentElement.currentStyle ) {
6596         currentStyle = function( elem, name ) {
6597                 var left,
6598                         ret = elem.currentStyle && elem.currentStyle[ name ],
6599                         rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
6600                         style = elem.style;
6601
6602                 // From the awesome hack by Dean Edwards
6603                 // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
6604
6605                 // If we're not dealing with a regular pixel number
6606                 // but a number that has a weird ending, we need to convert it to pixels
6607                 if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
6608                         // Remember the original values
6609                         left = style.left;
6610
6611                         // Put in the new values to get a computed value out
6612                         if ( rsLeft ) {
6613                                 elem.runtimeStyle.left = elem.currentStyle.left;
6614                         }
6615                         style.left = name === "fontSize" ? "1em" : (ret || 0);
6616                         ret = style.pixelLeft + "px";
6617
6618                         // Revert the changed values
6619                         style.left = left;
6620                         if ( rsLeft ) {
6621                                 elem.runtimeStyle.left = rsLeft;
6622                         }
6623                 }
6624
6625                 return ret === "" ? "auto" : ret;
6626         };
6627 }
6628
6629 curCSS = getComputedStyle || currentStyle;
6630
6631 function getWH( elem, name, extra ) {
6632
6633         // Start with offset property
6634         var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6635                 which = name === "width" ? cssWidth : cssHeight;
6636
6637         if ( val > 0 ) {
6638                 if ( extra !== "border" ) {
6639                         jQuery.each( which, function() {
6640                                 if ( !extra ) {
6641                                         val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
6642                                 }
6643                                 if ( extra === "margin" ) {
6644                                         val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
6645                                 } else {
6646                                         val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
6647                                 }
6648                         });
6649                 }
6650
6651                 return val + "px";
6652         }
6653
6654         // Fall back to computed then uncomputed css if necessary
6655         val = curCSS( elem, name, name );
6656         if ( val < 0 || val == null ) {
6657                 val = elem.style[ name ] || 0;
6658         }
6659         // Normalize "", auto, and prepare for extra
6660         val = parseFloat( val ) || 0;
6661
6662         // Add padding, border, margin
6663         if ( extra ) {
6664                 jQuery.each( which, function() {
6665                         val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0;
6666                         if ( extra !== "padding" ) {
6667                                 val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0;
6668                         }
6669                         if ( extra === "margin" ) {
6670                                 val += parseFloat( jQuery.css( elem, extra + this ) ) || 0;
6671                         }
6672                 });
6673         }
6674
6675         return val + "px";
6676 }
6677
6678 if ( jQuery.expr && jQuery.expr.filters ) {
6679         jQuery.expr.filters.hidden = function( elem ) {
6680                 var width = elem.offsetWidth,
6681                         height = elem.offsetHeight;
6682
6683                 return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
6684         };
6685
6686         jQuery.expr.filters.visible = function( elem ) {
6687                 return !jQuery.expr.filters.hidden( elem );
6688         };
6689 }
6690
6691
6692
6693
6694 var r20 = /%20/g,
6695         rbracket = /\[\]$/,
6696         rCRLF = /\r?\n/g,
6697         rhash = /#.*$/,
6698         rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
6699         rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
6700         // #7653, #8125, #8152: local protocol detection
6701         rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
6702         rnoContent = /^(?:GET|HEAD)$/,
6703         rprotocol = /^\/\//,
6704         rquery = /\?/,
6705         rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
6706         rselectTextarea = /^(?:select|textarea)/i,
6707         rspacesAjax = /\s+/,
6708         rts = /([?&])_=[^&]*/,
6709         rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
6710
6711         // Keep a copy of the old load method
6712         _load = jQuery.fn.load,
6713
6714         /* Prefilters
6715          * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6716          * 2) These are called:
6717          *    - BEFORE asking for a transport
6718          *    - AFTER param serialization (s.data is a string if s.processData is true)
6719          * 3) key is the dataType
6720          * 4) the catchall symbol "*" can be used
6721          * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6722          */
6723         prefilters = {},
6724
6725         /* Transports bindings
6726          * 1) key is the dataType
6727          * 2) the catchall symbol "*" can be used
6728          * 3) selection will start with transport dataType and THEN go to "*" if needed
6729          */
6730         transports = {},
6731
6732         // Document location
6733         ajaxLocation,
6734
6735         // Document location segments
6736         ajaxLocParts,
6737         
6738         // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
6739         allTypes = ["*/"] + ["*"];
6740
6741 // #8138, IE may throw an exception when accessing
6742 // a field from window.location if document.domain has been set
6743 try {
6744         ajaxLocation = location.href;
6745 } catch( e ) {
6746         // Use the href attribute of an A element
6747         // since IE will modify it given document.location
6748         ajaxLocation = document.createElement( "a" );
6749         ajaxLocation.href = "";
6750         ajaxLocation = ajaxLocation.href;
6751 }
6752
6753 // Segment location into parts
6754 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6755
6756 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6757 function addToPrefiltersOrTransports( structure ) {
6758
6759         // dataTypeExpression is optional and defaults to "*"
6760         return function( dataTypeExpression, func ) {
6761
6762                 if ( typeof dataTypeExpression !== "string" ) {
6763                         func = dataTypeExpression;
6764                         dataTypeExpression = "*";
6765                 }
6766
6767                 if ( jQuery.isFunction( func ) ) {
6768                         var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
6769                                 i = 0,
6770                                 length = dataTypes.length,
6771                                 dataType,
6772                                 list,
6773                                 placeBefore;
6774
6775                         // For each dataType in the dataTypeExpression
6776                         for(; i < length; i++ ) {
6777                                 dataType = dataTypes[ i ];
6778                                 // We control if we're asked to add before
6779                                 // any existing element
6780                                 placeBefore = /^\+/.test( dataType );
6781                                 if ( placeBefore ) {
6782                                         dataType = dataType.substr( 1 ) || "*";
6783                                 }
6784                                 list = structure[ dataType ] = structure[ dataType ] || [];
6785                                 // then we add to the structure accordingly
6786                                 list[ placeBefore ? "unshift" : "push" ]( func );
6787                         }
6788                 }
6789         };
6790 }
6791
6792 // Base inspection function for prefilters and transports
6793 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
6794                 dataType /* internal */, inspected /* internal */ ) {
6795
6796         dataType = dataType || options.dataTypes[ 0 ];
6797         inspected = inspected || {};
6798
6799         inspected[ dataType ] = true;
6800
6801         var list = structure[ dataType ],
6802                 i = 0,
6803                 length = list ? list.length : 0,
6804                 executeOnly = ( structure === prefilters ),
6805                 selection;
6806
6807         for(; i < length && ( executeOnly || !selection ); i++ ) {
6808                 selection = list[ i ]( options, originalOptions, jqXHR );
6809                 // If we got redirected to another dataType
6810                 // we try there if executing only and not done already
6811                 if ( typeof selection === "string" ) {
6812                         if ( !executeOnly || inspected[ selection ] ) {
6813                                 selection = undefined;
6814                         } else {
6815                                 options.dataTypes.unshift( selection );
6816                                 selection = inspectPrefiltersOrTransports(
6817                                                 structure, options, originalOptions, jqXHR, selection, inspected );
6818                         }
6819                 }
6820         }
6821         // If we're only executing or nothing was selected
6822         // we try the catchall dataType if not done already
6823         if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
6824                 selection = inspectPrefiltersOrTransports(
6825                                 structure, options, originalOptions, jqXHR, "*", inspected );
6826         }
6827         // unnecessary when only executing (prefilters)
6828         // but it'll be ignored by the caller in that case
6829         return selection;
6830 }
6831
6832 // A special extend for ajax options
6833 // that takes "flat" options (not to be deep extended)
6834 // Fixes #9887
6835 function ajaxExtend( target, src ) {
6836         var key, deep,
6837                 flatOptions = jQuery.ajaxSettings.flatOptions || {};
6838         for( key in src ) {
6839                 if ( src[ key ] !== undefined ) {
6840                         ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
6841                 }
6842         }
6843         if ( deep ) {
6844                 jQuery.extend( true, target, deep );
6845         }
6846 }
6847
6848 jQuery.fn.extend({
6849         load: function( url, params, callback ) {
6850                 if ( typeof url !== "string" && _load ) {
6851                         return _load.apply( this, arguments );
6852
6853                 // Don't do a request if no elements are being requested
6854                 } else if ( !this.length ) {
6855                         return this;
6856                 }
6857
6858                 var off = url.indexOf( " " );
6859                 if ( off >= 0 ) {
6860                         var selector = url.slice( off, url.length );
6861                         url = url.slice( 0, off );
6862                 }
6863
6864                 // Default to a GET request
6865                 var type = "GET";
6866
6867                 // If the second parameter was provided
6868                 if ( params ) {
6869                         // If it's a function
6870                         if ( jQuery.isFunction( params ) ) {
6871                                 // We assume that it's the callback
6872                                 callback = params;
6873                                 params = undefined;
6874
6875                         // Otherwise, build a param string
6876                         } else if ( typeof params === "object" ) {
6877                                 params = jQuery.param( params, jQuery.ajaxSettings.traditional );
6878                                 type = "POST";
6879                         }
6880                 }
6881
6882                 var self = this;
6883
6884                 // Request the remote document
6885                 jQuery.ajax({
6886                         url: url,
6887                         type: type,
6888                         dataType: "html",
6889                         data: params,
6890                         // Complete callback (responseText is used internally)
6891                         complete: function( jqXHR, status, responseText ) {
6892                                 // Store the response as specified by the jqXHR object
6893                                 responseText = jqXHR.responseText;
6894                                 // If successful, inject the HTML into all the matched elements
6895                                 if ( jqXHR.isResolved() ) {
6896                                         // #4825: Get the actual response in case
6897                                         // a dataFilter is present in ajaxSettings
6898                                         jqXHR.done(function( r ) {
6899                                                 responseText = r;
6900                                         });
6901                                         // See if a selector was specified
6902                                         self.html( selector ?
6903                                                 // Create a dummy div to hold the results
6904                                                 jQuery("<div>")
6905                                                         // inject the contents of the document in, removing the scripts
6906                                                         // to avoid any 'Permission Denied' errors in IE
6907                                                         .append(responseText.replace(rscript, ""))
6908
6909                                                         // Locate the specified elements
6910                                                         .find(selector) :
6911
6912                                                 // If not, just inject the full result
6913                                                 responseText );
6914                                 }
6915
6916                                 if ( callback ) {
6917                                         self.each( callback, [ responseText, status, jqXHR ] );
6918                                 }
6919                         }
6920                 });
6921
6922                 return this;
6923         },
6924
6925         serialize: function() {
6926                 return jQuery.param( this.serializeArray() );
6927         },
6928
6929         serializeArray: function() {
6930                 return this.map(function(){
6931                         return this.elements ? jQuery.makeArray( this.elements ) : this;
6932                 })
6933                 .filter(function(){
6934                         return this.name && !this.disabled &&
6935                                 ( this.checked || rselectTextarea.test( this.nodeName ) ||
6936                                         rinput.test( this.type ) );
6937                 })
6938                 .map(function( i, elem ){
6939                         var val = jQuery( this ).val();
6940
6941                         return val == null ?
6942                                 null :
6943                                 jQuery.isArray( val ) ?
6944                                         jQuery.map( val, function( val, i ){
6945                                                 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6946                                         }) :
6947                                         { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6948                 }).get();
6949         }
6950 });
6951
6952 // Attach a bunch of functions for handling common AJAX events
6953 jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
6954         jQuery.fn[ o ] = function( f ){
6955                 return this.bind( o, f );
6956         };
6957 });
6958
6959 jQuery.each( [ "get", "post" ], function( i, method ) {
6960         jQuery[ method ] = function( url, data, callback, type ) {
6961                 // shift arguments if data argument was omitted
6962                 if ( jQuery.isFunction( data ) ) {
6963                         type = type || callback;
6964                         callback = data;
6965                         data = undefined;
6966                 }
6967
6968                 return jQuery.ajax({
6969                         type: method,
6970                         url: url,
6971                         data: data,
6972                         success: callback,
6973                         dataType: type
6974                 });
6975         };
6976 });
6977
6978 jQuery.extend({
6979
6980         getScript: function( url, callback ) {
6981                 return jQuery.get( url, undefined, callback, "script" );
6982         },
6983
6984         getJSON: function( url, data, callback ) {
6985                 return jQuery.get( url, data, callback, "json" );
6986         },
6987
6988         // Creates a full fledged settings object into target
6989         // with both ajaxSettings and settings fields.
6990         // If target is omitted, writes into ajaxSettings.
6991         ajaxSetup: function( target, settings ) {
6992                 if ( settings ) {
6993                         // Building a settings object
6994                         ajaxExtend( target, jQuery.ajaxSettings );
6995                 } else {
6996                         // Extending ajaxSettings
6997                         settings = target;
6998                         target = jQuery.ajaxSettings;
6999                 }
7000                 ajaxExtend( target, settings );
7001                 return target;
7002         },
7003
7004         ajaxSettings: {
7005                 url: ajaxLocation,
7006                 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7007                 global: true,
7008                 type: "GET",
7009                 contentType: "application/x-www-form-urlencoded",
7010                 processData: true,
7011                 async: true,
7012                 /*
7013                 timeout: 0,
7014                 data: null,
7015                 dataType: null,
7016                 username: null,
7017                 password: null,
7018                 cache: null,
7019                 traditional: false,
7020                 headers: {},
7021                 */
7022
7023                 accepts: {
7024                         xml: "application/xml, text/xml",
7025                         html: "text/html",
7026                         text: "text/plain",
7027                         json: "application/json, text/javascript",
7028                         "*": allTypes
7029                 },
7030
7031                 contents: {
7032                         xml: /xml/,
7033                         html: /html/,
7034                         json: /json/
7035                 },
7036
7037                 responseFields: {
7038                         xml: "responseXML",
7039                         text: "responseText"
7040                 },
7041
7042                 // List of data converters
7043                 // 1) key format is "source_type destination_type" (a single space in-between)
7044                 // 2) the catchall symbol "*" can be used for source_type
7045                 converters: {
7046
7047                         // Convert anything to text
7048                         "* text": window.String,
7049
7050                         // Text to html (true = no transformation)
7051                         "text html": true,
7052
7053                         // Evaluate text as a json expression
7054                         "text json": jQuery.parseJSON,
7055
7056                         // Parse text as xml
7057                         "text xml": jQuery.parseXML
7058                 },
7059
7060                 // For options that shouldn't be deep extended:
7061                 // you can add your own custom options here if
7062                 // and when you create one that shouldn't be
7063                 // deep extended (see ajaxExtend)
7064                 flatOptions: {
7065                         context: true,
7066                         url: true
7067                 }
7068         },
7069
7070         ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7071         ajaxTransport: addToPrefiltersOrTransports( transports ),
7072
7073         // Main method
7074         ajax: function( url, options ) {
7075
7076                 // If url is an object, simulate pre-1.5 signature
7077                 if ( typeof url === "object" ) {
7078                         options = url;
7079                         url = undefined;
7080                 }
7081
7082                 // Force options to be an object
7083                 options = options || {};
7084
7085                 var // Create the final options object
7086                         s = jQuery.ajaxSetup( {}, options ),
7087                         // Callbacks context
7088                         callbackContext = s.context || s,
7089                         // Context for global events
7090                         // It's the callbackContext if one was provided in the options
7091                         // and if it's a DOM node or a jQuery collection
7092                         globalEventContext = callbackContext !== s &&
7093                                 ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
7094                                                 jQuery( callbackContext ) : jQuery.event,
7095                         // Deferreds
7096                         deferred = jQuery.Deferred(),
7097                         completeDeferred = jQuery._Deferred(),
7098                         // Status-dependent callbacks
7099                         statusCode = s.statusCode || {},
7100                         // ifModified key
7101                         ifModifiedKey,
7102                         // Headers (they are sent all at once)
7103                         requestHeaders = {},
7104                         requestHeadersNames = {},
7105                         // Response headers
7106                         responseHeadersString,
7107                         responseHeaders,
7108                         // transport
7109                         transport,
7110                         // timeout handle
7111                         timeoutTimer,
7112                         // Cross-domain detection vars
7113                         parts,
7114                         // The jqXHR state
7115                         state = 0,
7116                         // To know if global events are to be dispatched
7117                         fireGlobals,
7118                         // Loop variable
7119                         i,
7120                         // Fake xhr
7121                         jqXHR = {
7122
7123                                 readyState: 0,
7124
7125                                 // Caches the header
7126                                 setRequestHeader: function( name, value ) {
7127                                         if ( !state ) {
7128                                                 var lname = name.toLowerCase();
7129                                                 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7130                                                 requestHeaders[ name ] = value;
7131                                         }
7132                                         return this;
7133                                 },
7134
7135                                 // Raw string
7136                                 getAllResponseHeaders: function() {
7137                                         return state === 2 ? responseHeadersString : null;
7138                                 },
7139
7140                                 // Builds headers hashtable if needed
7141                                 getResponseHeader: function( key ) {
7142                                         var match;
7143                                         if ( state === 2 ) {
7144                                                 if ( !responseHeaders ) {
7145                                                         responseHeaders = {};
7146                                                         while( ( match = rheaders.exec( responseHeadersString ) ) ) {
7147                                                                 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7148                                                         }
7149                                                 }
7150                                                 match = responseHeaders[ key.toLowerCase() ];
7151                                         }
7152                                         return match === undefined ? null : match;
7153                                 },
7154
7155                                 // Overrides response content-type header
7156                                 overrideMimeType: function( type ) {
7157                                         if ( !state ) {
7158                                                 s.mimeType = type;
7159                                         }
7160                                         return this;
7161                                 },
7162
7163                                 // Cancel the request
7164                                 abort: function( statusText ) {
7165                                         statusText = statusText || "abort";
7166                                         if ( transport ) {
7167                                                 transport.abort( statusText );
7168                                         }
7169                                         done( 0, statusText );
7170                                         return this;
7171                                 }
7172                         };
7173
7174                 // Callback for when everything is done
7175                 // It is defined here because jslint complains if it is declared
7176                 // at the end of the function (which would be more logical and readable)
7177                 function done( status, nativeStatusText, responses, headers ) {
7178
7179                         // Called once
7180                         if ( state === 2 ) {
7181                                 return;
7182                         }
7183
7184                         // State is "done" now
7185                         state = 2;
7186
7187                         // Clear timeout if it exists
7188                         if ( timeoutTimer ) {
7189                                 clearTimeout( timeoutTimer );
7190                         }
7191
7192                         // Dereference transport for early garbage collection
7193                         // (no matter how long the jqXHR object will be used)
7194                         transport = undefined;
7195
7196                         // Cache response headers
7197                         responseHeadersString = headers || "";
7198
7199                         // Set readyState
7200                         jqXHR.readyState = status > 0 ? 4 : 0;
7201
7202                         var isSuccess,
7203                                 success,
7204                                 error,
7205                                 statusText = nativeStatusText,
7206                                 response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
7207                                 lastModified,
7208                                 etag;
7209
7210                         // If successful, handle type chaining
7211                         if ( status >= 200 && status < 300 || status === 304 ) {
7212
7213                                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7214                                 if ( s.ifModified ) {
7215
7216                                         if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
7217                                                 jQuery.lastModified[ ifModifiedKey ] = lastModified;
7218                                         }
7219                                         if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
7220                                                 jQuery.etag[ ifModifiedKey ] = etag;
7221                                         }
7222                                 }
7223
7224                                 // If not modified
7225                                 if ( status === 304 ) {
7226
7227                                         statusText = "notmodified";
7228                                         isSuccess = true;
7229
7230                                 // If we have data
7231                                 } else {
7232
7233                                         try {
7234                                                 success = ajaxConvert( s, response );
7235                                                 statusText = "success";
7236                                                 isSuccess = true;
7237                                         } catch(e) {
7238                                                 // We have a parsererror
7239                                                 statusText = "parsererror";
7240                                                 error = e;
7241                                         }
7242                                 }
7243                         } else {
7244                                 // We extract error from statusText
7245                                 // then normalize statusText and status for non-aborts
7246                                 error = statusText;
7247                                 if( !statusText || status ) {
7248                                         statusText = "error";
7249                                         if ( status < 0 ) {
7250                                                 status = 0;
7251                                         }
7252                                 }
7253                         }
7254
7255                         // Set data for the fake xhr object
7256                         jqXHR.status = status;
7257                         jqXHR.statusText = "" + ( nativeStatusText || statusText );
7258
7259                         // Success/Error
7260                         if ( isSuccess ) {
7261                                 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7262                         } else {
7263                                 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7264                         }
7265
7266                         // Status-dependent callbacks
7267                         jqXHR.statusCode( statusCode );
7268                         statusCode = undefined;
7269
7270                         if ( fireGlobals ) {
7271                                 globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
7272                                                 [ jqXHR, s, isSuccess ? success : error ] );
7273                         }
7274
7275                         // Complete
7276                         completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
7277
7278                         if ( fireGlobals ) {
7279                                 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7280                                 // Handle the global AJAX counter
7281                                 if ( !( --jQuery.active ) ) {
7282                                         jQuery.event.trigger( "ajaxStop" );
7283                                 }
7284                         }
7285                 }
7286
7287                 // Attach deferreds
7288                 deferred.promise( jqXHR );
7289                 jqXHR.success = jqXHR.done;
7290                 jqXHR.error = jqXHR.fail;
7291                 jqXHR.complete = completeDeferred.done;
7292
7293                 // Status-dependent callbacks
7294                 jqXHR.statusCode = function( map ) {
7295                         if ( map ) {
7296                                 var tmp;
7297                                 if ( state < 2 ) {
7298                                         for( tmp in map ) {
7299                                                 statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
7300                                         }
7301                                 } else {
7302                                         tmp = map[ jqXHR.status ];
7303                                         jqXHR.then( tmp, tmp );
7304                                 }
7305                         }
7306                         return this;
7307                 };
7308
7309                 // Remove hash character (#7531: and string promotion)
7310                 // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
7311                 // We also use the url parameter if available
7312                 s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7313
7314                 // Extract dataTypes list
7315                 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
7316
7317                 // Determine if a cross-domain request is in order
7318                 if ( s.crossDomain == null ) {
7319                         parts = rurl.exec( s.url.toLowerCase() );
7320                         s.crossDomain = !!( parts &&
7321                                 ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
7322                                         ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
7323                                                 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
7324                         );
7325                 }
7326
7327                 // Convert data if not already a string
7328                 if ( s.data && s.processData && typeof s.data !== "string" ) {
7329                         s.data = jQuery.param( s.data, s.traditional );
7330                 }
7331
7332                 // Apply prefilters
7333                 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7334
7335                 // If request was aborted inside a prefiler, stop there
7336                 if ( state === 2 ) {
7337                         return false;
7338                 }
7339
7340                 // We can fire global events as of now if asked to
7341                 fireGlobals = s.global;
7342
7343                 // Uppercase the type
7344                 s.type = s.type.toUpperCase();
7345
7346                 // Determine if request has content
7347                 s.hasContent = !rnoContent.test( s.type );
7348
7349                 // Watch for a new set of requests
7350                 if ( fireGlobals && jQuery.active++ === 0 ) {
7351                         jQuery.event.trigger( "ajaxStart" );
7352                 }
7353
7354                 // More options handling for requests with no content
7355                 if ( !s.hasContent ) {
7356
7357                         // If data is available, append data to url
7358                         if ( s.data ) {
7359                                 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
7360                                 // #9682: remove data so that it's not used in an eventual retry
7361                                 delete s.data;
7362                         }
7363
7364                         // Get ifModifiedKey before adding the anti-cache parameter
7365                         ifModifiedKey = s.url;
7366
7367                         // Add anti-cache in url if needed
7368                         if ( s.cache === false ) {
7369
7370                                 var ts = jQuery.now(),
7371                                         // try replacing _= if it is there
7372                                         ret = s.url.replace( rts, "$1_=" + ts );
7373
7374                                 // if nothing was replaced, add timestamp to the end
7375                                 s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
7376                         }
7377                 }
7378
7379                 // Set the correct header, if data is being sent
7380                 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7381                         jqXHR.setRequestHeader( "Content-Type", s.contentType );
7382                 }
7383
7384                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7385                 if ( s.ifModified ) {
7386                         ifModifiedKey = ifModifiedKey || s.url;
7387                         if ( jQuery.lastModified[ ifModifiedKey ] ) {
7388                                 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
7389                         }
7390                         if ( jQuery.etag[ ifModifiedKey ] ) {
7391                                 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
7392                         }
7393                 }
7394
7395                 // Set the Accepts header for the server, depending on the dataType
7396                 jqXHR.setRequestHeader(
7397                         "Accept",
7398                         s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7399                                 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7400                                 s.accepts[ "*" ]
7401                 );
7402
7403                 // Check for headers option
7404                 for ( i in s.headers ) {
7405                         jqXHR.setRequestHeader( i, s.headers[ i ] );
7406                 }
7407
7408                 // Allow custom headers/mimetypes and early abort
7409                 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7410                                 // Abort if not done already
7411                                 jqXHR.abort();
7412                                 return false;
7413
7414                 }
7415
7416                 // Install callbacks on deferreds
7417                 for ( i in { success: 1, error: 1, complete: 1 } ) {
7418                         jqXHR[ i ]( s[ i ] );
7419                 }
7420
7421                 // Get transport
7422                 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7423
7424                 // If no transport, we auto-abort
7425                 if ( !transport ) {
7426                         done( -1, "No Transport" );
7427                 } else {
7428                         jqXHR.readyState = 1;
7429                         // Send global event
7430                         if ( fireGlobals ) {
7431                                 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7432                         }
7433                         // Timeout
7434                         if ( s.async && s.timeout > 0 ) {
7435                                 timeoutTimer = setTimeout( function(){
7436                                         jqXHR.abort( "timeout" );
7437                                 }, s.timeout );
7438                         }
7439
7440                         try {
7441                                 state = 1;
7442                                 transport.send( requestHeaders, done );
7443                         } catch (e) {
7444                                 // Propagate exception as error if not done
7445                                 if ( state < 2 ) {
7446                                         done( -1, e );
7447                                 // Simply rethrow otherwise
7448                                 } else {
7449                                         jQuery.error( e );
7450                                 }
7451                         }
7452                 }
7453
7454                 return jqXHR;
7455         },
7456
7457         // Serialize an array of form elements or a set of
7458         // key/values into a query string
7459         param: function( a, traditional ) {
7460                 var s = [],
7461                         add = function( key, value ) {
7462                                 // If value is a function, invoke it and return its value
7463                                 value = jQuery.isFunction( value ) ? value() : value;
7464                                 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
7465                         };
7466
7467                 // Set traditional to true for jQuery <= 1.3.2 behavior.
7468                 if ( traditional === undefined ) {
7469                         traditional = jQuery.ajaxSettings.traditional;
7470                 }
7471
7472                 // If an array was passed in, assume that it is an array of form elements.
7473                 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
7474                         // Serialize the form elements
7475                         jQuery.each( a, function() {
7476                                 add( this.name, this.value );
7477                         });
7478
7479                 } else {
7480                         // If traditional, encode the "old" way (the way 1.3.2 or older
7481                         // did it), otherwise encode params recursively.
7482                         for ( var prefix in a ) {
7483                                 buildParams( prefix, a[ prefix ], traditional, add );
7484                         }
7485                 }
7486
7487                 // Return the resulting serialization
7488                 return s.join( "&" ).replace( r20, "+" );
7489         }
7490 });
7491
7492 function buildParams( prefix, obj, traditional, add ) {
7493         if ( jQuery.isArray( obj ) ) {
7494                 // Serialize array item.
7495                 jQuery.each( obj, function( i, v ) {
7496                         if ( traditional || rbracket.test( prefix ) ) {
7497                                 // Treat each array item as a scalar.
7498                                 add( prefix, v );
7499
7500                         } else {
7501                                 // If array item is non-scalar (array or object), encode its
7502                                 // numeric index to resolve deserialization ambiguity issues.
7503                                 // Note that rack (as of 1.0.0) can't currently deserialize
7504                                 // nested arrays properly, and attempting to do so may cause
7505                                 // a server error. Possible fixes are to modify rack's
7506                                 // deserialization algorithm or to provide an option or flag
7507                                 // to force array serialization to be shallow.
7508                                 buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
7509                         }
7510                 });
7511
7512         } else if ( !traditional && obj != null && typeof obj === "object" ) {
7513                 // Serialize object item.
7514                 for ( var name in obj ) {
7515                         buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
7516                 }
7517
7518         } else {
7519                 // Serialize scalar item.
7520                 add( prefix, obj );
7521         }
7522 }
7523
7524 // This is still on the jQuery object... for now
7525 // Want to move this to jQuery.ajax some day
7526 jQuery.extend({
7527
7528         // Counter for holding the number of active queries
7529         active: 0,
7530
7531         // Last-Modified header cache for next request
7532         lastModified: {},
7533         etag: {}
7534
7535 });
7536
7537 /* Handles responses to an ajax request:
7538  * - sets all responseXXX fields accordingly
7539  * - finds the right dataType (mediates between content-type and expected dataType)
7540  * - returns the corresponding response
7541  */
7542 function ajaxHandleResponses( s, jqXHR, responses ) {
7543
7544         var contents = s.contents,
7545                 dataTypes = s.dataTypes,
7546                 responseFields = s.responseFields,
7547                 ct,
7548                 type,
7549                 finalDataType,
7550                 firstDataType;
7551
7552         // Fill responseXXX fields
7553         for( type in responseFields ) {
7554                 if ( type in responses ) {
7555                         jqXHR[ responseFields[type] ] = responses[ type ];
7556                 }
7557         }
7558
7559         // Remove auto dataType and get content-type in the process
7560         while( dataTypes[ 0 ] === "*" ) {
7561                 dataTypes.shift();
7562                 if ( ct === undefined ) {
7563                         ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
7564                 }
7565         }
7566
7567         // Check if we're dealing with a known content-type
7568         if ( ct ) {
7569                 for ( type in contents ) {
7570                         if ( contents[ type ] && contents[ type ].test( ct ) ) {
7571                                 dataTypes.unshift( type );
7572                                 break;
7573                         }
7574                 }
7575         }
7576
7577         // Check to see if we have a response for the expected dataType
7578         if ( dataTypes[ 0 ] in responses ) {
7579                 finalDataType = dataTypes[ 0 ];
7580         } else {
7581                 // Try convertible dataTypes
7582                 for ( type in responses ) {
7583                         if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7584                                 finalDataType = type;
7585                                 break;
7586                         }
7587                         if ( !firstDataType ) {
7588                                 firstDataType = type;
7589                         }
7590                 }
7591                 // Or just use first one
7592                 finalDataType = finalDataType || firstDataType;
7593         }
7594
7595         // If we found a dataType
7596         // We add the dataType to the list if needed
7597         // and return the corresponding response
7598         if ( finalDataType ) {
7599                 if ( finalDataType !== dataTypes[ 0 ] ) {
7600                         dataTypes.unshift( finalDataType );
7601                 }
7602                 return responses[ finalDataType ];
7603         }
7604 }
7605
7606 // Chain conversions given the request and the original response
7607 function ajaxConvert( s, response ) {
7608
7609         // Apply the dataFilter if provided
7610         if ( s.dataFilter ) {
7611                 response = s.dataFilter( response, s.dataType );
7612         }
7613
7614         var dataTypes = s.dataTypes,
7615                 converters = {},
7616                 i,
7617                 key,
7618                 length = dataTypes.length,
7619                 tmp,
7620                 // Current and previous dataTypes
7621                 current = dataTypes[ 0 ],
7622                 prev,
7623                 // Conversion expression
7624                 conversion,
7625                 // Conversion function
7626                 conv,
7627                 // Conversion functions (transitive conversion)
7628                 conv1,
7629                 conv2;
7630
7631         // For each dataType in the chain
7632         for( i = 1; i < length; i++ ) {
7633
7634                 // Create converters map
7635                 // with lowercased keys
7636                 if ( i === 1 ) {
7637                         for( key in s.converters ) {
7638                                 if( typeof key === "string" ) {
7639                                         converters[ key.toLowerCase() ] = s.converters[ key ];
7640                                 }
7641                         }
7642                 }
7643
7644                 // Get the dataTypes
7645                 prev = current;
7646                 current = dataTypes[ i ];
7647
7648                 // If current is auto dataType, update it to prev
7649                 if( current === "*" ) {
7650                         current = prev;
7651                 // If no auto and dataTypes are actually different
7652                 } else if ( prev !== "*" && prev !== current ) {
7653
7654                         // Get the converter
7655                         conversion = prev + " " + current;
7656                         conv = converters[ conversion ] || converters[ "* " + current ];
7657
7658                         // If there is no direct converter, search transitively
7659                         if ( !conv ) {
7660                                 conv2 = undefined;
7661                                 for( conv1 in converters ) {
7662                                         tmp = conv1.split( " " );
7663                                         if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
7664                                                 conv2 = converters[ tmp[1] + " " + current ];
7665                                                 if ( conv2 ) {
7666                                                         conv1 = converters[ conv1 ];
7667                                                         if ( conv1 === true ) {
7668                                                                 conv = conv2;
7669                                                         } else if ( conv2 === true ) {
7670                                                                 conv = conv1;
7671                                                         }
7672                                                         break;
7673                                                 }
7674                                         }
7675                                 }
7676                         }
7677                         // If we found no converter, dispatch an error
7678                         if ( !( conv || conv2 ) ) {
7679                                 jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
7680                         }
7681                         // If found converter is not an equivalence
7682                         if ( conv !== true ) {
7683                                 // Convert with 1 or 2 converters accordingly
7684                                 response = conv ? conv( response ) : conv2( conv1(response) );
7685                         }
7686                 }
7687         }
7688         return response;
7689 }
7690
7691
7692
7693
7694 var jsc = jQuery.now(),
7695         jsre = /(\=)\?(&|$)|\?\?/i;
7696
7697 // Default jsonp settings
7698 jQuery.ajaxSetup({
7699         jsonp: "callback",
7700         jsonpCallback: function() {
7701                 return jQuery.expando + "_" + ( jsc++ );
7702         }
7703 });
7704
7705 // Detect, normalize options and install callbacks for jsonp requests
7706 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7707
7708         var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
7709                 ( typeof s.data === "string" );
7710
7711         if ( s.dataTypes[ 0 ] === "jsonp" ||
7712                 s.jsonp !== false && ( jsre.test( s.url ) ||
7713                                 inspectData && jsre.test( s.data ) ) ) {
7714
7715                 var responseContainer,
7716                         jsonpCallback = s.jsonpCallback =
7717                                 jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
7718                         previous = window[ jsonpCallback ],
7719                         url = s.url,
7720                         data = s.data,
7721                         replace = "$1" + jsonpCallback + "$2";
7722
7723                 if ( s.jsonp !== false ) {
7724                         url = url.replace( jsre, replace );
7725                         if ( s.url === url ) {
7726                                 if ( inspectData ) {
7727                                         data = data.replace( jsre, replace );
7728                                 }
7729                                 if ( s.data === data ) {
7730                                         // Add callback manually
7731                                         url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
7732                                 }
7733                         }
7734                 }
7735
7736                 s.url = url;
7737                 s.data = data;
7738
7739                 // Install callback
7740                 window[ jsonpCallback ] = function( response ) {
7741                         responseContainer = [ response ];
7742                 };
7743
7744                 // Clean-up function
7745                 jqXHR.always(function() {
7746                         // Set callback back to previous value
7747                         window[ jsonpCallback ] = previous;
7748                         // Call if it was a function and we have a response
7749                         if ( responseContainer && jQuery.isFunction( previous ) ) {
7750                                 window[ jsonpCallback ]( responseContainer[ 0 ] );
7751                         }
7752                 });
7753
7754                 // Use data converter to retrieve json after script execution
7755                 s.converters["script json"] = function() {
7756                         if ( !responseContainer ) {
7757                                 jQuery.error( jsonpCallback + " was not called" );
7758                         }
7759                         return responseContainer[ 0 ];
7760                 };
7761
7762                 // force json dataType
7763                 s.dataTypes[ 0 ] = "json";
7764
7765                 // Delegate to script
7766                 return "script";
7767         }
7768 });
7769
7770
7771
7772
7773 // Install script dataType
7774 jQuery.ajaxSetup({
7775         accepts: {
7776                 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7777         },
7778         contents: {
7779                 script: /javascript|ecmascript/
7780         },
7781         converters: {
7782                 "text script": function( text ) {
7783                         jQuery.globalEval( text );
7784                         return text;
7785                 }
7786         }
7787 });
7788
7789 // Handle cache's special case and global
7790 jQuery.ajaxPrefilter( "script", function( s ) {
7791         if ( s.cache === undefined ) {
7792                 s.cache = false;
7793         }
7794         if ( s.crossDomain ) {
7795                 s.type = "GET";
7796                 s.global = false;
7797         }
7798 });
7799
7800 // Bind script tag hack transport
7801 jQuery.ajaxTransport( "script", function(s) {
7802
7803         // This transport only deals with cross domain requests
7804         if ( s.crossDomain ) {
7805
7806                 var script,
7807                         head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
7808
7809                 return {
7810
7811                         send: function( _, callback ) {
7812
7813                                 script = document.createElement( "script" );
7814
7815                                 script.async = "async";
7816
7817                                 if ( s.scriptCharset ) {
7818                                         script.charset = s.scriptCharset;
7819                                 }
7820
7821                                 script.src = s.url;
7822
7823                                 // Attach handlers for all browsers
7824                                 script.onload = script.onreadystatechange = function( _, isAbort ) {
7825
7826                                         if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
7827
7828                                                 // Handle memory leak in IE
7829                                                 script.onload = script.onreadystatechange = null;
7830
7831                                                 // Remove the script
7832                                                 if ( head && script.parentNode ) {
7833                                                         head.removeChild( script );
7834                                                 }
7835
7836                                                 // Dereference the script
7837                                                 script = undefined;
7838
7839                                                 // Callback if not abort
7840                                                 if ( !isAbort ) {
7841                                                         callback( 200, "success" );
7842                                                 }
7843                                         }
7844                                 };
7845                                 // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
7846                                 // This arises when a base node is used (#2709 and #4378).
7847                                 head.insertBefore( script, head.firstChild );
7848                         },
7849
7850                         abort: function() {
7851                                 if ( script ) {
7852                                         script.onload( 0, 1 );
7853                                 }
7854                         }
7855                 };
7856         }
7857 });
7858
7859
7860
7861
7862 var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
7863         xhrOnUnloadAbort = window.ActiveXObject ? function() {
7864                 // Abort all pending requests
7865                 for ( var key in xhrCallbacks ) {
7866                         xhrCallbacks[ key ]( 0, 1 );
7867                 }
7868         } : false,
7869         xhrId = 0,
7870         xhrCallbacks;
7871
7872 // Functions to create xhrs
7873 function createStandardXHR() {
7874         try {
7875                 return new window.XMLHttpRequest();
7876         } catch( e ) {}
7877 }
7878
7879 function createActiveXHR() {
7880         try {
7881                 return new window.ActiveXObject( "Microsoft.XMLHTTP" );
7882         } catch( e ) {}
7883 }
7884
7885 // Create the request object
7886 // (This is still attached to ajaxSettings for backward compatibility)
7887 jQuery.ajaxSettings.xhr = window.ActiveXObject ?
7888         /* Microsoft failed to properly
7889          * implement the XMLHttpRequest in IE7 (can't request local files),
7890          * so we use the ActiveXObject when it is available
7891          * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
7892          * we need a fallback.
7893          */
7894         function() {
7895                 return !this.isLocal && createStandardXHR() || createActiveXHR();
7896         } :
7897         // For all other browsers, use the standard XMLHttpRequest object
7898         createStandardXHR;
7899
7900 // Determine support properties
7901 (function( xhr ) {
7902         jQuery.extend( jQuery.support, {
7903                 ajax: !!xhr,
7904                 cors: !!xhr && ( "withCredentials" in xhr )
7905         });
7906 })( jQuery.ajaxSettings.xhr() );
7907
7908 // Create transport if the browser can provide an xhr
7909 if ( jQuery.support.ajax ) {
7910
7911         jQuery.ajaxTransport(function( s ) {
7912                 // Cross domain only allowed if supported through XMLHttpRequest
7913                 if ( !s.crossDomain || jQuery.support.cors ) {
7914
7915                         var callback;
7916
7917                         return {
7918                                 send: function( headers, complete ) {
7919
7920                                         // Get a new xhr
7921                                         var xhr = s.xhr(),
7922                                                 handle,
7923                                                 i;
7924
7925                                         // Open the socket
7926                                         // Passing null username, generates a login popup on Opera (#2865)
7927                                         if ( s.username ) {
7928                                                 xhr.open( s.type, s.url, s.async, s.username, s.password );
7929                                         } else {
7930                                                 xhr.open( s.type, s.url, s.async );
7931                                         }
7932
7933                                         // Apply custom fields if provided
7934                                         if ( s.xhrFields ) {
7935                                                 for ( i in s.xhrFields ) {
7936                                                         xhr[ i ] = s.xhrFields[ i ];
7937                                                 }
7938                                         }
7939
7940                                         // Override mime type if needed
7941                                         if ( s.mimeType && xhr.overrideMimeType ) {
7942                                                 xhr.overrideMimeType( s.mimeType );
7943                                         }
7944
7945                                         // X-Requested-With header
7946                                         // For cross-domain requests, seeing as conditions for a preflight are
7947                                         // akin to a jigsaw puzzle, we simply never set it to be sure.
7948                                         // (it can always be set on a per-request basis or even using ajaxSetup)
7949                                         // For same-domain requests, won't change header if already provided.
7950                                         if ( !s.crossDomain && !headers["X-Requested-With"] ) {
7951                                                 headers[ "X-Requested-With" ] = "XMLHttpRequest";
7952                                         }
7953
7954                                         // Need an extra try/catch for cross domain requests in Firefox 3
7955                                         try {
7956                                                 for ( i in headers ) {
7957                                                         xhr.setRequestHeader( i, headers[ i ] );
7958                                                 }
7959                                         } catch( _ ) {}
7960
7961                                         // Do send the request
7962                                         // This may raise an exception which is actually
7963                                         // handled in jQuery.ajax (so no try/catch here)
7964                                         xhr.send( ( s.hasContent && s.data ) || null );
7965
7966                                         // Listener
7967                                         callback = function( _, isAbort ) {
7968
7969                                                 var status,
7970                                                         statusText,
7971                                                         responseHeaders,
7972                                                         responses,
7973                                                         xml;
7974
7975                                                 // Firefox throws exceptions when accessing properties
7976                                                 // of an xhr when a network error occured
7977                                                 // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
7978                                                 try {
7979
7980                                                         // Was never called and is aborted or complete
7981                                                         if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
7982
7983                                                                 // Only called once
7984                                                                 callback = undefined;
7985
7986                                                                 // Do not keep as active anymore
7987                                                                 if ( handle ) {
7988                                                                         xhr.onreadystatechange = jQuery.noop;
7989                                                                         if ( xhrOnUnloadAbort ) {
7990                                                                                 delete xhrCallbacks[ handle ];
7991                                                                         }
7992                                                                 }
7993
7994                                                                 // If it's an abort
7995                                                                 if ( isAbort ) {
7996                                                                         // Abort it manually if needed
7997                                                                         if ( xhr.readyState !== 4 ) {
7998                                                                                 xhr.abort();
7999                                                                         }
8000                                                                 } else {
8001                                                                         status = xhr.status;
8002                                                                         responseHeaders = xhr.getAllResponseHeaders();
8003                                                                         responses = {};
8004                                                                         xml = xhr.responseXML;
8005
8006                                                                         // Construct response list
8007                                                                         if ( xml && xml.documentElement /* #4958 */ ) {
8008                                                                                 responses.xml = xml;
8009                                                                         }
8010                                                                         responses.text = xhr.responseText;
8011
8012                                                                         // Firefox throws an exception when accessing
8013                                                                         // statusText for faulty cross-domain requests
8014                                                                         try {
8015                                                                                 statusText = xhr.statusText;
8016                                                                         } catch( e ) {
8017                                                                                 // We normalize with Webkit giving an empty statusText
8018                                                                                 statusText = "";
8019                                                                         }
8020
8021                                                                         // Filter status for non standard behaviors
8022
8023                                                                         // If the request is local and we have data: assume a success
8024                                                                         // (success with no data won't get notified, that's the best we
8025                                                                         // can do given current implementations)
8026                                                                         if ( !status && s.isLocal && !s.crossDomain ) {
8027                                                                                 status = responses.text ? 200 : 404;
8028                                                                         // IE - #1450: sometimes returns 1223 when it should be 204
8029                                                                         } else if ( status === 1223 ) {
8030                                                                                 status = 204;
8031                                                                         }
8032                                                                 }
8033                                                         }
8034                                                 } catch( firefoxAccessException ) {
8035                                                         if ( !isAbort ) {
8036                                                                 complete( -1, firefoxAccessException );
8037                                                         }
8038                                                 }
8039
8040                                                 // Call complete if needed
8041                                                 if ( responses ) {
8042                                                         complete( status, statusText, responses, responseHeaders );
8043                                                 }
8044                                         };
8045
8046                                         // if we're in sync mode or it's in cache
8047                                         // and has been retrieved directly (IE6 & IE7)
8048                                         // we need to manually fire the callback
8049                                         if ( !s.async || xhr.readyState === 4 ) {
8050                                                 callback();
8051                                         } else {
8052                                                 handle = ++xhrId;
8053                                                 if ( xhrOnUnloadAbort ) {
8054                                                         // Create the active xhrs callbacks list if needed
8055                                                         // and attach the unload handler
8056                                                         if ( !xhrCallbacks ) {
8057                                                                 xhrCallbacks = {};
8058                                                                 jQuery( window ).unload( xhrOnUnloadAbort );
8059                                                         }
8060                                                         // Add to list of active xhrs callbacks
8061                                                         xhrCallbacks[ handle ] = callback;
8062                                                 }
8063                                                 xhr.onreadystatechange = callback;
8064                                         }
8065                                 },
8066
8067                                 abort: function() {
8068                                         if ( callback ) {
8069                                                 callback(0,1);
8070                                         }
8071                                 }
8072                         };
8073                 }
8074         });
8075 }
8076
8077
8078
8079
8080 var elemdisplay = {},
8081         iframe, iframeDoc,
8082         rfxtypes = /^(?:toggle|show|hide)$/,
8083         rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
8084         timerId,
8085         fxAttrs = [
8086                 // height animations
8087                 [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
8088                 // width animations
8089                 [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
8090                 // opacity animations
8091                 [ "opacity" ]
8092         ],
8093         fxNow;
8094
8095 jQuery.fn.extend({
8096         show: function( speed, easing, callback ) {
8097                 var elem, display;
8098
8099                 if ( speed || speed === 0 ) {
8100                         return this.animate( genFx("show", 3), speed, easing, callback);
8101
8102                 } else {
8103                         for ( var i = 0, j = this.length; i < j; i++ ) {
8104                                 elem = this[i];
8105
8106                                 if ( elem.style ) {
8107                                         display = elem.style.display;
8108
8109                                         // Reset the inline display of this element to learn if it is
8110                                         // being hidden by cascaded rules or not
8111                                         if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
8112                                                 display = elem.style.display = "";
8113                                         }
8114
8115                                         // Set elements which have been overridden with display: none
8116                                         // in a stylesheet to whatever the default browser style is
8117                                         // for such an element
8118                                         if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
8119                                                 jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
8120                                         }
8121                                 }
8122                         }
8123
8124                         // Set the display of most of the elements in a second loop
8125                         // to avoid the constant reflow
8126                         for ( i = 0; i < j; i++ ) {
8127                                 elem = this[i];
8128
8129                                 if ( elem.style ) {
8130                                         display = elem.style.display;
8131
8132                                         if ( display === "" || display === "none" ) {
8133                                                 elem.style.display = jQuery._data(elem, "olddisplay") || "";
8134                                         }
8135                                 }
8136                         }
8137
8138                         return this;
8139                 }
8140         },
8141
8142         hide: function( speed, easing, callback ) {
8143                 if ( speed || speed === 0 ) {
8144                         return this.animate( genFx("hide", 3), speed, easing, callback);
8145
8146                 } else {
8147                         for ( var i = 0, j = this.length; i < j; i++ ) {
8148                                 if ( this[i].style ) {
8149                                         var display = jQuery.css( this[i], "display" );
8150
8151                                         if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
8152                                                 jQuery._data( this[i], "olddisplay", display );
8153                                         }
8154                                 }
8155                         }
8156
8157                         // Set the display of the elements in a second loop
8158                         // to avoid the constant reflow
8159                         for ( i = 0; i < j; i++ ) {
8160                                 if ( this[i].style ) {
8161                                         this[i].style.display = "none";
8162                                 }
8163                         }
8164
8165                         return this;
8166                 }
8167         },
8168
8169         // Save the old toggle function
8170         _toggle: jQuery.fn.toggle,
8171
8172         toggle: function( fn, fn2, callback ) {
8173                 var bool = typeof fn === "boolean";
8174
8175                 if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
8176                         this._toggle.apply( this, arguments );
8177
8178                 } else if ( fn == null || bool ) {
8179                         this.each(function() {
8180                                 var state = bool ? fn : jQuery(this).is(":hidden");
8181                                 jQuery(this)[ state ? "show" : "hide" ]();
8182                         });
8183
8184                 } else {
8185                         this.animate(genFx("toggle", 3), fn, fn2, callback);
8186                 }
8187
8188                 return this;
8189         },
8190
8191         fadeTo: function( speed, to, easing, callback ) {
8192                 return this.filter(":hidden").css("opacity", 0).show().end()
8193                                         .animate({opacity: to}, speed, easing, callback);
8194         },
8195
8196         animate: function( prop, speed, easing, callback ) {
8197                 var optall = jQuery.speed(speed, easing, callback);
8198
8199                 if ( jQuery.isEmptyObject( prop ) ) {
8200                         return this.each( optall.complete, [ false ] );
8201                 }
8202
8203                 // Do not change referenced properties as per-property easing will be lost
8204                 prop = jQuery.extend( {}, prop );
8205
8206                 return this[ optall.queue === false ? "each" : "queue" ](function() {
8207                         // XXX 'this' does not always have a nodeName when running the
8208                         // test suite
8209
8210                         if ( optall.queue === false ) {
8211                                 jQuery._mark( this );
8212                         }
8213
8214                         var opt = jQuery.extend( {}, optall ),
8215                                 isElement = this.nodeType === 1,
8216                                 hidden = isElement && jQuery(this).is(":hidden"),
8217                                 name, val, p,
8218                                 display, e,
8219                                 parts, start, end, unit;
8220
8221                         // will store per property easing and be used to determine when an animation is complete
8222                         opt.animatedProperties = {};
8223
8224                         for ( p in prop ) {
8225
8226                                 // property name normalization
8227                                 name = jQuery.camelCase( p );
8228                                 if ( p !== name ) {
8229                                         prop[ name ] = prop[ p ];
8230                                         delete prop[ p ];
8231                                 }
8232
8233                                 val = prop[ name ];
8234
8235                                 // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
8236                                 if ( jQuery.isArray( val ) ) {
8237                                         opt.animatedProperties[ name ] = val[ 1 ];
8238                                         val = prop[ name ] = val[ 0 ];
8239                                 } else {
8240                                         opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
8241                                 }
8242
8243                                 if ( val === "hide" && hidden || val === "show" && !hidden ) {
8244                                         return opt.complete.call( this );
8245                                 }
8246
8247                                 if ( isElement && ( name === "height" || name === "width" ) ) {
8248                                         // Make sure that nothing sneaks out
8249                                         // Record all 3 overflow attributes because IE does not
8250                                         // change the overflow attribute when overflowX and
8251                                         // overflowY are set to the same value
8252                                         opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
8253
8254                                         // Set display property to inline-block for height/width
8255                                         // animations on inline elements that are having width/height
8256                                         // animated
8257                                         if ( jQuery.css( this, "display" ) === "inline" &&
8258                                                         jQuery.css( this, "float" ) === "none" ) {
8259                                                 if ( !jQuery.support.inlineBlockNeedsLayout ) {
8260                                                         this.style.display = "inline-block";
8261
8262                                                 } else {
8263                                                         display = defaultDisplay( this.nodeName );
8264
8265                                                         // inline-level elements accept inline-block;
8266                                                         // block-level elements need to be inline with layout
8267                                                         if ( display === "inline" ) {
8268                                                                 this.style.display = "inline-block";
8269
8270                                                         } else {
8271                                                                 this.style.display = "inline";
8272                                                                 this.style.zoom = 1;
8273                                                         }
8274                                                 }
8275                                         }
8276                                 }
8277                         }
8278
8279                         if ( opt.overflow != null ) {
8280                                 this.style.overflow = "hidden";
8281                         }
8282
8283                         for ( p in prop ) {
8284                                 e = new jQuery.fx( this, opt, p );
8285                                 val = prop[ p ];
8286
8287                                 if ( rfxtypes.test(val) ) {
8288                                         e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
8289
8290                                 } else {
8291                                         parts = rfxnum.exec( val );
8292                                         start = e.cur();
8293
8294                                         if ( parts ) {
8295                                                 end = parseFloat( parts[2] );
8296                                                 unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
8297
8298                                                 // We need to compute starting value
8299                                                 if ( unit !== "px" ) {
8300                                                         jQuery.style( this, p, (end || 1) + unit);
8301                                                         start = ((end || 1) / e.cur()) * start;
8302                                                         jQuery.style( this, p, start + unit);
8303                                                 }
8304
8305                                                 // If a +=/-= token was provided, we're doing a relative animation
8306                                                 if ( parts[1] ) {
8307                                                         end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
8308                                                 }
8309
8310                                                 e.custom( start, end, unit );
8311
8312                                         } else {
8313                                                 e.custom( start, val, "" );
8314                                         }
8315                                 }
8316                         }
8317
8318                         // For JS strict compliance
8319                         return true;
8320                 });
8321         },
8322
8323         stop: function( clearQueue, gotoEnd ) {
8324                 if ( clearQueue ) {
8325                         this.queue([]);
8326                 }
8327
8328                 this.each(function() {
8329                         var timers = jQuery.timers,
8330                                 i = timers.length;
8331                         // clear marker counters if we know they won't be
8332                         if ( !gotoEnd ) {
8333                                 jQuery._unmark( true, this );
8334                         }
8335                         while ( i-- ) {
8336                                 if ( timers[i].elem === this ) {
8337                                         if (gotoEnd) {
8338                                                 // force the next step to be the last
8339                                                 timers[i](true);
8340                                         }
8341
8342                                         timers.splice(i, 1);
8343                                 }
8344                         }
8345                 });
8346
8347                 // start the next in the queue if the last step wasn't forced
8348                 if ( !gotoEnd ) {
8349                         this.dequeue();
8350                 }
8351
8352                 return this;
8353         }
8354
8355 });
8356
8357 // Animations created synchronously will run synchronously
8358 function createFxNow() {
8359         setTimeout( clearFxNow, 0 );
8360         return ( fxNow = jQuery.now() );
8361 }
8362
8363 function clearFxNow() {
8364         fxNow = undefined;
8365 }
8366
8367 // Generate parameters to create a standard animation
8368 function genFx( type, num ) {
8369         var obj = {};
8370
8371         jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
8372                 obj[ this ] = type;
8373         });
8374
8375         return obj;
8376 }
8377
8378 // Generate shortcuts for custom animations
8379 jQuery.each({
8380         slideDown: genFx("show", 1),
8381         slideUp: genFx("hide", 1),
8382         slideToggle: genFx("toggle", 1),
8383         fadeIn: { opacity: "show" },
8384         fadeOut: { opacity: "hide" },
8385         fadeToggle: { opacity: "toggle" }
8386 }, function( name, props ) {
8387         jQuery.fn[ name ] = function( speed, easing, callback ) {
8388                 return this.animate( props, speed, easing, callback );
8389         };
8390 });
8391
8392 jQuery.extend({
8393         speed: function( speed, easing, fn ) {
8394                 var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
8395                         complete: fn || !fn && easing ||
8396                                 jQuery.isFunction( speed ) && speed,
8397                         duration: speed,
8398                         easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
8399                 };
8400
8401                 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8402                         opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
8403
8404                 // Queueing
8405                 opt.old = opt.complete;
8406                 opt.complete = function( noUnmark ) {
8407                         if ( jQuery.isFunction( opt.old ) ) {
8408                                 opt.old.call( this );
8409                         }
8410
8411                         if ( opt.queue !== false ) {
8412                                 jQuery.dequeue( this );
8413                         } else if ( noUnmark !== false ) {
8414                                 jQuery._unmark( this );
8415                         }
8416                 };
8417
8418                 return opt;
8419         },
8420
8421         easing: {
8422                 linear: function( p, n, firstNum, diff ) {
8423                         return firstNum + diff * p;
8424                 },
8425                 swing: function( p, n, firstNum, diff ) {
8426                         return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
8427                 }
8428         },
8429
8430         timers: [],
8431
8432         fx: function( elem, options, prop ) {
8433                 this.options = options;
8434                 this.elem = elem;
8435                 this.prop = prop;
8436
8437                 options.orig = options.orig || {};
8438         }
8439
8440 });
8441
8442 jQuery.fx.prototype = {
8443         // Simple function for setting a style value
8444         update: function() {
8445                 if ( this.options.step ) {
8446                         this.options.step.call( this.elem, this.now, this );
8447                 }
8448
8449                 (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
8450         },
8451
8452         // Get the current size
8453         cur: function() {
8454                 if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
8455                         return this.elem[ this.prop ];
8456                 }
8457
8458                 var parsed,
8459                         r = jQuery.css( this.elem, this.prop );
8460                 // Empty strings, null, undefined and "auto" are converted to 0,
8461                 // complex values such as "rotate(1rad)" are returned as is,
8462                 // simple values such as "10px" are parsed to Float.
8463                 return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
8464         },
8465
8466         // Start an animation from one number to another
8467         custom: function( from, to, unit ) {
8468                 var self = this,
8469                         fx = jQuery.fx;
8470
8471                 this.startTime = fxNow || createFxNow();
8472                 this.start = from;
8473                 this.end = to;
8474                 this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
8475                 this.now = this.start;
8476                 this.pos = this.state = 0;
8477
8478                 function t( gotoEnd ) {
8479                         return self.step(gotoEnd);
8480                 }
8481
8482                 t.elem = this.elem;
8483
8484                 if ( t() && jQuery.timers.push(t) && !timerId ) {
8485                         timerId = setInterval( fx.tick, fx.interval );
8486                 }
8487         },
8488
8489         // Simple 'show' function
8490         show: function() {
8491                 // Remember where we started, so that we can go back to it later
8492                 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8493                 this.options.show = true;
8494
8495                 // Begin the animation
8496                 // Make sure that we start at a small width/height to avoid any
8497                 // flash of content
8498                 this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
8499
8500                 // Start by showing the element
8501                 jQuery( this.elem ).show();
8502         },
8503
8504         // Simple 'hide' function
8505         hide: function() {
8506                 // Remember where we started, so that we can go back to it later
8507                 this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
8508                 this.options.hide = true;
8509
8510                 // Begin the animation
8511                 this.custom(this.cur(), 0);
8512         },
8513
8514         // Each step of an animation
8515         step: function( gotoEnd ) {
8516                 var t = fxNow || createFxNow(),
8517                         done = true,
8518                         elem = this.elem,
8519                         options = this.options,
8520                         i, n;
8521
8522                 if ( gotoEnd || t >= options.duration + this.startTime ) {
8523                         this.now = this.end;
8524                         this.pos = this.state = 1;
8525                         this.update();
8526
8527                         options.animatedProperties[ this.prop ] = true;
8528
8529                         for ( i in options.animatedProperties ) {
8530                                 if ( options.animatedProperties[i] !== true ) {
8531                                         done = false;
8532                                 }
8533                         }
8534
8535                         if ( done ) {
8536                                 // Reset the overflow
8537                                 if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
8538
8539                                         jQuery.each( [ "", "X", "Y" ], function (index, value) {
8540                                                 elem.style[ "overflow" + value ] = options.overflow[index];
8541                                         });
8542                                 }
8543
8544                                 // Hide the element if the "hide" operation was done
8545                                 if ( options.hide ) {
8546                                         jQuery(elem).hide();
8547                                 }
8548
8549                                 // Reset the properties, if the item has been hidden or shown
8550                                 if ( options.hide || options.show ) {
8551                                         for ( var p in options.animatedProperties ) {
8552                                                 jQuery.style( elem, p, options.orig[p] );
8553                                         }
8554                                 }
8555
8556                                 // Execute the complete function
8557                                 options.complete.call( elem );
8558                         }
8559
8560                         return false;
8561
8562                 } else {
8563                         // classical easing cannot be used with an Infinity duration
8564                         if ( options.duration == Infinity ) {
8565                                 this.now = t;
8566                         } else {
8567                                 n = t - this.startTime;
8568                                 this.state = n / options.duration;
8569
8570                                 // Perform the easing function, defaults to swing
8571                                 this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
8572                                 this.now = this.start + ((this.end - this.start) * this.pos);
8573                         }
8574                         // Perform the next step of the animation
8575                         this.update();
8576                 }
8577
8578                 return true;
8579         }
8580 };
8581
8582 jQuery.extend( jQuery.fx, {
8583         tick: function() {
8584                 for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
8585                         if ( !timers[i]() ) {
8586                                 timers.splice(i--, 1);
8587                         }
8588                 }
8589
8590                 if ( !timers.length ) {
8591                         jQuery.fx.stop();
8592                 }
8593         },
8594
8595         interval: 13,
8596
8597         stop: function() {
8598                 clearInterval( timerId );
8599                 timerId = null;
8600         },
8601
8602         speeds: {
8603                 slow: 600,
8604                 fast: 200,
8605                 // Default speed
8606                 _default: 400
8607         },
8608
8609         step: {
8610                 opacity: function( fx ) {
8611                         jQuery.style( fx.elem, "opacity", fx.now );
8612                 },
8613
8614                 _default: function( fx ) {
8615                         if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
8616                                 fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
8617                         } else {
8618                                 fx.elem[ fx.prop ] = fx.now;
8619                         }
8620                 }
8621         }
8622 });
8623
8624 if ( jQuery.expr && jQuery.expr.filters ) {
8625         jQuery.expr.filters.animated = function( elem ) {
8626                 return jQuery.grep(jQuery.timers, function( fn ) {
8627                         return elem === fn.elem;
8628                 }).length;
8629         };
8630 }
8631
8632 // Try to restore the default display value of an element
8633 function defaultDisplay( nodeName ) {
8634
8635         if ( !elemdisplay[ nodeName ] ) {
8636
8637                 var body = document.body,
8638                         elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
8639                         display = elem.css( "display" );
8640
8641                 elem.remove();
8642
8643                 // If the simple way fails,
8644                 // get element's real default display by attaching it to a temp iframe
8645                 if ( display === "none" || display === "" ) {
8646                         // No iframe to use yet, so create it
8647                         if ( !iframe ) {
8648                                 iframe = document.createElement( "iframe" );
8649                                 iframe.frameBorder = iframe.width = iframe.height = 0;
8650                         }
8651
8652                         body.appendChild( iframe );
8653
8654                         // Create a cacheable copy of the iframe document on first call.
8655                         // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
8656                         // document to it; WebKit & Firefox won't allow reusing the iframe document.
8657                         if ( !iframeDoc || !iframe.createElement ) {
8658                                 iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
8659                                 iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "<!doctype html>" : "" ) + "<html><body>" );
8660                                 iframeDoc.close();
8661                         }
8662
8663                         elem = iframeDoc.createElement( nodeName );
8664
8665                         iframeDoc.body.appendChild( elem );
8666
8667                         display = jQuery.css( elem, "display" );
8668
8669                         body.removeChild( iframe );
8670                 }
8671
8672                 // Store the correct default display
8673                 elemdisplay[ nodeName ] = display;
8674         }
8675
8676         return elemdisplay[ nodeName ];
8677 }
8678
8679
8680
8681
8682 var rtable = /^t(?:able|d|h)$/i,
8683         rroot = /^(?:body|html)$/i;
8684
8685 if ( "getBoundingClientRect" in document.documentElement ) {
8686         jQuery.fn.offset = function( options ) {
8687                 var elem = this[0], box;
8688
8689                 if ( options ) {
8690                         return this.each(function( i ) {
8691                                 jQuery.offset.setOffset( this, options, i );
8692                         });
8693                 }
8694
8695                 if ( !elem || !elem.ownerDocument ) {
8696                         return null;
8697                 }
8698
8699                 if ( elem === elem.ownerDocument.body ) {
8700                         return jQuery.offset.bodyOffset( elem );
8701                 }
8702
8703                 try {
8704                         box = elem.getBoundingClientRect();
8705                 } catch(e) {}
8706
8707                 var doc = elem.ownerDocument,
8708                         docElem = doc.documentElement;
8709
8710                 // Make sure we're not dealing with a disconnected DOM node
8711                 if ( !box || !jQuery.contains( docElem, elem ) ) {
8712                         return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
8713                 }
8714
8715                 var body = doc.body,
8716                         win = getWindow(doc),
8717                         clientTop  = docElem.clientTop  || body.clientTop  || 0,
8718                         clientLeft = docElem.clientLeft || body.clientLeft || 0,
8719                         scrollTop  = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop  || body.scrollTop,
8720                         scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
8721                         top  = box.top  + scrollTop  - clientTop,
8722                         left = box.left + scrollLeft - clientLeft;
8723
8724                 return { top: top, left: left };
8725         };
8726
8727 } else {
8728         jQuery.fn.offset = function( options ) {
8729                 var elem = this[0];
8730
8731                 if ( options ) {
8732                         return this.each(function( i ) {
8733                                 jQuery.offset.setOffset( this, options, i );
8734                         });
8735                 }
8736
8737                 if ( !elem || !elem.ownerDocument ) {
8738                         return null;
8739                 }
8740
8741                 if ( elem === elem.ownerDocument.body ) {
8742                         return jQuery.offset.bodyOffset( elem );
8743                 }
8744
8745                 jQuery.offset.initialize();
8746
8747                 var computedStyle,
8748                         offsetParent = elem.offsetParent,
8749                         prevOffsetParent = elem,
8750                         doc = elem.ownerDocument,
8751                         docElem = doc.documentElement,
8752                         body = doc.body,
8753                         defaultView = doc.defaultView,
8754                         prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
8755                         top = elem.offsetTop,
8756                         left = elem.offsetLeft;
8757
8758                 while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
8759                         if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8760                                 break;
8761                         }
8762
8763                         computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
8764                         top  -= elem.scrollTop;
8765                         left -= elem.scrollLeft;
8766
8767                         if ( elem === offsetParent ) {
8768                                 top  += elem.offsetTop;
8769                                 left += elem.offsetLeft;
8770
8771                                 if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
8772                                         top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
8773                                         left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8774                                 }
8775
8776                                 prevOffsetParent = offsetParent;
8777                                 offsetParent = elem.offsetParent;
8778                         }
8779
8780                         if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
8781                                 top  += parseFloat( computedStyle.borderTopWidth  ) || 0;
8782                                 left += parseFloat( computedStyle.borderLeftWidth ) || 0;
8783                         }
8784
8785                         prevComputedStyle = computedStyle;
8786                 }
8787
8788                 if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
8789                         top  += body.offsetTop;
8790                         left += body.offsetLeft;
8791                 }
8792
8793                 if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
8794                         top  += Math.max( docElem.scrollTop, body.scrollTop );
8795                         left += Math.max( docElem.scrollLeft, body.scrollLeft );
8796                 }
8797
8798                 return { top: top, left: left };
8799         };
8800 }
8801
8802 jQuery.offset = {
8803         initialize: function() {
8804                 var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
8805                         html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
8806
8807                 jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
8808
8809                 container.innerHTML = html;
8810                 body.insertBefore( container, body.firstChild );
8811                 innerDiv = container.firstChild;
8812                 checkDiv = innerDiv.firstChild;
8813                 td = innerDiv.nextSibling.firstChild.firstChild;
8814
8815                 this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
8816                 this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
8817
8818                 checkDiv.style.position = "fixed";
8819                 checkDiv.style.top = "20px";
8820
8821                 // safari subtracts parent border width here which is 5px
8822                 this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
8823                 checkDiv.style.position = checkDiv.style.top = "";
8824
8825                 innerDiv.style.overflow = "hidden";
8826                 innerDiv.style.position = "relative";
8827
8828                 this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
8829
8830                 this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
8831
8832                 body.removeChild( container );
8833                 jQuery.offset.initialize = jQuery.noop;
8834         },
8835
8836         bodyOffset: function( body ) {
8837                 var top = body.offsetTop,
8838                         left = body.offsetLeft;
8839
8840                 jQuery.offset.initialize();
8841
8842                 if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
8843                         top  += parseFloat( jQuery.css(body, "marginTop") ) || 0;
8844                         left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
8845                 }
8846
8847                 return { top: top, left: left };
8848         },
8849
8850         setOffset: function( elem, options, i ) {
8851                 var position = jQuery.css( elem, "position" );
8852
8853                 // set position first, in-case top/left are set even on static elem
8854                 if ( position === "static" ) {
8855                         elem.style.position = "relative";
8856                 }
8857
8858                 var curElem = jQuery( elem ),
8859                         curOffset = curElem.offset(),
8860                         curCSSTop = jQuery.css( elem, "top" ),
8861                         curCSSLeft = jQuery.css( elem, "left" ),
8862                         calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
8863                         props = {}, curPosition = {}, curTop, curLeft;
8864
8865                 // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
8866                 if ( calculatePosition ) {
8867                         curPosition = curElem.position();
8868                         curTop = curPosition.top;
8869                         curLeft = curPosition.left;
8870                 } else {
8871                         curTop = parseFloat( curCSSTop ) || 0;
8872                         curLeft = parseFloat( curCSSLeft ) || 0;
8873                 }
8874
8875                 if ( jQuery.isFunction( options ) ) {
8876                         options = options.call( elem, i, curOffset );
8877                 }
8878
8879                 if (options.top != null) {
8880                         props.top = (options.top - curOffset.top) + curTop;
8881                 }
8882                 if (options.left != null) {
8883                         props.left = (options.left - curOffset.left) + curLeft;
8884                 }
8885
8886                 if ( "using" in options ) {
8887                         options.using.call( elem, props );
8888                 } else {
8889                         curElem.css( props );
8890                 }
8891         }
8892 };
8893
8894
8895 jQuery.fn.extend({
8896         position: function() {
8897                 if ( !this[0] ) {
8898                         return null;
8899                 }
8900
8901                 var elem = this[0],
8902
8903                 // Get *real* offsetParent
8904                 offsetParent = this.offsetParent(),
8905
8906                 // Get correct offsets
8907                 offset       = this.offset(),
8908                 parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
8909
8910                 // Subtract element margins
8911                 // note: when an element has margin: auto the offsetLeft and marginLeft
8912                 // are the same in Safari causing offset.left to incorrectly be 0
8913                 offset.top  -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
8914                 offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
8915
8916                 // Add offsetParent borders
8917                 parentOffset.top  += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
8918                 parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
8919
8920                 // Subtract the two offsets
8921                 return {
8922                         top:  offset.top  - parentOffset.top,
8923                         left: offset.left - parentOffset.left
8924                 };
8925         },
8926
8927         offsetParent: function() {
8928                 return this.map(function() {
8929                         var offsetParent = this.offsetParent || document.body;
8930                         while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
8931                                 offsetParent = offsetParent.offsetParent;
8932                         }
8933                         return offsetParent;
8934                 });
8935         }
8936 });
8937
8938
8939 // Create scrollLeft and scrollTop methods
8940 jQuery.each( ["Left", "Top"], function( i, name ) {
8941         var method = "scroll" + name;
8942
8943         jQuery.fn[ method ] = function( val ) {
8944                 var elem, win;
8945
8946                 if ( val === undefined ) {
8947                         elem = this[ 0 ];
8948
8949                         if ( !elem ) {
8950                                 return null;
8951                         }
8952
8953                         win = getWindow( elem );
8954
8955                         // Return the scroll offset
8956                         return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
8957                                 jQuery.support.boxModel && win.document.documentElement[ method ] ||
8958                                         win.document.body[ method ] :
8959                                 elem[ method ];
8960                 }
8961
8962                 // Set the scroll offset
8963                 return this.each(function() {
8964                         win = getWindow( this );
8965
8966                         if ( win ) {
8967                                 win.scrollTo(
8968                                         !i ? val : jQuery( win ).scrollLeft(),
8969                                          i ? val : jQuery( win ).scrollTop()
8970                                 );
8971
8972                         } else {
8973                                 this[ method ] = val;
8974                         }
8975                 });
8976         };
8977 });
8978
8979 function getWindow( elem ) {
8980         return jQuery.isWindow( elem ) ?
8981                 elem :
8982                 elem.nodeType === 9 ?
8983                         elem.defaultView || elem.parentWindow :
8984                         false;
8985 }
8986
8987
8988
8989
8990 // Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
8991 jQuery.each([ "Height", "Width" ], function( i, name ) {
8992
8993         var type = name.toLowerCase();
8994
8995         // innerHeight and innerWidth
8996         jQuery.fn[ "inner" + name ] = function() {
8997                 var elem = this[0];
8998                 return elem && elem.style ?
8999                         parseFloat( jQuery.css( elem, type, "padding" ) ) :
9000                         null;
9001         };
9002
9003         // outerHeight and outerWidth
9004         jQuery.fn[ "outer" + name ] = function( margin ) {
9005                 var elem = this[0];
9006                 return elem && elem.style ?
9007                         parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
9008                         null;
9009         };
9010
9011         jQuery.fn[ type ] = function( size ) {
9012                 // Get window width or height
9013                 var elem = this[0];
9014                 if ( !elem ) {
9015                         return size == null ? null : this;
9016                 }
9017
9018                 if ( jQuery.isFunction( size ) ) {
9019                         return this.each(function( i ) {
9020                                 var self = jQuery( this );
9021                                 self[ type ]( size.call( this, i, self[ type ]() ) );
9022                         });
9023                 }
9024
9025                 if ( jQuery.isWindow( elem ) ) {
9026                         // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
9027                         // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
9028                         var docElemProp = elem.document.documentElement[ "client" + name ],
9029                                 body = elem.document.body;
9030                         return elem.document.compatMode === "CSS1Compat" && docElemProp ||
9031                                 body && body[ "client" + name ] || docElemProp;
9032
9033                 // Get document width or height
9034                 } else if ( elem.nodeType === 9 ) {
9035                         // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
9036                         return Math.max(
9037                                 elem.documentElement["client" + name],
9038                                 elem.body["scroll" + name], elem.documentElement["scroll" + name],
9039                                 elem.body["offset" + name], elem.documentElement["offset" + name]
9040                         );
9041
9042                 // Get or set width or height on the element
9043                 } else if ( size === undefined ) {
9044                         var orig = jQuery.css( elem, type ),
9045                                 ret = parseFloat( orig );
9046
9047                         return jQuery.isNaN( ret ) ? orig : ret;
9048
9049                 // Set the width or height on the element (default to pixels if value is unitless)
9050                 } else {
9051                         return this.css( type, typeof size === "string" ? size : size + "px" );
9052                 }
9053         };
9054
9055 });
9056
9057
9058 // Expose jQuery to the global object
9059 window.jQuery = window.$ = jQuery;
9060 })(window);
9061 //     Underscore.js 1.1.7
9062 //     (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
9063 //     Underscore is freely distributable under the MIT license.
9064 //     Portions of Underscore are inspired or borrowed from Prototype,
9065 //     Oliver Steele's Functional, and John Resig's Micro-Templating.
9066 //     For all details and documentation:
9067 //     http://documentcloud.github.com/underscore
9068
9069 (function() {
9070
9071   // Baseline setup
9072   // --------------
9073
9074   // Establish the root object, `window` in the browser, or `global` on the server.
9075   var root = this;
9076
9077   // Save the previous value of the `_` variable.
9078   var previousUnderscore = root._;
9079
9080   // Establish the object that gets returned to break out of a loop iteration.
9081   var breaker = {};
9082
9083   // Save bytes in the minified (but not gzipped) version:
9084   var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
9085
9086   // Create quick reference variables for speed access to core prototypes.
9087   var slice            = ArrayProto.slice,
9088       unshift          = ArrayProto.unshift,
9089       toString         = ObjProto.toString,
9090       hasOwnProperty   = ObjProto.hasOwnProperty;
9091
9092   // All **ECMAScript 5** native function implementations that we hope to use
9093   // are declared here.
9094   var
9095     nativeForEach      = ArrayProto.forEach,
9096     nativeMap          = ArrayProto.map,
9097     nativeReduce       = ArrayProto.reduce,
9098     nativeReduceRight  = ArrayProto.reduceRight,
9099     nativeFilter       = ArrayProto.filter,
9100     nativeEvery        = ArrayProto.every,
9101     nativeSome         = ArrayProto.some,
9102     nativeIndexOf      = ArrayProto.indexOf,
9103     nativeLastIndexOf  = ArrayProto.lastIndexOf,
9104     nativeIsArray      = Array.isArray,
9105     nativeKeys         = Object.keys,
9106     nativeBind         = FuncProto.bind;
9107
9108   // Create a safe reference to the Underscore object for use below.
9109   var _ = function(obj) { return new wrapper(obj); };
9110
9111   // Export the Underscore object for **CommonJS**, with backwards-compatibility
9112   // for the old `require()` API. If we're not in CommonJS, add `_` to the
9113   // global object.
9114   if (typeof module !== 'undefined' && module.exports) {
9115     module.exports = _;
9116     _._ = _;
9117   } else {
9118     // Exported as a string, for Closure Compiler "advanced" mode.
9119     root['_'] = _;
9120   }
9121
9122   // Current version.
9123   _.VERSION = '1.1.7';
9124
9125   // Collection Functions
9126   // --------------------
9127
9128   // The cornerstone, an `each` implementation, aka `forEach`.
9129   // Handles objects with the built-in `forEach`, arrays, and raw objects.
9130   // Delegates to **ECMAScript 5**'s native `forEach` if available.
9131   var each = _.each = _.forEach = function(obj, iterator, context) {
9132     if (obj == null) return;
9133     if (nativeForEach && obj.forEach === nativeForEach) {
9134       obj.forEach(iterator, context);
9135     } else if (obj.length === +obj.length) {
9136       for (var i = 0, l = obj.length; i < l; i++) {
9137         if (i in obj && iterator.call(context, obj[i], i, obj) === breaker) return;
9138       }
9139     } else {
9140       for (var key in obj) {
9141         if (hasOwnProperty.call(obj, key)) {
9142           if (iterator.call(context, obj[key], key, obj) === breaker) return;
9143         }
9144       }
9145     }
9146   };
9147
9148   // Return the results of applying the iterator to each element.
9149   // Delegates to **ECMAScript 5**'s native `map` if available.
9150   _.map = function(obj, iterator, context) {
9151     var results = [];
9152     if (obj == null) return results;
9153     if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
9154     each(obj, function(value, index, list) {
9155       results[results.length] = iterator.call(context, value, index, list);
9156     });
9157     return results;
9158   };
9159
9160   // **Reduce** builds up a single result from a list of values, aka `inject`,
9161   // or `foldl`. Delegates to **ECMAScript 5**'s native `reduce` if available.
9162   _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
9163     var initial = memo !== void 0;
9164     if (obj == null) obj = [];
9165     if (nativeReduce && obj.reduce === nativeReduce) {
9166       if (context) iterator = _.bind(iterator, context);
9167       return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
9168     }
9169     each(obj, function(value, index, list) {
9170       if (!initial) {
9171         memo = value;
9172         initial = true;
9173       } else {
9174         memo = iterator.call(context, memo, value, index, list);
9175       }
9176     });
9177     if (!initial) throw new TypeError("Reduce of empty array with no initial value");
9178     return memo;
9179   };
9180
9181   // The right-associative version of reduce, also known as `foldr`.
9182   // Delegates to **ECMAScript 5**'s native `reduceRight` if available.
9183   _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
9184     if (obj == null) obj = [];
9185     if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
9186       if (context) iterator = _.bind(iterator, context);
9187       return memo !== void 0 ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
9188     }
9189     var reversed = (_.isArray(obj) ? obj.slice() : _.toArray(obj)).reverse();
9190     return _.reduce(reversed, iterator, memo, context);
9191   };
9192
9193   // Return the first value which passes a truth test. Aliased as `detect`.
9194   _.find = _.detect = function(obj, iterator, context) {
9195     var result;
9196     any(obj, function(value, index, list) {
9197       if (iterator.call(context, value, index, list)) {
9198         result = value;
9199         return true;
9200       }
9201     });
9202     return result;
9203   };
9204
9205   // Return all the elements that pass a truth test.
9206   // Delegates to **ECMAScript 5**'s native `filter` if available.
9207   // Aliased as `select`.
9208   _.filter = _.select = function(obj, iterator, context) {
9209     var results = [];
9210     if (obj == null) return results;
9211     if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
9212     each(obj, function(value, index, list) {
9213       if (iterator.call(context, value, index, list)) results[results.length] = value;
9214     });
9215     return results;
9216   };
9217
9218   // Return all the elements for which a truth test fails.
9219   _.reject = function(obj, iterator, context) {
9220     var results = [];
9221     if (obj == null) return results;
9222     each(obj, function(value, index, list) {
9223       if (!iterator.call(context, value, index, list)) results[results.length] = value;
9224     });
9225     return results;
9226   };
9227
9228   // Determine whether all of the elements match a truth test.
9229   // Delegates to **ECMAScript 5**'s native `every` if available.
9230   // Aliased as `all`.
9231   _.every = _.all = function(obj, iterator, context) {
9232     var result = true;
9233     if (obj == null) return result;
9234     if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
9235     each(obj, function(value, index, list) {
9236       if (!(result = result && iterator.call(context, value, index, list))) return breaker;
9237     });
9238     return result;
9239   };
9240
9241   // Determine if at least one element in the object matches a truth test.
9242   // Delegates to **ECMAScript 5**'s native `some` if available.
9243   // Aliased as `any`.
9244   var any = _.some = _.any = function(obj, iterator, context) {
9245     iterator = iterator || _.identity;
9246     var result = false;
9247     if (obj == null) return result;
9248     if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
9249     each(obj, function(value, index, list) {
9250       if (result |= iterator.call(context, value, index, list)) return breaker;
9251     });
9252     return !!result;
9253   };
9254
9255   // Determine if a given value is included in the array or object using `===`.
9256   // Aliased as `contains`.
9257   _.include = _.contains = function(obj, target) {
9258     var found = false;
9259     if (obj == null) return found;
9260     if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
9261     any(obj, function(value) {
9262       if (found = value === target) return true;
9263     });
9264     return found;
9265   };
9266
9267   // Invoke a method (with arguments) on every item in a collection.
9268   _.invoke = function(obj, method) {
9269     var args = slice.call(arguments, 2);
9270     return _.map(obj, function(value) {
9271       return (method.call ? method || value : value[method]).apply(value, args);
9272     });
9273   };
9274
9275   // Convenience version of a common use case of `map`: fetching a property.
9276   _.pluck = function(obj, key) {
9277     return _.map(obj, function(value){ return value[key]; });
9278   };
9279
9280   // Return the maximum element or (element-based computation).
9281   _.max = function(obj, iterator, context) {
9282     if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj);
9283     var result = {computed : -Infinity};
9284     each(obj, function(value, index, list) {
9285       var computed = iterator ? iterator.call(context, value, index, list) : value;
9286       computed >= result.computed && (result = {value : value, computed : computed});
9287     });
9288     return result.value;
9289   };
9290
9291   // Return the minimum element (or element-based computation).
9292   _.min = function(obj, iterator, context) {
9293     if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj);
9294     var result = {computed : Infinity};
9295     each(obj, function(value, index, list) {
9296       var computed = iterator ? iterator.call(context, value, index, list) : value;
9297       computed < result.computed && (result = {value : value, computed : computed});
9298     });
9299     return result.value;
9300   };
9301
9302   // Sort the object's values by a criterion produced by an iterator.
9303   _.sortBy = function(obj, iterator, context) {
9304     return _.pluck(_.map(obj, function(value, index, list) {
9305       return {
9306         value : value,
9307         criteria : iterator.call(context, value, index, list)
9308       };
9309     }).sort(function(left, right) {
9310       var a = left.criteria, b = right.criteria;
9311       return a < b ? -1 : a > b ? 1 : 0;
9312     }), 'value');
9313   };
9314
9315   // Groups the object's values by a criterion produced by an iterator
9316   _.groupBy = function(obj, iterator) {
9317     var result = {};
9318     each(obj, function(value, index) {
9319       var key = iterator(value, index);
9320       (result[key] || (result[key] = [])).push(value);
9321     });
9322     return result;
9323   };
9324
9325   // Use a comparator function to figure out at what index an object should
9326   // be inserted so as to maintain order. Uses binary search.
9327   _.sortedIndex = function(array, obj, iterator) {
9328     iterator || (iterator = _.identity);
9329     var low = 0, high = array.length;
9330     while (low < high) {
9331       var mid = (low + high) >> 1;
9332       iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid;
9333     }
9334     return low;
9335   };
9336
9337   // Safely convert anything iterable into a real, live array.
9338   _.toArray = function(iterable) {
9339     if (!iterable)                return [];
9340     if (iterable.toArray)         return iterable.toArray();
9341     if (_.isArray(iterable))      return slice.call(iterable);
9342     if (_.isArguments(iterable))  return slice.call(iterable);
9343     return _.values(iterable);
9344   };
9345
9346   // Return the number of elements in an object.
9347   _.size = function(obj) {
9348     return _.toArray(obj).length;
9349   };
9350
9351   // Array Functions
9352   // ---------------
9353
9354   // Get the first element of an array. Passing **n** will return the first N
9355   // values in the array. Aliased as `head`. The **guard** check allows it to work
9356   // with `_.map`.
9357   _.first = _.head = function(array, n, guard) {
9358     return (n != null) && !guard ? slice.call(array, 0, n) : array[0];
9359   };
9360
9361   // Returns everything but the first entry of the array. Aliased as `tail`.
9362   // Especially useful on the arguments object. Passing an **index** will return
9363   // the rest of the values in the array from that index onward. The **guard**
9364   // check allows it to work with `_.map`.
9365   _.rest = _.tail = function(array, index, guard) {
9366     return slice.call(array, (index == null) || guard ? 1 : index);
9367   };
9368
9369   // Get the last element of an array.
9370   _.last = function(array) {
9371     return array[array.length - 1];
9372   };
9373
9374   // Trim out all falsy values from an array.
9375   _.compact = function(array) {
9376     return _.filter(array, function(value){ return !!value; });
9377   };
9378
9379   // Return a completely flattened version of an array.
9380   _.flatten = function(array) {
9381     return _.reduce(array, function(memo, value) {
9382       if (_.isArray(value)) return memo.concat(_.flatten(value));
9383       memo[memo.length] = value;
9384       return memo;
9385     }, []);
9386   };
9387
9388   // Return a version of the array that does not contain the specified value(s).
9389   _.without = function(array) {
9390     return _.difference(array, slice.call(arguments, 1));
9391   };
9392
9393   // Produce a duplicate-free version of the array. If the array has already
9394   // been sorted, you have the option of using a faster algorithm.
9395   // Aliased as `unique`.
9396   _.uniq = _.unique = function(array, isSorted) {
9397     return _.reduce(array, function(memo, el, i) {
9398       if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) memo[memo.length] = el;
9399       return memo;
9400     }, []);
9401   };
9402
9403   // Produce an array that contains the union: each distinct element from all of
9404   // the passed-in arrays.
9405   _.union = function() {
9406     return _.uniq(_.flatten(arguments));
9407   };
9408
9409   // Produce an array that contains every item shared between all the
9410   // passed-in arrays. (Aliased as "intersect" for back-compat.)
9411   _.intersection = _.intersect = function(array) {
9412     var rest = slice.call(arguments, 1);
9413     return _.filter(_.uniq(array), function(item) {
9414       return _.every(rest, function(other) {
9415         return _.indexOf(other, item) >= 0;
9416       });
9417     });
9418   };
9419
9420   // Take the difference between one array and another.
9421   // Only the elements present in just the first array will remain.
9422   _.difference = function(array, other) {
9423     return _.filter(array, function(value){ return !_.include(other, value); });
9424   };
9425
9426   // Zip together multiple lists into a single array -- elements that share
9427   // an index go together.
9428   _.zip = function() {
9429     var args = slice.call(arguments);
9430     var length = _.max(_.pluck(args, 'length'));
9431     var results = new Array(length);
9432     for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i);
9433     return results;
9434   };
9435
9436   // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**),
9437   // we need this function. Return the position of the first occurrence of an
9438   // item in an array, or -1 if the item is not included in the array.
9439   // Delegates to **ECMAScript 5**'s native `indexOf` if available.
9440   // If the array is large and already in sort order, pass `true`
9441   // for **isSorted** to use binary search.
9442   _.indexOf = function(array, item, isSorted) {
9443     if (array == null) return -1;
9444     var i, l;
9445     if (isSorted) {
9446       i = _.sortedIndex(array, item);
9447       return array[i] === item ? i : -1;
9448     }
9449     if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item);
9450     for (i = 0, l = array.length; i < l; i++) if (array[i] === item) return i;
9451     return -1;
9452   };
9453
9454
9455   // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available.
9456   _.lastIndexOf = function(array, item) {
9457     if (array == null) return -1;
9458     if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item);
9459     var i = array.length;
9460     while (i--) if (array[i] === item) return i;
9461     return -1;
9462   };
9463
9464   // Generate an integer Array containing an arithmetic progression. A port of
9465   // the native Python `range()` function. See
9466   // [the Python documentation](http://docs.python.org/library/functions.html#range).
9467   _.range = function(start, stop, step) {
9468     if (arguments.length <= 1) {
9469       stop = start || 0;
9470       start = 0;
9471     }
9472     step = arguments[2] || 1;
9473
9474     var len = Math.max(Math.ceil((stop - start) / step), 0);
9475     var idx = 0;
9476     var range = new Array(len);
9477
9478     while(idx < len) {
9479       range[idx++] = start;
9480       start += step;
9481     }
9482
9483     return range;
9484   };
9485
9486   // Function (ahem) Functions
9487   // ------------------
9488
9489   // Create a function bound to a given object (assigning `this`, and arguments,
9490   // optionally). Binding with arguments is also known as `curry`.
9491   // Delegates to **ECMAScript 5**'s native `Function.bind` if available.
9492   // We check for `func.bind` first, to fail fast when `func` is undefined.
9493   _.bind = function(func, obj) {
9494     if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
9495     var args = slice.call(arguments, 2);
9496     return function() {
9497       return func.apply(obj, args.concat(slice.call(arguments)));
9498     };
9499   };
9500
9501   // Bind all of an object's methods to that object. Useful for ensuring that
9502   // all callbacks defined on an object belong to it.
9503   _.bindAll = function(obj) {
9504     var funcs = slice.call(arguments, 1);
9505     if (funcs.length == 0) funcs = _.functions(obj);
9506     each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
9507     return obj;
9508   };
9509
9510   // Memoize an expensive function by storing its results.
9511   _.memoize = function(func, hasher) {
9512     var memo = {};
9513     hasher || (hasher = _.identity);
9514     return function() {
9515       var key = hasher.apply(this, arguments);
9516       return hasOwnProperty.call(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
9517     };
9518   };
9519
9520   // Delays a function for the given number of milliseconds, and then calls
9521   // it with the arguments supplied.
9522   _.delay = function(func, wait) {
9523     var args = slice.call(arguments, 2);
9524     return setTimeout(function(){ return func.apply(func, args); }, wait);
9525   };
9526
9527   // Defers a function, scheduling it to run after the current call stack has
9528   // cleared.
9529   _.defer = function(func) {
9530     return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
9531   };
9532
9533   // Internal function used to implement `_.throttle` and `_.debounce`.
9534   var limit = function(func, wait, debounce) {
9535     var timeout;
9536     return function() {
9537       var context = this, args = arguments;
9538       var throttler = function() {
9539         timeout = null;
9540         func.apply(context, args);
9541       };
9542       if (debounce) clearTimeout(timeout);
9543       if (debounce || !timeout) timeout = setTimeout(throttler, wait);
9544     };
9545   };
9546
9547   // Returns a function, that, when invoked, will only be triggered at most once
9548   // during a given window of time.
9549   _.throttle = function(func, wait) {
9550     return limit(func, wait, false);
9551   };
9552
9553   // Returns a function, that, as long as it continues to be invoked, will not
9554   // be triggered. The function will be called after it stops being called for
9555   // N milliseconds.
9556   _.debounce = function(func, wait) {
9557     return limit(func, wait, true);
9558   };
9559
9560   // Returns a function that will be executed at most one time, no matter how
9561   // often you call it. Useful for lazy initialization.
9562   _.once = function(func) {
9563     var ran = false, memo;
9564     return function() {
9565       if (ran) return memo;
9566       ran = true;
9567       return memo = func.apply(this, arguments);
9568     };
9569   };
9570
9571   // Returns the first function passed as an argument to the second,
9572   // allowing you to adjust arguments, run code before and after, and
9573   // conditionally execute the original function.
9574   _.wrap = function(func, wrapper) {
9575     return function() {
9576       var args = [func].concat(slice.call(arguments));
9577       return wrapper.apply(this, args);
9578     };
9579   };
9580
9581   // Returns a function that is the composition of a list of functions, each
9582   // consuming the return value of the function that follows.
9583   _.compose = function() {
9584     var funcs = slice.call(arguments);
9585     return function() {
9586       var args = slice.call(arguments);
9587       for (var i = funcs.length - 1; i >= 0; i--) {
9588         args = [funcs[i].apply(this, args)];
9589       }
9590       return args[0];
9591     };
9592   };
9593
9594   // Returns a function that will only be executed after being called N times.
9595   _.after = function(times, func) {
9596     return function() {
9597       if (--times < 1) { return func.apply(this, arguments); }
9598     };
9599   };
9600
9601
9602   // Object Functions
9603   // ----------------
9604
9605   // Retrieve the names of an object's properties.
9606   // Delegates to **ECMAScript 5**'s native `Object.keys`
9607   _.keys = nativeKeys || function(obj) {
9608     if (obj !== Object(obj)) throw new TypeError('Invalid object');
9609     var keys = [];
9610     for (var key in obj) if (hasOwnProperty.call(obj, key)) keys[keys.length] = key;
9611     return keys;
9612   };
9613
9614   // Retrieve the values of an object's properties.
9615   _.values = function(obj) {
9616     return _.map(obj, _.identity);
9617   };
9618
9619   // Return a sorted list of the function names available on the object.
9620   // Aliased as `methods`
9621   _.functions = _.methods = function(obj) {
9622     var names = [];
9623     for (var key in obj) {
9624       if (_.isFunction(obj[key])) names.push(key);
9625     }
9626     return names.sort();
9627   };
9628
9629   // Extend a given object with all the properties in passed-in object(s).
9630   _.extend = function(obj) {
9631     each(slice.call(arguments, 1), function(source) {
9632       for (var prop in source) {
9633         if (source[prop] !== void 0) obj[prop] = source[prop];
9634       }
9635     });
9636     return obj;
9637   };
9638
9639   // Fill in a given object with default properties.
9640   _.defaults = function(obj) {
9641     each(slice.call(arguments, 1), function(source) {
9642       for (var prop in source) {
9643         if (obj[prop] == null) obj[prop] = source[prop];
9644       }
9645     });
9646     return obj;
9647   };
9648
9649   // Create a (shallow-cloned) duplicate of an object.
9650   _.clone = function(obj) {
9651     return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
9652   };
9653
9654   // Invokes interceptor with the obj, and then returns obj.
9655   // The primary purpose of this method is to "tap into" a method chain, in
9656   // order to perform operations on intermediate results within the chain.
9657   _.tap = function(obj, interceptor) {
9658     interceptor(obj);
9659     return obj;
9660   };
9661
9662   // Perform a deep comparison to check if two objects are equal.
9663   _.isEqual = function(a, b) {
9664     // Check object identity.
9665     if (a === b) return true;
9666     // Different types?
9667     var atype = typeof(a), btype = typeof(b);
9668     if (atype != btype) return false;
9669     // Basic equality test (watch out for coercions).
9670     if (a == b) return true;
9671     // One is falsy and the other truthy.
9672     if ((!a && b) || (a && !b)) return false;
9673     // Unwrap any wrapped objects.
9674     if (a._chain) a = a._wrapped;
9675     if (b._chain) b = b._wrapped;
9676     // One of them implements an isEqual()?
9677     if (a.isEqual) return a.isEqual(b);
9678     if (b.isEqual) return b.isEqual(a);
9679     // Check dates' integer values.
9680     if (_.isDate(a) && _.isDate(b)) return a.getTime() === b.getTime();
9681     // Both are NaN?
9682     if (_.isNaN(a) && _.isNaN(b)) return false;
9683     // Compare regular expressions.
9684     if (_.isRegExp(a) && _.isRegExp(b))
9685       return a.source     === b.source &&
9686              a.global     === b.global &&
9687              a.ignoreCase === b.ignoreCase &&
9688              a.multiline  === b.multiline;
9689     // If a is not an object by this point, we can't handle it.
9690     if (atype !== 'object') return false;
9691     // Check for different array lengths before comparing contents.
9692     if (a.length && (a.length !== b.length)) return false;
9693     // Nothing else worked, deep compare the contents.
9694     var aKeys = _.keys(a), bKeys = _.keys(b);
9695     // Different object sizes?
9696     if (aKeys.length != bKeys.length) return false;
9697     // Recursive comparison of contents.
9698     for (var key in a) if (!(key in b) || !_.isEqual(a[key], b[key])) return false;
9699     return true;
9700   };
9701
9702   // Is a given array or object empty?
9703   _.isEmpty = function(obj) {
9704     if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
9705     for (var key in obj) if (hasOwnProperty.call(obj, key)) return false;
9706     return true;
9707   };
9708
9709   // Is a given value a DOM element?
9710   _.isElement = function(obj) {
9711     return !!(obj && obj.nodeType == 1);
9712   };
9713
9714   // Is a given value an array?
9715   // Delegates to ECMA5's native Array.isArray
9716   _.isArray = nativeIsArray || function(obj) {
9717     return toString.call(obj) === '[object Array]';
9718   };
9719
9720   // Is a given variable an object?
9721   _.isObject = function(obj) {
9722     return obj === Object(obj);
9723   };
9724
9725   // Is a given variable an arguments object?
9726   _.isArguments = function(obj) {
9727     return !!(obj && hasOwnProperty.call(obj, 'callee'));
9728   };
9729
9730   // Is a given value a function?
9731   _.isFunction = function(obj) {
9732     return !!(obj && obj.constructor && obj.call && obj.apply);
9733   };
9734
9735   // Is a given value a string?
9736   _.isString = function(obj) {
9737     return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
9738   };
9739
9740   // Is a given value a number?
9741   _.isNumber = function(obj) {
9742     return !!(obj === 0 || (obj && obj.toExponential && obj.toFixed));
9743   };
9744
9745   // Is the given value `NaN`? `NaN` happens to be the only value in JavaScript
9746   // that does not equal itself.
9747   _.isNaN = function(obj) {
9748     return obj !== obj;
9749   };
9750
9751   // Is a given value a boolean?
9752   _.isBoolean = function(obj) {
9753     return obj === true || obj === false;
9754   };
9755
9756   // Is a given value a date?
9757   _.isDate = function(obj) {
9758     return !!(obj && obj.getTimezoneOffset && obj.setUTCFullYear);
9759   };
9760
9761   // Is the given value a regular expression?
9762   _.isRegExp = function(obj) {
9763     return !!(obj && obj.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));
9764   };
9765
9766   // Is a given value equal to null?
9767   _.isNull = function(obj) {
9768     return obj === null;
9769   };
9770
9771   // Is a given variable undefined?
9772   _.isUndefined = function(obj) {
9773     return obj === void 0;
9774   };
9775
9776   // Utility Functions
9777   // -----------------
9778
9779   // Run Underscore.js in *noConflict* mode, returning the `_` variable to its
9780   // previous owner. Returns a reference to the Underscore object.
9781   _.noConflict = function() {
9782     root._ = previousUnderscore;
9783     return this;
9784   };
9785
9786   // Keep the identity function around for default iterators.
9787   _.identity = function(value) {
9788     return value;
9789   };
9790
9791   // Run a function **n** times.
9792   _.times = function (n, iterator, context) {
9793     for (var i = 0; i < n; i++) iterator.call(context, i);
9794   };
9795
9796   // Add your own custom functions to the Underscore object, ensuring that
9797   // they're correctly added to the OOP wrapper as well.
9798   _.mixin = function(obj) {
9799     each(_.functions(obj), function(name){
9800       addToWrapper(name, _[name] = obj[name]);
9801     });
9802   };
9803
9804   // Generate a unique integer id (unique within the entire client session).
9805   // Useful for temporary DOM ids.
9806   var idCounter = 0;
9807   _.uniqueId = function(prefix) {
9808     var id = idCounter++;
9809     return prefix ? prefix + id : id;
9810   };
9811
9812   // By default, Underscore uses ERB-style template delimiters, change the
9813   // following template settings to use alternative delimiters.
9814   _.templateSettings = {
9815     evaluate    : /<%([\s\S]+?)%>/g,
9816     interpolate : /<%=([\s\S]+?)%>/g
9817   };
9818
9819   // JavaScript micro-templating, similar to John Resig's implementation.
9820   // Underscore templating handles arbitrary delimiters, preserves whitespace,
9821   // and correctly escapes quotes within interpolated code.
9822   _.template = function(str, data) {
9823     var c  = _.templateSettings;
9824     var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' +
9825       'with(obj||{}){__p.push(\'' +
9826       str.replace(/\\/g, '\\\\')
9827          .replace(/'/g, "\\'")
9828          .replace(c.interpolate, function(match, code) {
9829            return "'," + code.replace(/\\'/g, "'") + ",'";
9830          })
9831          .replace(c.evaluate || null, function(match, code) {
9832            return "');" + code.replace(/\\'/g, "'")
9833                               .replace(/[\r\n\t]/g, ' ') + "__p.push('";
9834          })
9835          .replace(/\r/g, '\\r')
9836          .replace(/\n/g, '\\n')
9837          .replace(/\t/g, '\\t')
9838          + "');}return __p.join('');";
9839     var func = new Function('obj', tmpl);
9840     return data ? func(data) : func;
9841   };
9842
9843   // The OOP Wrapper
9844   // ---------------
9845
9846   // If Underscore is called as a function, it returns a wrapped object that
9847   // can be used OO-style. This wrapper holds altered versions of all the
9848   // underscore functions. Wrapped objects may be chained.
9849   var wrapper = function(obj) { this._wrapped = obj; };
9850
9851   // Expose `wrapper.prototype` as `_.prototype`
9852   _.prototype = wrapper.prototype;
9853
9854   // Helper function to continue chaining intermediate results.
9855   var result = function(obj, chain) {
9856     return chain ? _(obj).chain() : obj;
9857   };
9858
9859   // A method to easily add functions to the OOP wrapper.
9860   var addToWrapper = function(name, func) {
9861     wrapper.prototype[name] = function() {
9862       var args = slice.call(arguments);
9863       unshift.call(args, this._wrapped);
9864       return result(func.apply(_, args), this._chain);
9865     };
9866   };
9867
9868   // Add all of the Underscore functions to the wrapper object.
9869   _.mixin(_);
9870
9871   // Add all mutator Array functions to the wrapper.
9872   each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
9873     var method = ArrayProto[name];
9874     wrapper.prototype[name] = function() {
9875       method.apply(this._wrapped, arguments);
9876       return result(this._wrapped, this._chain);
9877     };
9878   });
9879
9880   // Add all accessor Array functions to the wrapper.
9881   each(['concat', 'join', 'slice'], function(name) {
9882     var method = ArrayProto[name];
9883     wrapper.prototype[name] = function() {
9884       return result(method.apply(this._wrapped, arguments), this._chain);
9885     };
9886   });
9887
9888   // Start chaining a wrapped Underscore object.
9889   wrapper.prototype.chain = function() {
9890     this._chain = true;
9891     return this;
9892   };
9893
9894   // Extracts the result from a wrapped and chained object.
9895   wrapper.prototype.value = function() {
9896     return this._wrapped;
9897   };
9898
9899 })();
9900 //     Backbone.js 0.5.3
9901 //     (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
9902 //     Backbone may be freely distributed under the MIT license.
9903 //     For all details and documentation:
9904 //     http://documentcloud.github.com/backbone
9905
9906 (function(){
9907
9908   // Initial Setup
9909   // -------------
9910
9911   // Save a reference to the global object.
9912   var root = this;
9913
9914   // Save the previous value of the `Backbone` variable.
9915   var previousBackbone = root.Backbone;
9916
9917   // The top-level namespace. All public Backbone classes and modules will
9918   // be attached to this. Exported for both CommonJS and the browser.
9919   var Backbone;
9920   if (typeof exports !== 'undefined') {
9921     Backbone = exports;
9922   } else {
9923     Backbone = root.Backbone = {};
9924   }
9925
9926   // Current version of the library. Keep in sync with `package.json`.
9927   Backbone.VERSION = '0.5.3';
9928
9929   // Require Underscore, if we're on the server, and it's not already present.
9930   var _ = root._;
9931   if (!_ && (typeof require !== 'undefined')) _ = require('underscore')._;
9932
9933   // For Backbone's purposes, jQuery or Zepto owns the `$` variable.
9934   var $ = root.jQuery || root.Zepto;
9935
9936   // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
9937   // to its previous owner. Returns a reference to this Backbone object.
9938   Backbone.noConflict = function() {
9939     root.Backbone = previousBackbone;
9940     return this;
9941   };
9942
9943   // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option will
9944   // fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and set a
9945   // `X-Http-Method-Override` header.
9946   Backbone.emulateHTTP = false;
9947
9948   // Turn on `emulateJSON` to support legacy servers that can't deal with direct
9949   // `application/json` requests ... will encode the body as
9950   // `application/x-www-form-urlencoded` instead and will send the model in a
9951   // form param named `model`.
9952   Backbone.emulateJSON = false;
9953
9954   // Backbone.Events
9955   // -----------------
9956
9957   // A module that can be mixed in to *any object* in order to provide it with
9958   // custom events. You may `bind` or `unbind` a callback function to an event;
9959   // `trigger`-ing an event fires all callbacks in succession.
9960   //
9961   //     var object = {};
9962   //     _.extend(object, Backbone.Events);
9963   //     object.bind('expand', function(){ alert('expanded'); });
9964   //     object.trigger('expand');
9965   //
9966   Backbone.Events = {
9967
9968     // Bind an event, specified by a string name, `ev`, to a `callback` function.
9969     // Passing `"all"` will bind the callback to all events fired.
9970     bind : function(ev, callback, context) {
9971       var calls = this._callbacks || (this._callbacks = {});
9972       var list  = calls[ev] || (calls[ev] = []);
9973       list.push([callback, context]);
9974       return this;
9975     },
9976
9977     // Remove one or many callbacks. If `callback` is null, removes all
9978     // callbacks for the event. If `ev` is null, removes all bound callbacks
9979     // for all events.
9980     unbind : function(ev, callback) {
9981       var calls;
9982       if (!ev) {
9983         this._callbacks = {};
9984       } else if (calls = this._callbacks) {
9985         if (!callback) {
9986           calls[ev] = [];
9987         } else {
9988           var list = calls[ev];
9989           if (!list) return this;
9990           for (var i = 0, l = list.length; i < l; i++) {
9991             if (list[i] && callback === list[i][0]) {
9992               list[i] = null;
9993               break;
9994             }
9995           }
9996         }
9997       }
9998       return this;
9999     },
10000
10001     // Trigger an event, firing all bound callbacks. Callbacks are passed the
10002     // same arguments as `trigger` is, apart from the event name.
10003     // Listening for `"all"` passes the true event name as the first argument.
10004     trigger : function(eventName) {
10005       var list, calls, ev, callback, args;
10006       var both = 2;
10007       if (!(calls = this._callbacks)) return this;
10008       while (both--) {
10009         ev = both ? eventName : 'all';
10010         if (list = calls[ev]) {
10011           for (var i = 0, l = list.length; i < l; i++) {
10012             if (!(callback = list[i])) {
10013               list.splice(i, 1); i--; l--;
10014             } else {
10015               args = both ? Array.prototype.slice.call(arguments, 1) : arguments;
10016               callback[0].apply(callback[1] || this, args);
10017             }
10018           }
10019         }
10020       }
10021       return this;
10022     }
10023
10024   };
10025
10026   // Backbone.Model
10027   // --------------
10028
10029   // Create a new model, with defined attributes. A client id (`cid`)
10030   // is automatically generated and assigned for you.
10031   Backbone.Model = function(attributes, options) {
10032     var defaults;
10033     attributes || (attributes = {});
10034     if (defaults = this.defaults) {
10035       if (_.isFunction(defaults)) defaults = defaults.call(this);
10036       attributes = _.extend({}, defaults, attributes);
10037     }
10038     this.attributes = {};
10039     this._escapedAttributes = {};
10040     this.cid = _.uniqueId('c');
10041     this.set(attributes, {silent : true});
10042     this._changed = false;
10043     this._previousAttributes = _.clone(this.attributes);
10044     if (options && options.collection) this.collection = options.collection;
10045     this.initialize(attributes, options);
10046   };
10047
10048   // Attach all inheritable methods to the Model prototype.
10049   _.extend(Backbone.Model.prototype, Backbone.Events, {
10050
10051     // A snapshot of the model's previous attributes, taken immediately
10052     // after the last `"change"` event was fired.
10053     _previousAttributes : null,
10054
10055     // Has the item been changed since the last `"change"` event?
10056     _changed : false,
10057
10058     // The default name for the JSON `id` attribute is `"id"`. MongoDB and
10059     // CouchDB users may want to set this to `"_id"`.
10060     idAttribute : 'id',
10061
10062     // Initialize is an empty function by default. Override it with your own
10063     // initialization logic.
10064     initialize : function(){},
10065
10066     // Return a copy of the model's `attributes` object.
10067     toJSON : function() {
10068       return _.clone(this.attributes);
10069     },
10070
10071     // Get the value of an attribute.
10072     get : function(attr) {
10073       return this.attributes[attr];
10074     },
10075
10076     // Get the HTML-escaped value of an attribute.
10077     escape : function(attr) {
10078       var html;
10079       if (html = this._escapedAttributes[attr]) return html;
10080       var val = this.attributes[attr];
10081       return this._escapedAttributes[attr] = escapeHTML(val == null ? '' : '' + val);
10082     },
10083
10084     // Returns `true` if the attribute contains a value that is not null
10085     // or undefined.
10086     has : function(attr) {
10087       return this.attributes[attr] != null;
10088     },
10089
10090     // Set a hash of model attributes on the object, firing `"change"` unless you
10091     // choose to silence it.
10092     set : function(attrs, options) {
10093
10094       // Extract attributes and options.
10095       options || (options = {});
10096       if (!attrs) return this;
10097       if (attrs.attributes) attrs = attrs.attributes;
10098       var now = this.attributes, escaped = this._escapedAttributes;
10099
10100       // Run validation.
10101       if (!options.silent && this.validate && !this._performValidation(attrs, options)) return false;
10102
10103       // Check for changes of `id`.
10104       if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
10105
10106       // We're about to start triggering change events.
10107       var alreadyChanging = this._changing;
10108       this._changing = true;
10109
10110       // Update attributes.
10111       for (var attr in attrs) {
10112         var val = attrs[attr];
10113         if (!_.isEqual(now[attr], val)) {
10114           now[attr] = val;
10115           delete escaped[attr];
10116           this._changed = true;
10117           if (!options.silent) this.trigger('change:' + attr, this, val, options);
10118         }
10119       }
10120
10121       // Fire the `"change"` event, if the model has been changed.
10122       if (!alreadyChanging && !options.silent && this._changed) this.change(options);
10123       this._changing = false;
10124       return this;
10125     },
10126
10127     // Remove an attribute from the model, firing `"change"` unless you choose
10128     // to silence it. `unset` is a noop if the attribute doesn't exist.
10129     unset : function(attr, options) {
10130       if (!(attr in this.attributes)) return this;
10131       options || (options = {});
10132       var value = this.attributes[attr];
10133
10134       // Run validation.
10135       var validObj = {};
10136       validObj[attr] = void 0;
10137       if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;
10138
10139       // Remove the attribute.
10140       delete this.attributes[attr];
10141       delete this._escapedAttributes[attr];
10142       if (attr == this.idAttribute) delete this.id;
10143       this._changed = true;
10144       if (!options.silent) {
10145         this.trigger('change:' + attr, this, void 0, options);
10146         this.change(options);
10147       }
10148       return this;
10149     },
10150
10151     // Clear all attributes on the model, firing `"change"` unless you choose
10152     // to silence it.
10153     clear : function(options) {
10154       options || (options = {});
10155       var attr;
10156       var old = this.attributes;
10157
10158       // Run validation.
10159       var validObj = {};
10160       for (attr in old) validObj[attr] = void 0;
10161       if (!options.silent && this.validate && !this._performValidation(validObj, options)) return false;
10162
10163       this.attributes = {};
10164       this._escapedAttributes = {};
10165       this._changed = true;
10166       if (!options.silent) {
10167         for (attr in old) {
10168           this.trigger('change:' + attr, this, void 0, options);
10169         }
10170         this.change(options);
10171       }
10172       return this;
10173     },
10174
10175     // Fetch the model from the server. If the server's representation of the
10176     // model differs from its current attributes, they will be overriden,
10177     // triggering a `"change"` event.
10178     fetch : function(options) {
10179       options || (options = {});
10180       var model = this;
10181       var success = options.success;
10182       options.success = function(resp, status, xhr) {
10183         if (!model.set(model.parse(resp, xhr), options)) return false;
10184         if (success) success(model, resp);
10185       };
10186       options.error = wrapError(options.error, model, options);
10187       return (this.sync || Backbone.sync).call(this, 'read', this, options);
10188     },
10189
10190     // Set a hash of model attributes, and sync the model to the server.
10191     // If the server returns an attributes hash that differs, the model's
10192     // state will be `set` again.
10193     save : function(attrs, options) {
10194       options || (options = {});
10195       if (attrs && !this.set(attrs, options)) return false;
10196       var model = this;
10197       var success = options.success;
10198       options.success = function(resp, status, xhr) {
10199         if (!model.set(model.parse(resp, xhr), options)) return false;
10200         if (success) success(model, resp, xhr);
10201       };
10202       options.error = wrapError(options.error, model, options);
10203       var method = this.isNew() ? 'create' : 'update';
10204       return (this.sync || Backbone.sync).call(this, method, this, options);
10205     },
10206
10207     // Destroy this model on the server if it was already persisted. Upon success, the model is removed
10208     // from its collection, if it has one.
10209     destroy : function(options) {
10210       options || (options = {});
10211       if (this.isNew()) return this.trigger('destroy', this, this.collection, options);
10212       var model = this;
10213       var success = options.success;
10214       options.success = function(resp) {
10215         model.trigger('destroy', model, model.collection, options);
10216         if (success) success(model, resp);
10217       };
10218       options.error = wrapError(options.error, model, options);
10219       return (this.sync || Backbone.sync).call(this, 'delete', this, options);
10220     },
10221
10222     // Default URL for the model's representation on the server -- if you're
10223     // using Backbone's restful methods, override this to change the endpoint
10224     // that will be called.
10225     url : function() {
10226       var base = getUrl(this.collection) || this.urlRoot || urlError();
10227       if (this.isNew()) return base;
10228       return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
10229     },
10230
10231     // **parse** converts a response into the hash of attributes to be `set` on
10232     // the model. The default implementation is just to pass the response along.
10233     parse : function(resp, xhr) {
10234       return resp;
10235     },
10236
10237     // Create a new model with identical attributes to this one.
10238     clone : function() {
10239       return new this.constructor(this);
10240     },
10241
10242     // A model is new if it has never been saved to the server, and lacks an id.
10243     isNew : function() {
10244       return this.id == null;
10245     },
10246
10247     // Call this method to manually fire a `change` event for this model.
10248     // Calling this will cause all objects observing the model to update.
10249     change : function(options) {
10250       this.trigger('change', this, options);
10251       this._previousAttributes = _.clone(this.attributes);
10252       this._changed = false;
10253     },
10254
10255     // Determine if the model has changed since the last `"change"` event.
10256     // If you specify an attribute name, determine if that attribute has changed.
10257     hasChanged : function(attr) {
10258       if (attr) return this._previousAttributes[attr] != this.attributes[attr];
10259       return this._changed;
10260     },
10261
10262     // Return an object containing all the attributes that have changed, or false
10263     // if there are no changed attributes. Useful for determining what parts of a
10264     // view need to be updated and/or what attributes need to be persisted to
10265     // the server.
10266     changedAttributes : function(now) {
10267       now || (now = this.attributes);
10268       var old = this._previousAttributes;
10269       var changed = false;
10270       for (var attr in now) {
10271         if (!_.isEqual(old[attr], now[attr])) {
10272           changed = changed || {};
10273           changed[attr] = now[attr];
10274         }
10275       }
10276       return changed;
10277     },
10278
10279     // Get the previous value of an attribute, recorded at the time the last
10280     // `"change"` event was fired.
10281     previous : function(attr) {
10282       if (!attr || !this._previousAttributes) return null;
10283       return this._previousAttributes[attr];
10284     },
10285
10286     // Get all of the attributes of the model at the time of the previous
10287     // `"change"` event.
10288     previousAttributes : function() {
10289       return _.clone(this._previousAttributes);
10290     },
10291
10292     // Run validation against a set of incoming attributes, returning `true`
10293     // if all is well. If a specific `error` callback has been passed,
10294     // call that instead of firing the general `"error"` event.
10295     _performValidation : function(attrs, options) {
10296       var error = this.validate(attrs);
10297       if (error) {
10298         if (options.error) {
10299           options.error(this, error, options);
10300         } else {
10301           this.trigger('error', this, error, options);
10302         }
10303         return false;
10304       }
10305       return true;
10306     }
10307
10308   });
10309
10310   // Backbone.Collection
10311   // -------------------
10312
10313   // Provides a standard collection class for our sets of models, ordered
10314   // or unordered. If a `comparator` is specified, the Collection will maintain
10315   // its models in sort order, as they're added and removed.
10316   Backbone.Collection = function(models, options) {
10317     options || (options = {});
10318     if (options.comparator) this.comparator = options.comparator;
10319     _.bindAll(this, '_onModelEvent', '_removeReference');
10320     this._reset();
10321     if (models) this.reset(models, {silent: true});
10322     this.initialize.apply(this, arguments);
10323   };
10324
10325   // Define the Collection's inheritable methods.
10326   _.extend(Backbone.Collection.prototype, Backbone.Events, {
10327
10328     // The default model for a collection is just a **Backbone.Model**.
10329     // This should be overridden in most cases.
10330     model : Backbone.Model,
10331
10332     // Initialize is an empty function by default. Override it with your own
10333     // initialization logic.
10334     initialize : function(){},
10335
10336     // The JSON representation of a Collection is an array of the
10337     // models' attributes.
10338     toJSON : function() {
10339       return this.map(function(model){ return model.toJSON(); });
10340     },
10341
10342     // Add a model, or list of models to the set. Pass **silent** to avoid
10343     // firing the `added` event for every new model.
10344     add : function(models, options) {
10345       if (_.isArray(models)) {
10346         for (var i = 0, l = models.length; i < l; i++) {
10347           this._add(models[i], options);
10348         }
10349       } else {
10350         this._add(models, options);
10351       }
10352       return this;
10353     },
10354
10355     // Remove a model, or a list of models from the set. Pass silent to avoid
10356     // firing the `removed` event for every model removed.
10357     remove : function(models, options) {
10358       if (_.isArray(models)) {
10359         for (var i = 0, l = models.length; i < l; i++) {
10360           this._remove(models[i], options);
10361         }
10362       } else {
10363         this._remove(models, options);
10364       }
10365       return this;
10366     },
10367
10368     // Get a model from the set by id.
10369     get : function(id) {
10370       if (id == null) return null;
10371       return this._byId[id.id != null ? id.id : id];
10372     },
10373
10374     // Get a model from the set by client id.
10375     getByCid : function(cid) {
10376       return cid && this._byCid[cid.cid || cid];
10377     },
10378
10379     // Get the model at the given index.
10380     at: function(index) {
10381       return this.models[index];
10382     },
10383
10384     // Force the collection to re-sort itself. You don't need to call this under normal
10385     // circumstances, as the set will maintain sort order as each item is added.
10386     sort : function(options) {
10387       options || (options = {});
10388       if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
10389       this.models = this.sortBy(this.comparator);
10390       if (!options.silent) this.trigger('reset', this, options);
10391       return this;
10392     },
10393
10394     // Pluck an attribute from each model in the collection.
10395     pluck : function(attr) {
10396       return _.map(this.models, function(model){ return model.get(attr); });
10397     },
10398
10399     // When you have more items than you want to add or remove individually,
10400     // you can reset the entire set with a new list of models, without firing
10401     // any `added` or `removed` events. Fires `reset` when finished.
10402     reset : function(models, options) {
10403       models  || (models = []);
10404       options || (options = {});
10405       this.each(this._removeReference);
10406       this._reset();
10407       this.add(models, {silent: true});
10408       if (!options.silent) this.trigger('reset', this, options);
10409       return this;
10410     },
10411
10412     // Fetch the default set of models for this collection, resetting the
10413     // collection when they arrive. If `add: true` is passed, appends the
10414     // models to the collection instead of resetting.
10415     fetch : function(options) {
10416       options || (options = {});
10417       var collection = this;
10418       var success = options.success;
10419       options.success = function(resp, status, xhr) {
10420         collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
10421         if (success) success(collection, resp);
10422       };
10423       options.error = wrapError(options.error, collection, options);
10424       return (this.sync || Backbone.sync).call(this, 'read', this, options);
10425     },
10426
10427     // Create a new instance of a model in this collection. After the model
10428     // has been created on the server, it will be added to the collection.
10429     // Returns the model, or 'false' if validation on a new model fails.
10430     create : function(model, options) {
10431       var coll = this;
10432       options || (options = {});
10433       model = this._prepareModel(model, options);
10434       if (!model) return false;
10435       var success = options.success;
10436       options.success = function(nextModel, resp, xhr) {
10437         coll.add(nextModel, options);
10438         if (success) success(nextModel, resp, xhr);
10439       };
10440       model.save(null, options);
10441       return model;
10442     },
10443
10444     // **parse** converts a response into a list of models to be added to the
10445     // collection. The default implementation is just to pass it through.
10446     parse : function(resp, xhr) {
10447       return resp;
10448     },
10449
10450     // Proxy to _'s chain. Can't be proxied the same way the rest of the
10451     // underscore methods are proxied because it relies on the underscore
10452     // constructor.
10453     chain: function () {
10454       return _(this.models).chain();
10455     },
10456
10457     // Reset all internal state. Called when the collection is reset.
10458     _reset : function(options) {
10459       this.length = 0;
10460       this.models = [];
10461       this._byId  = {};
10462       this._byCid = {};
10463     },
10464
10465     // Prepare a model to be added to this collection
10466     _prepareModel: function(model, options) {
10467       if (!(model instanceof Backbone.Model)) {
10468         var attrs = model;
10469         model = new this.model(attrs, {collection: this});
10470         if (model.validate && !model._performValidation(attrs, options)) model = false;
10471       } else if (!model.collection) {
10472         model.collection = this;
10473       }
10474       return model;
10475     },
10476
10477     // Internal implementation of adding a single model to the set, updating
10478     // hash indexes for `id` and `cid` lookups.
10479     // Returns the model, or 'false' if validation on a new model fails.
10480     _add : function(model, options) {
10481       options || (options = {});
10482       model = this._prepareModel(model, options);
10483       if (!model) return false;
10484       var already = this.getByCid(model);
10485       if (already) throw new Error(["Can't add the same model to a set twice", already.id]);
10486       this._byId[model.id] = model;
10487       this._byCid[model.cid] = model;
10488       var index = options.at != null ? options.at :
10489                   this.comparator ? this.sortedIndex(model, this.comparator) :
10490                   this.length;
10491       this.models.splice(index, 0, model);
10492       model.bind('all', this._onModelEvent);
10493       this.length++;
10494       if (!options.silent) model.trigger('add', model, this, options);
10495       return model;
10496     },
10497
10498     // Internal implementation of removing a single model from the set, updating
10499     // hash indexes for `id` and `cid` lookups.
10500     _remove : function(model, options) {
10501       options || (options = {});
10502       model = this.getByCid(model) || this.get(model);
10503       if (!model) return null;
10504       delete this._byId[model.id];
10505       delete this._byCid[model.cid];
10506       this.models.splice(this.indexOf(model), 1);
10507       this.length--;
10508       if (!options.silent) model.trigger('remove', model, this, options);
10509       this._removeReference(model);
10510       return model;
10511     },
10512
10513     // Internal method to remove a model's ties to a collection.
10514     _removeReference : function(model) {
10515       if (this == model.collection) {
10516         delete model.collection;
10517       }
10518       model.unbind('all', this._onModelEvent);
10519     },
10520
10521     // Internal method called every time a model in the set fires an event.
10522     // Sets need to update their indexes when models change ids. All other
10523     // events simply proxy through. "add" and "remove" events that originate
10524     // in other collections are ignored.
10525     _onModelEvent : function(ev, model, collection, options) {
10526       if ((ev == 'add' || ev == 'remove') && collection != this) return;
10527       if (ev == 'destroy') {
10528         this._remove(model, options);
10529       }
10530       if (model && ev === 'change:' + model.idAttribute) {
10531         delete this._byId[model.previous(model.idAttribute)];
10532         this._byId[model.id] = model;
10533       }
10534       this.trigger.apply(this, arguments);
10535     }
10536
10537   });
10538
10539   // Underscore methods that we want to implement on the Collection.
10540   var methods = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find', 'detect',
10541     'filter', 'select', 'reject', 'every', 'all', 'some', 'any', 'include',
10542     'contains', 'invoke', 'max', 'min', 'sortBy', 'sortedIndex', 'toArray', 'size',
10543     'first', 'rest', 'last', 'without', 'indexOf', 'lastIndexOf', 'isEmpty', 'groupBy'];
10544
10545   // Mix in each Underscore method as a proxy to `Collection#models`.
10546   _.each(methods, function(method) {
10547     Backbone.Collection.prototype[method] = function() {
10548       return _[method].apply(_, [this.models].concat(_.toArray(arguments)));
10549     };
10550   });
10551
10552   // Backbone.Router
10553   // -------------------
10554
10555   // Routers map faux-URLs to actions, and fire events when routes are
10556   // matched. Creating a new one sets its `routes` hash, if not set statically.
10557   Backbone.Router = function(options) {
10558     options || (options = {});
10559     if (options.routes) this.routes = options.routes;
10560     this._bindRoutes();
10561     this.initialize.apply(this, arguments);
10562   };
10563
10564   // Cached regular expressions for matching named param parts and splatted
10565   // parts of route strings.
10566   var namedParam    = /:([\w\d]+)/g;
10567   var splatParam    = /\*([\w\d]+)/g;
10568   var escapeRegExp  = /[-[\]{}()+?.,\\^$|#\s]/g;
10569
10570   // Set up all inheritable **Backbone.Router** properties and methods.
10571   _.extend(Backbone.Router.prototype, Backbone.Events, {
10572
10573     // Initialize is an empty function by default. Override it with your own
10574     // initialization logic.
10575     initialize : function(){},
10576
10577     // Manually bind a single named route to a callback. For example:
10578     //
10579     //     this.route('search/:query/p:num', 'search', function(query, num) {
10580     //       ...
10581     //     });
10582     //
10583     route : function(route, name, callback) {
10584       Backbone.history || (Backbone.history = new Backbone.History);
10585       if (!_.isRegExp(route)) route = this._routeToRegExp(route);
10586       Backbone.history.route(route, _.bind(function(fragment) {
10587         var args = this._extractParameters(route, fragment);
10588         callback.apply(this, args);
10589         this.trigger.apply(this, ['route:' + name].concat(args));
10590       }, this));
10591     },
10592
10593     // Simple proxy to `Backbone.history` to save a fragment into the history.
10594     navigate : function(fragment, triggerRoute) {
10595       Backbone.history.navigate(fragment, triggerRoute);
10596     },
10597
10598     // Bind all defined routes to `Backbone.history`. We have to reverse the
10599     // order of the routes here to support behavior where the most general
10600     // routes can be defined at the bottom of the route map.
10601     _bindRoutes : function() {
10602       if (!this.routes) return;
10603       var routes = [];
10604       for (var route in this.routes) {
10605         routes.unshift([route, this.routes[route]]);
10606       }
10607       for (var i = 0, l = routes.length; i < l; i++) {
10608         this.route(routes[i][0], routes[i][1], this[routes[i][1]]);
10609       }
10610     },
10611
10612     // Convert a route string into a regular expression, suitable for matching
10613     // against the current location hash.
10614     _routeToRegExp : function(route) {
10615       route = route.replace(escapeRegExp, "\\$&")
10616                    .replace(namedParam, "([^\/]*)")
10617                    .replace(splatParam, "(.*?)");
10618       return new RegExp('^' + route + '$');
10619     },
10620
10621     // Given a route, and a URL fragment that it matches, return the array of
10622     // extracted parameters.
10623     _extractParameters : function(route, fragment) {
10624       return route.exec(fragment).slice(1);
10625     }
10626
10627   });
10628
10629   // Backbone.History
10630   // ----------------
10631
10632   // Handles cross-browser history management, based on URL fragments. If the
10633   // browser does not support `onhashchange`, falls back to polling.
10634   Backbone.History = function() {
10635     this.handlers = [];
10636     _.bindAll(this, 'checkUrl');
10637   };
10638
10639   // Cached regex for cleaning hashes.
10640   var hashStrip = /^#*/;
10641
10642   // Cached regex for detecting MSIE.
10643   var isExplorer = /msie [\w.]+/;
10644
10645   // Has the history handling already been started?
10646   var historyStarted = false;
10647
10648   // Set up all inheritable **Backbone.History** properties and methods.
10649   _.extend(Backbone.History.prototype, {
10650
10651     // The default interval to poll for hash changes, if necessary, is
10652     // twenty times a second.
10653     interval: 50,
10654
10655     // Get the cross-browser normalized URL fragment, either from the URL,
10656     // the hash, or the override.
10657     getFragment : function(fragment, forcePushState) {
10658       if (fragment == null) {
10659         if (this._hasPushState || forcePushState) {
10660           fragment = window.location.pathname;
10661           var search = window.location.search;
10662           if (search) fragment += search;
10663           if (fragment.indexOf(this.options.root) == 0) fragment = fragment.substr(this.options.root.length);
10664         } else {
10665           fragment = window.location.hash;
10666         }
10667       }
10668       return decodeURIComponent(fragment.replace(hashStrip, ''));
10669     },
10670
10671     // Start the hash change handling, returning `true` if the current URL matches
10672     // an existing route, and `false` otherwise.
10673     start : function(options) {
10674
10675       // Figure out the initial configuration. Do we need an iframe?
10676       // Is pushState desired ... is it available?
10677       if (historyStarted) throw new Error("Backbone.history has already been started");
10678       this.options          = _.extend({}, {root: '/'}, this.options, options);
10679       this._wantsPushState  = !!this.options.pushState;
10680       this._hasPushState    = !!(this.options.pushState && window.history && window.history.pushState);
10681       var fragment          = this.getFragment();
10682       var docMode           = document.documentMode;
10683       var oldIE             = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
10684       if (oldIE) {
10685         this.iframe = $('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
10686         this.navigate(fragment);
10687       }
10688
10689       // Depending on whether we're using pushState or hashes, and whether
10690       // 'onhashchange' is supported, determine how we check the URL state.
10691       if (this._hasPushState) {
10692         $(window).bind('popstate', this.checkUrl);
10693       } else if ('onhashchange' in window && !oldIE) {
10694         $(window).bind('hashchange', this.checkUrl);
10695       } else {
10696         setInterval(this.checkUrl, this.interval);
10697       }
10698
10699       // Determine if we need to change the base url, for a pushState link
10700       // opened by a non-pushState browser.
10701       this.fragment = fragment;
10702       historyStarted = true;
10703       var loc = window.location;
10704       var atRoot  = loc.pathname == this.options.root;
10705       if (this._wantsPushState && !this._hasPushState && !atRoot) {
10706         this.fragment = this.getFragment(null, true);
10707         window.location.replace(this.options.root + '#' + this.fragment);
10708         // Return immediately as browser will do redirect to new url
10709         return true;
10710       } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
10711         this.fragment = loc.hash.replace(hashStrip, '');
10712         window.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment);
10713       }
10714
10715       if (!this.options.silent) {
10716         return this.loadUrl();
10717       }
10718     },
10719
10720     // Add a route to be tested when the fragment changes. Routes added later may
10721     // override previous routes.
10722     route : function(route, callback) {
10723       this.handlers.unshift({route : route, callback : callback});
10724     },
10725
10726     // Checks the current URL to see if it has changed, and if it has,
10727     // calls `loadUrl`, normalizing across the hidden iframe.
10728     checkUrl : function(e) {
10729       var current = this.getFragment();
10730       if (current == this.fragment && this.iframe) current = this.getFragment(this.iframe.location.hash);
10731       if (current == this.fragment || current == decodeURIComponent(this.fragment)) return false;
10732       if (this.iframe) this.navigate(current);
10733       this.loadUrl() || this.loadUrl(window.location.hash);
10734     },
10735
10736     // Attempt to load the current URL fragment. If a route succeeds with a
10737     // match, returns `true`. If no defined routes matches the fragment,
10738     // returns `false`.
10739     loadUrl : function(fragmentOverride) {
10740       var fragment = this.fragment = this.getFragment(fragmentOverride);
10741       var matched = _.any(this.handlers, function(handler) {
10742         if (handler.route.test(fragment)) {
10743           handler.callback(fragment);
10744           return true;
10745         }
10746       });
10747       return matched;
10748     },
10749
10750     // Save a fragment into the hash history. You are responsible for properly
10751     // URL-encoding the fragment in advance. This does not trigger
10752     // a `hashchange` event.
10753     navigate : function(fragment, triggerRoute) {
10754       var frag = (fragment || '').replace(hashStrip, '');
10755       if (this.fragment == frag || this.fragment == decodeURIComponent(frag)) return;
10756       if (this._hasPushState) {
10757         var loc = window.location;
10758         if (frag.indexOf(this.options.root) != 0) frag = this.options.root + frag;
10759         this.fragment = frag;
10760         window.history.pushState({}, document.title, loc.protocol + '//' + loc.host + frag);
10761       } else {
10762         window.location.hash = this.fragment = frag;
10763         if (this.iframe && (frag != this.getFragment(this.iframe.location.hash))) {
10764           this.iframe.document.open().close();
10765           this.iframe.location.hash = frag;
10766         }
10767       }
10768       if (triggerRoute) this.loadUrl(fragment);
10769     }
10770
10771   });
10772
10773   // Backbone.View
10774   // -------------
10775
10776   // Creating a Backbone.View creates its initial element outside of the DOM,
10777   // if an existing element is not provided...
10778   Backbone.View = function(options) {
10779     this.cid = _.uniqueId('view');
10780     this._configure(options || {});
10781     this._ensureElement();
10782     this.delegateEvents();
10783     this.initialize.apply(this, arguments);
10784   };
10785
10786   // Element lookup, scoped to DOM elements within the current view.
10787   // This should be prefered to global lookups, if you're dealing with
10788   // a specific view.
10789   var selectorDelegate = function(selector) {
10790     return $(selector, this.el);
10791   };
10792
10793   // Cached regex to split keys for `delegate`.
10794   var eventSplitter = /^(\S+)\s*(.*)$/;
10795
10796   // List of view options to be merged as properties.
10797   var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName'];
10798
10799   // Set up all inheritable **Backbone.View** properties and methods.
10800   _.extend(Backbone.View.prototype, Backbone.Events, {
10801
10802     // The default `tagName` of a View's element is `"div"`.
10803     tagName : 'div',
10804
10805     // Attach the `selectorDelegate` function as the `$` property.
10806     $       : selectorDelegate,
10807
10808     // Initialize is an empty function by default. Override it with your own
10809     // initialization logic.
10810     initialize : function(){},
10811
10812     // **render** is the core function that your view should override, in order
10813     // to populate its element (`this.el`), with the appropriate HTML. The
10814     // convention is for **render** to always return `this`.
10815     render : function() {
10816       return this;
10817     },
10818
10819     // Remove this view from the DOM. Note that the view isn't present in the
10820     // DOM by default, so calling this method may be a no-op.
10821     remove : function() {
10822       $(this.el).remove();
10823       return this;
10824     },
10825
10826     // For small amounts of DOM Elements, where a full-blown template isn't
10827     // needed, use **make** to manufacture elements, one at a time.
10828     //
10829     //     var el = this.make('li', {'class': 'row'}, this.model.escape('title'));
10830     //
10831     make : function(tagName, attributes, content) {
10832       var el = document.createElement(tagName);
10833       if (attributes) $(el).attr(attributes);
10834       if (content) $(el).html(content);
10835       return el;
10836     },
10837
10838     // Set callbacks, where `this.callbacks` is a hash of
10839     //
10840     // *{"event selector": "callback"}*
10841     //
10842     //     {
10843     //       'mousedown .title':  'edit',
10844     //       'click .button':     'save'
10845     //     }
10846     //
10847     // pairs. Callbacks will be bound to the view, with `this` set properly.
10848     // Uses event delegation for efficiency.
10849     // Omitting the selector binds the event to `this.el`.
10850     // This only works for delegate-able events: not `focus`, `blur`, and
10851     // not `change`, `submit`, and `reset` in Internet Explorer.
10852     delegateEvents : function(events) {
10853       if (!(events || (events = this.events))) return;
10854       if (_.isFunction(events)) events = events.call(this);
10855       $(this.el).unbind('.delegateEvents' + this.cid);
10856       for (var key in events) {
10857         var method = this[events[key]];
10858         if (!method) throw new Error('Event "' + events[key] + '" does not exist');
10859         var match = key.match(eventSplitter);
10860         var eventName = match[1], selector = match[2];
10861         method = _.bind(method, this);
10862         eventName += '.delegateEvents' + this.cid;
10863         if (selector === '') {
10864           $(this.el).bind(eventName, method);
10865         } else {
10866           $(this.el).delegate(selector, eventName, method);
10867         }
10868       }
10869     },
10870
10871     // Performs the initial configuration of a View with a set of options.
10872     // Keys with special meaning *(model, collection, id, className)*, are
10873     // attached directly to the view.
10874     _configure : function(options) {
10875       if (this.options) options = _.extend({}, this.options, options);
10876       for (var i = 0, l = viewOptions.length; i < l; i++) {
10877         var attr = viewOptions[i];
10878         if (options[attr]) this[attr] = options[attr];
10879       }
10880       this.options = options;
10881     },
10882
10883     // Ensure that the View has a DOM element to render into.
10884     // If `this.el` is a string, pass it through `$()`, take the first
10885     // matching element, and re-assign it to `el`. Otherwise, create
10886     // an element from the `id`, `className` and `tagName` proeprties.
10887     _ensureElement : function() {
10888       if (!this.el) {
10889         var attrs = this.attributes || {};
10890         if (this.id) attrs.id = this.id;
10891         if (this.className) attrs['class'] = this.className;
10892         this.el = this.make(this.tagName, attrs);
10893       } else if (_.isString(this.el)) {
10894         this.el = $(this.el).get(0);
10895       }
10896     }
10897
10898   });
10899
10900   // The self-propagating extend function that Backbone classes use.
10901   var extend = function (protoProps, classProps) {
10902     var child = inherits(this, protoProps, classProps);
10903     child.extend = this.extend;
10904     return child;
10905   };
10906
10907   // Set up inheritance for the model, collection, and view.
10908   Backbone.Model.extend = Backbone.Collection.extend =
10909     Backbone.Router.extend = Backbone.View.extend = extend;
10910
10911   // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
10912   var methodMap = {
10913     'create': 'POST',
10914     'update': 'PUT',
10915     'delete': 'DELETE',
10916     'read'  : 'GET'
10917   };
10918
10919   // Backbone.sync
10920   // -------------
10921
10922   // Override this function to change the manner in which Backbone persists
10923   // models to the server. You will be passed the type of request, and the
10924   // model in question. By default, uses makes a RESTful Ajax request
10925   // to the model's `url()`. Some possible customizations could be:
10926   //
10927   // * Use `setTimeout` to batch rapid-fire updates into a single request.
10928   // * Send up the models as XML instead of JSON.
10929   // * Persist models via WebSockets instead of Ajax.
10930   //
10931   // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
10932   // as `POST`, with a `_method` parameter containing the true HTTP method,
10933   // as well as all requests with the body as `application/x-www-form-urlencoded` instead of
10934   // `application/json` with the model in a param named `model`.
10935   // Useful when interfacing with server-side languages like **PHP** that make
10936   // it difficult to read the body of `PUT` requests.
10937   Backbone.sync = function(method, model, options) {
10938     var type = methodMap[method];
10939
10940     // Default JSON-request options.
10941     var params = _.extend({
10942       type:         type,
10943       dataType:     'json'
10944     }, options);
10945
10946     // Ensure that we have a URL.
10947     if (!params.url) {
10948       params.url = getUrl(model) || urlError();
10949     }
10950
10951     // Ensure that we have the appropriate request data.
10952     if (!params.data && model && (method == 'create' || method == 'update')) {
10953       params.contentType = 'application/json';
10954       params.data = JSON.stringify(model.toJSON());
10955     }
10956
10957     // For older servers, emulate JSON by encoding the request into an HTML-form.
10958     if (Backbone.emulateJSON) {
10959       params.contentType = 'application/x-www-form-urlencoded';
10960       params.data        = params.data ? {model : params.data} : {};
10961     }
10962
10963     // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
10964     // And an `X-HTTP-Method-Override` header.
10965     if (Backbone.emulateHTTP) {
10966       if (type === 'PUT' || type === 'DELETE') {
10967         if (Backbone.emulateJSON) params.data._method = type;
10968         params.type = 'POST';
10969         params.beforeSend = function(xhr) {
10970           xhr.setRequestHeader('X-HTTP-Method-Override', type);
10971         };
10972       }
10973     }
10974
10975     // Don't process data on a non-GET request.
10976     if (params.type !== 'GET' && !Backbone.emulateJSON) {
10977       params.processData = false;
10978     }
10979
10980     // Make the request.
10981     return $.ajax(params);
10982   };
10983
10984   // Helpers
10985   // -------
10986
10987   // Shared empty constructor function to aid in prototype-chain creation.
10988   var ctor = function(){};
10989
10990   // Helper function to correctly set up the prototype chain, for subclasses.
10991   // Similar to `goog.inherits`, but uses a hash of prototype properties and
10992   // class properties to be extended.
10993   var inherits = function(parent, protoProps, staticProps) {
10994     var child;
10995
10996     // The constructor function for the new subclass is either defined by you
10997     // (the "constructor" property in your `extend` definition), or defaulted
10998     // by us to simply call `super()`.
10999     if (protoProps && protoProps.hasOwnProperty('constructor')) {
11000       child = protoProps.constructor;
11001     } else {
11002       child = function(){ return parent.apply(this, arguments); };
11003     }
11004
11005     // Inherit class (static) properties from parent.
11006     _.extend(child, parent);
11007
11008     // Set the prototype chain to inherit from `parent`, without calling
11009     // `parent`'s constructor function.
11010     ctor.prototype = parent.prototype;
11011     child.prototype = new ctor();
11012
11013     // Add prototype properties (instance properties) to the subclass,
11014     // if supplied.
11015     if (protoProps) _.extend(child.prototype, protoProps);
11016
11017     // Add static properties to the constructor function, if supplied.
11018     if (staticProps) _.extend(child, staticProps);
11019
11020     // Correctly set child's `prototype.constructor`.
11021     child.prototype.constructor = child;
11022
11023     // Set a convenience property in case the parent's prototype is needed later.
11024     child.__super__ = parent.prototype;
11025
11026     return child;
11027   };
11028
11029   // Helper function to get a URL from a Model or Collection as a property
11030   // or as a function.
11031   var getUrl = function(object) {
11032     if (!(object && object.url)) return null;
11033     return _.isFunction(object.url) ? object.url() : object.url;
11034   };
11035
11036   // Throw an error when a URL is needed, and none is supplied.
11037   var urlError = function() {
11038     throw new Error('A "url" property or function must be specified');
11039   };
11040
11041   // Wrap an optional error callback with a fallback error event.
11042   var wrapError = function(onError, model, options) {
11043     return function(resp) {
11044       if (onError) {
11045         onError(model, resp, options);
11046       } else {
11047         model.trigger('error', model, resp, options);
11048       }
11049     };
11050   };
11051
11052   // Helper function to escape a string for HTML rendering.
11053   var escapeHTML = function(string) {
11054     return string.replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#x27;').replace(/\//g,'&#x2F;');
11055   };
11056
11057 }).call(this);
11058 /**
11059  * Castor - a cross site POSTing JavaScript logging library for Loggly
11060  *
11061  * Copyright (c) 2011 Loggly, Inc.
11062  * All rights reserved.
11063  *
11064  * Author: Kord Campbell <kord@loggly.com>
11065  * Date: May 2, 2011
11066  *
11067  * Uses methods from janky.post, copyright(c) 2011 Thomas Rampelberg <thomas@saunter.org>
11068  *
11069  * Sample usage (replace with your own Loggly HTTP input URL):
11070
11071   <script src="/js/loggly.js" type="text/javascript"></script>
11072   <script type="text/javascript">
11073     window.onload=function(){
11074       castor = new loggly({ url: 'http://logs.loggly.com/inputs/a4e839e9-4227-49aa-9d28-e18e5ba5a818?rt=1', level: 'WARN'});
11075       castor.log("url="+window.location.href + " browser=" + castor.user_agent + " height=" + castor.browser_size.height);
11076     }
11077   </script>
11078
11079  */
11080
11081 (function() {
11082   this.loggly = function(opts) {
11083     this.user_agent = get_agent();
11084     this.browser_size = get_size();
11085     log_methods = {'error': 5, 'warn': 4, 'info': 3, 'debug': 2, 'log': 1};
11086     if (!opts.url) throw new Error("Please include a Loggly HTTP URL.");
11087     if (!opts.level) {
11088       this.level = log_methods['info'];
11089     } else {
11090       this.level = log_methods[opts.level];
11091     }
11092     this.log = function(data) {
11093       if (log_methods['log'] == this.level) {
11094         opts.data = data;
11095         janky(opts);
11096       }
11097     };
11098     this.debug = function(data) {
11099       if (log_methods['debug'] >= this.level) {
11100         opts.data = data;
11101         janky(opts);
11102       }
11103     };
11104     this.info = function(data) {
11105       if (log_methods['info'] >= this.level) {
11106         opts.data = data;
11107         janky(opts);
11108       }
11109     };
11110     this.warn = function(data) {
11111       if (log_methods['warn'] >= this.level) {
11112         opts.data = data;
11113         janky(opts);
11114       }
11115     };
11116     this.error = function(data) {
11117       if (log_methods['error'] >= this.level) {
11118         opts.data = data;
11119         janky(opts);
11120       }
11121     };
11122   };
11123   this.janky = function(opts) {
11124     janky._form(function(iframe, form) {
11125       form.setAttribute("action", opts.url);
11126       form.setAttribute("method", "post");
11127       janky._input(iframe, form, opts.data);
11128       form.submit();
11129           setTimeout(function(){
11130         document.body.removeChild(iframe);
11131       }, 2000);
11132     });
11133   };
11134   this.janky._form = function(cb) {
11135     var iframe = document.createElement("iframe");
11136     document.body.appendChild(iframe);
11137     iframe.style.display = "none";
11138     setTimeout(function() {
11139       var form = iframe.contentWindow.document.createElement("form");
11140       iframe.contentWindow.document.body.appendChild(form);
11141       cb(iframe, form);
11142     }, 0);
11143   };
11144   this.janky._input = function(iframe, form, data) {
11145     var inp = iframe.contentWindow.document.createElement("input");
11146     inp.setAttribute("type", "hidden");
11147     inp.setAttribute("name", "source");
11148     inp.value = "castor " + data;
11149     form.appendChild(inp);
11150   };
11151   this.get_agent = function () {
11152     return navigator.appCodeName + navigator.appName + navigator.appVersion;
11153   };
11154   this.get_size = function () {
11155     var width = 0; var height = 0;
11156     if( typeof( window.innerWidth ) == 'number' ) {
11157       width = window.innerWidth; height = window.innerHeight;
11158     } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
11159       width = document.documentElement.clientWidth; height = document.documentElement.clientHeight;
11160     } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
11161       width = document.body.clientWidth; height = document.body.clientHeight;
11162     }
11163     return {'height': height, 'width': width};
11164   };
11165 })();
11166
11167
11168 jsworld={};jsworld.formatIsoDateTime=function(a,b){if(typeof a==="undefined")a=new Date;if(typeof b==="undefined")b=false;var c=jsworld.formatIsoDate(a)+" "+jsworld.formatIsoTime(a);if(b){var d=a.getHours()-a.getUTCHours();var e=Math.abs(d);var f=a.getUTCMinutes();var g=a.getMinutes();if(g!=f&&f<30&&d<0)e--;if(g!=f&&f>30&&d>0)e--;var h;if(g!=f)h=":30";else h=":00";var i;if(e<10)i="0"+e+h;else i=""+e+h;if(d<0)i="-"+i;else i="+"+i;c=c+i}return c};jsworld.formatIsoDate=function(a){if(typeof a==="undefined")a=new Date;var b=a.getFullYear();var c=a.getMonth()+1;var d=a.getDate();return b+"-"+jsworld._zeroPad(c,2)+"-"+jsworld._zeroPad(d,2)};jsworld.formatIsoTime=function(a){if(typeof a==="undefined")a=new Date;var b=a.getHours();var c=a.getMinutes();var d=a.getSeconds();return jsworld._zeroPad(b,2)+":"+jsworld._zeroPad(c,2)+":"+jsworld._zeroPad(d,2)};jsworld.parseIsoDateTime=function(a){if(typeof a!="string")throw"Error: The parameter must be a string";var b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d):(\d\d):(\d\d)/);if(b===null)b=a.match(/^(\d\d\d\d)(\d\d)(\d\d)[T ](\d\d)(\d\d)(\d\d)/);if(b===null)b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d)(\d\d)(\d\d)/);if(b===null)b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d):(\d\d):(\d\d)/);if(b===null)throw"Error: Invalid ISO-8601 date/time string";var c=parseInt(b[1],10);var d=parseInt(b[2],10);var e=parseInt(b[3],10);var f=parseInt(b[4],10);var g=parseInt(b[5],10);var h=parseInt(b[6],10);if(d<1||d>12||e<1||e>31||f<0||f>23||g<0||g>59||h<0||h>59)throw"Error: Invalid ISO-8601 date/time value";var i=new Date(c,d-1,e,f,g,h);if(i.getDate()!=e||i.getMonth()+1!=d)throw"Error: Invalid date";return i};jsworld.parseIsoDate=function(a){if(typeof a!="string")throw"Error: The parameter must be a string";var b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)/);if(b===null)b=a.match(/^(\d\d\d\d)(\d\d)(\d\d)/);if(b===null)throw"Error: Invalid ISO-8601 date string";var c=parseInt(b[1],10);var d=parseInt(b[2],10);var e=parseInt(b[3],10);if(d<1||d>12||e<1||e>31)throw"Error: Invalid ISO-8601 date value";var f=new Date(c,d-1,e);if(f.getDate()!=e||f.getMonth()+1!=d)throw"Error: Invalid date";return f};jsworld.parseIsoTime=function(a){if(typeof a!="string")throw"Error: The parameter must be a string";var b=a.match(/^(\d\d):(\d\d):(\d\d)/);if(b===null)b=a.match(/^(\d\d)(\d\d)(\d\d)/);if(b===null)throw"Error: Invalid ISO-8601 date/time string";var c=parseInt(b[1],10);var d=parseInt(b[2],10);var e=parseInt(b[3],10);if(c<0||c>23||d<0||d>59||e<0||e>59)throw"Error: Invalid ISO-8601 time value";return new Date(0,0,0,c,d,e)};jsworld._trim=function(a){var b=" \n\r\t\f \u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";for(var c=0;c<a.length;c++){if(b.indexOf(a.charAt(c))===-1){a=a.substring(c);break}}for(c=a.length-1;c>=0;c--){if(b.indexOf(a.charAt(c))===-1){a=a.substring(0,c+1);break}}return b.indexOf(a.charAt(0))===-1?a:""};jsworld._isNumber=function(a){if(typeof a=="number")return true;if(typeof a!="string")return false;var b=a+"";return/^-?(\d+|\d*\.\d+)$/.test(b)};jsworld._isInteger=function(a){if(typeof a!="number"&&typeof a!="string")return false;var b=a+"";return/^-?\d+$/.test(b)};jsworld._isFloat=function(a){if(typeof a!="number"&&typeof a!="string")return false;var b=a+"";return/^-?\.\d+?$/.test(b)};jsworld._hasOption=function(a,b){if(typeof a!="string"||typeof b!="string")return false;if(b.indexOf(a)!=-1)return true;else return false};jsworld._stringReplaceAll=function(a,b,c){var d;if(b.length==1&&c.length==1){d="";for(var e=0;e<a.length;e++){if(a.charAt(e)==b.charAt(0))d=d+c.charAt(0);else d=d+a.charAt(e)}return d}else{d=a;var f=d.indexOf(b);while(f!=-1){d=d.replace(b,c);f=d.indexOf(b)}return d}};jsworld._stringStartsWith=function(a,b){if(a.length<b.length)return false;for(var c=0;c<b.length;c++){if(a.charAt(c)!=b.charAt(c))return false}return true};jsworld._getPrecision=function(a){if(typeof a!="string")return-1;var b=a.match(/\.(\d)/);if(b)return parseInt(b[1],10);else return-1};jsworld._splitNumber=function(a){if(typeof a=="number")a=a+"";var b={};if(a.charAt(0)=="-")a=a.substring(1);var c=a.split(".");if(!c[1])c[1]="";b.integer=c[0];b.fraction=c[1];return b};jsworld._formatIntegerPart=function(a,b,c){if(c==""||b=="-1")return a;var d=b.split(";");var e="";var f=a.length;var g;while(f>0){if(d.length>0)g=parseInt(d.shift(),10);if(isNaN(g))throw"Error: Invalid grouping";if(g==-1){e=a.substring(0,f)+e;break}f-=g;if(f<1){e=a.substring(0,f+g)+e;break}e=c+a.substring(f,f+g)+e}return e};jsworld._formatFractionPart=function(a,b){for(var c=0;a.length<b;c++)a=a+"0";return a};jsworld._zeroPad=function(a,b){var c=a+"";while(c.length<b)c="0"+c;return c};jsworld._spacePad=function(a,b){var c=a+"";while(c.length<b)c=" "+c;return c};jsworld.Locale=function(a){this._className="jsworld.Locale";this._parseList=function(a,b){var c=[];if(a==null){throw"Names not defined"}else if(typeof a=="object"){c=a}else if(typeof a=="string"){c=a.split(";",b);for(var d=0;d<c.length;d++){if(c[d][0]=='"'&&c[d][c[d].length-1]=='"')c[d]=c[d].slice(1,-1);else throw"Missing double quotes"}}else{throw"Names must be an array or a string"}if(c.length!=b)throw"Expected "+b+" items, got "+c.length;return c};this._validateFormatString=function(a){if(typeof a=="string"&&a.length>0)return a;else throw"Empty or no string"};if(a==null||typeof a!="object")throw"Error: Invalid/missing locale properties";if(typeof a.decimal_point!="string")throw"Error: Invalid/missing decimal_point property";this.decimal_point=a.decimal_point;if(typeof a.thousands_sep!="string")throw"Error: Invalid/missing thousands_sep property";this.thousands_sep=a.thousands_sep;if(typeof a.grouping!="string")throw"Error: Invalid/missing grouping property";this.grouping=a.grouping;if(typeof a.int_curr_symbol!="string")throw"Error: Invalid/missing int_curr_symbol property";if(!/[A-Za-z]{3}.?/.test(a.int_curr_symbol))throw"Error: Invalid int_curr_symbol property";this.int_curr_symbol=a.int_curr_symbol;if(typeof a.currency_symbol!="string")throw"Error: Invalid/missing currency_symbol property";this.currency_symbol=a.currency_symbol;if(typeof a.frac_digits!="number"&&a.frac_digits<0)throw"Error: Invalid/missing frac_digits property";this.frac_digits=a.frac_digits;if(a.mon_decimal_point===null||a.mon_decimal_point==""){if(this.frac_digits>0)throw"Error: Undefined mon_decimal_point property";else a.mon_decimal_point=""}if(typeof a.mon_decimal_point!="string")throw"Error: Invalid/missing mon_decimal_point property";this.mon_decimal_point=a.mon_decimal_point;if(typeof a.mon_thousands_sep!="string")throw"Error: Invalid/missing mon_thousands_sep property";this.mon_thousands_sep=a.mon_thousands_sep;if(typeof a.mon_grouping!="string")throw"Error: Invalid/missing mon_grouping property";this.mon_grouping=a.mon_grouping;if(typeof a.positive_sign!="string")throw"Error: Invalid/missing positive_sign property";this.positive_sign=a.positive_sign;if(typeof a.negative_sign!="string")throw"Error: Invalid/missing negative_sign property";this.negative_sign=a.negative_sign;if(a.p_cs_precedes!==0&&a.p_cs_precedes!==1)throw"Error: Invalid/missing p_cs_precedes property, must be 0 or 1";this.p_cs_precedes=a.p_cs_precedes;if(a.n_cs_precedes!==0&&a.n_cs_precedes!==1)throw"Error: Invalid/missing n_cs_precedes, must be 0 or 1";this.n_cs_precedes=a.n_cs_precedes;if(a.p_sep_by_space!==0&&a.p_sep_by_space!==1&&a.p_sep_by_space!==2)throw"Error: Invalid/missing p_sep_by_space property, must be 0, 1 or 2";this.p_sep_by_space=a.p_sep_by_space;if(a.n_sep_by_space!==0&&a.n_sep_by_space!==1&&a.n_sep_by_space!==2)throw"Error: Invalid/missing n_sep_by_space property, must be 0, 1, or 2";this.n_sep_by_space=a.n_sep_by_space;if(a.p_sign_posn!==0&&a.p_sign_posn!==1&&a.p_sign_posn!==2&&a.p_sign_posn!==3&&a.p_sign_posn!==4)throw"Error: Invalid/missing p_sign_posn property, must be 0, 1, 2, 3 or 4";this.p_sign_posn=a.p_sign_posn;if(a.n_sign_posn!==0&&a.n_sign_posn!==1&&a.n_sign_posn!==2&&a.n_sign_posn!==3&&a.n_sign_posn!==4)throw"Error: Invalid/missing n_sign_posn property, must be 0, 1, 2, 3 or 4";this.n_sign_posn=a.n_sign_posn;if(typeof a.int_frac_digits!="number"&&a.int_frac_digits<0)throw"Error: Invalid/missing int_frac_digits property";this.int_frac_digits=a.int_frac_digits;if(a.int_p_cs_precedes!==0&&a.int_p_cs_precedes!==1)throw"Error: Invalid/missing int_p_cs_precedes property, must be 0 or 1";this.int_p_cs_precedes=a.int_p_cs_precedes;if(a.int_n_cs_precedes!==0&&a.int_n_cs_precedes!==1)throw"Error: Invalid/missing int_n_cs_precedes property, must be 0 or 1";this.int_n_cs_precedes=a.int_n_cs_precedes;if(a.int_p_sep_by_space!==0&&a.int_p_sep_by_space!==1&&a.int_p_sep_by_space!==2)throw"Error: Invalid/missing int_p_sep_by_spacev, must be 0, 1 or 2";this.int_p_sep_by_space=a.int_p_sep_by_space;if(a.int_n_sep_by_space!==0&&a.int_n_sep_by_space!==1&&a.int_n_sep_by_space!==2)throw"Error: Invalid/missing int_n_sep_by_space property, must be 0, 1, or 2";this.int_n_sep_by_space=a.int_n_sep_by_space;if(a.int_p_sign_posn!==0&&a.int_p_sign_posn!==1&&a.int_p_sign_posn!==2&&a.int_p_sign_posn!==3&&a.int_p_sign_posn!==4)throw"Error: Invalid/missing int_p_sign_posn property, must be 0, 1, 2, 3 or 4";this.int_p_sign_posn=a.int_p_sign_posn;if(a.int_n_sign_posn!==0&&a.int_n_sign_posn!==1&&a.int_n_sign_posn!==2&&a.int_n_sign_posn!==3&&a.int_n_sign_posn!==4)throw"Error: Invalid/missing int_n_sign_posn property, must be 0, 1, 2, 3 or 4";this.int_n_sign_posn=a.int_n_sign_posn;if(a==null||typeof a!="object")throw"Error: Invalid/missing time locale properties";try{this.abday=this._parseList(a.abday,7)}catch(b){throw"Error: Invalid abday property: "+b}try{this.day=this._parseList(a.day,7)}catch(b){throw"Error: Invalid day property: "+b}try{this.abmon=this._parseList(a.abmon,12)}catch(b){throw"Error: Invalid abmon property: "+b}try{this.mon=this._parseList(a.mon,12)}catch(b){throw"Error: Invalid mon property: "+b}try{this.d_fmt=this._validateFormatString(a.d_fmt)}catch(b){throw"Error: Invalid d_fmt property: "+b}try{this.t_fmt=this._validateFormatString(a.t_fmt)}catch(b){throw"Error: Invalid t_fmt property: "+b}try{this.d_t_fmt=this._validateFormatString(a.d_t_fmt)}catch(b){throw"Error: Invalid d_t_fmt property: "+b}try{var c=this._parseList(a.am_pm,2);this.am=c[0];this.pm=c[1]}catch(b){this.am="";this.pm=""}this.getAbbreviatedWeekdayName=function(a){if(typeof a=="undefined"||a===null)return this.abday;if(!jsworld._isInteger(a)||a<0||a>6)throw"Error: Invalid weekday argument, must be an integer [0..6]";return this.abday[a]};this.getWeekdayName=function(a){if(typeof a=="undefined"||a===null)return this.day;if(!jsworld._isInteger(a)||a<0||a>6)throw"Error: Invalid weekday argument, must be an integer [0..6]";return this.day[a]};this.getAbbreviatedMonthName=function(a){if(typeof a=="undefined"||a===null)return this.abmon;if(!jsworld._isInteger(a)||a<0||a>11)throw"Error: Invalid month argument, must be an integer [0..11]";return this.abmon[a]};this.getMonthName=function(a){if(typeof a=="undefined"||a===null)return this.mon;if(!jsworld._isInteger(a)||a<0||a>11)throw"Error: Invalid month argument, must be an integer [0..11]";return this.mon[a]};this.getDecimalPoint=function(){return this.decimal_point};this.getCurrencySymbol=function(){return this.currency_symbol};this.getIntCurrencySymbol=function(){return this.int_curr_symbol.substring(0,3)};this.currencySymbolPrecedes=function(){if(this.p_cs_precedes==1)return true;else return false};this.intCurrencySymbolPrecedes=function(){if(this.int_p_cs_precedes==1)return true;else return false};this.getMonetaryDecimalPoint=function(){return this.mon_decimal_point};this.getFractionalDigits=function(){return this.frac_digits};this.getIntFractionalDigits=function(){return this.int_frac_digits}};jsworld.NumericFormatter=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance";this.lc=a;this.format=function(a,b){if(typeof a=="string")a=jsworld._trim(a);if(!jsworld._isNumber(a))throw"Error: The input is not a number";var c=parseFloat(a,10);var d=jsworld._getPrecision(b);if(d!=-1)c=Math.round(c*Math.pow(10,d))/Math.pow(10,d);var e=jsworld._splitNumber(String(c));var f;if(c===0)f="0";else f=jsworld._hasOption("^",b)?e.integer:jsworld._formatIntegerPart(e.integer,this.lc.grouping,this.lc.thousands_sep);var g=d!=-1?jsworld._formatFractionPart(e.fraction,d):e.fraction;var h=g.length?f+this.lc.decimal_point+g:f;if(jsworld._hasOption("~",b)||c===0){return h}else{if(jsworld._hasOption("+",b)||c<0){if(c>0)return"+"+h;else if(c<0)return"-"+h;else return h}else{return h}}}};jsworld.DateTimeFormatter=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance.";this.lc=a;this.formatDate=function(a){var b=null;if(typeof a=="string"){try{b=jsworld.parseIsoDate(a)}catch(c){b=jsworld.parseIsoDateTime(a)}}else if(a!==null&&typeof a=="object"){b=a}else{throw"Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"}return this._applyFormatting(b,this.lc.d_fmt)};this.formatTime=function(a){var b=null;if(typeof a=="string"){try{b=jsworld.parseIsoTime(a)}catch(c){b=jsworld.parseIsoDateTime(a)}}else if(a!==null&&typeof a=="object"){b=a}else{throw"Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"}return this._applyFormatting(b,this.lc.t_fmt)};this.formatDateTime=function(a){var b=null;if(typeof a=="string"){b=jsworld.parseIsoDateTime(a)}else if(a!==null&&typeof a=="object"){b=a}else{throw"Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"}return this._applyFormatting(b,this.lc.d_t_fmt)};this._applyFormatting=function(a,b){b=b.replace(/%%/g,"%");b=b.replace(/%a/g,this.lc.abday[a.getDay()]);b=b.replace(/%A/g,this.lc.day[a.getDay()]);b=b.replace(/%b/g,this.lc.abmon[a.getMonth()]);b=b.replace(/%B/g,this.lc.mon[a.getMonth()]);b=b.replace(/%d/g,jsworld._zeroPad(a.getDate(),2));b=b.replace(/%e/g,jsworld._spacePad(a.getDate(),2));b=b.replace(/%F/g,a.getFullYear()+"-"+jsworld._zeroPad(a.getMonth()+1,2)+"-"+jsworld._zeroPad(a.getDate(),2));b=b.replace(/%h/g,this.lc.abmon[a.getMonth()]);b=b.replace(/%H/g,jsworld._zeroPad(a.getHours(),2));b=b.replace(/%I/g,jsworld._zeroPad(this._hours12(a.getHours()),2));b=b.replace(/%k/g,a.getHours());b=b.replace(/%l/g,this._hours12(a.getHours()));b=b.replace(/%m/g,jsworld._zeroPad(a.getMonth()+1,2));b=b.replace(/%n/g,"\n");b=b.replace(/%M/g,jsworld._zeroPad(a.getMinutes(),2));b=b.replace(/%p/g,this._getAmPm(a.getHours()));b=b.replace(/%P/g,this._getAmPm(a.getHours()).toLocaleLowerCase());b=b.replace(/%R/g,jsworld._zeroPad(a.getHours(),2)+":"+jsworld._zeroPad(a.getMinutes(),2));b=b.replace(/%S/g,jsworld._zeroPad(a.getSeconds(),2));b=b.replace(/%T/g,jsworld._zeroPad(a.getHours(),2)+":"+jsworld._zeroPad(a.getMinutes(),2)+":"+jsworld._zeroPad(a.getSeconds(),2));b=b.replace(/%w/g,this.lc.day[a.getDay()]);b=b.replace(/%y/g,(new String(a.getFullYear())).substring(2));b=b.replace(/%Y/g,a.getFullYear());b=b.replace(/%Z/g,"");b=b.replace(/%[a-zA-Z]/g,"");return b};this._hours12=function(a){if(a===0)return 12;else if(a>12)return a-12;else return a};this._getAmPm=function(a){if(a===0||a>12)return this.lc.pm;else return this.lc.am}};jsworld.MonetaryFormatter=function(a,b,c){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance";this.lc=a;this.currencyFractionDigits={AFN:0,ALL:0,AMD:0,BHD:3,BIF:0,BYR:0,CLF:0,CLP:0,COP:0,CRC:0,DJF:0,GNF:0,GYD:0,HUF:0,IDR:0,IQD:0,IRR:0,ISK:0,JOD:3,JPY:0,KMF:0,KRW:0,KWD:3,LAK:0,LBP:0,LYD:3,MGA:0,MMK:0,MNT:0,MRO:0,MUR:0,OMR:3,PKR:0,PYG:0,RSD:0,RWF:0,SLL:0,SOS:0,STD:0,SYP:0,TND:3,TWD:0,TZS:0,UGX:0,UZS:0,VND:0,VUV:0,XAF:0,XOF:0,XPF:0,YER:0,ZMK:0};if(typeof b=="string"){this.currencyCode=b.toUpperCase();var d=this.currencyFractionDigits[this.currencyCode];if(typeof d!="number")d=2;this.lc.frac_digits=d;this.lc.int_frac_digits=d}else{this.currencyCode=this.lc.int_curr_symbol.substring(0,3).toUpperCase()}this.intSep=this.lc.int_curr_symbol.charAt(3);if(this.currencyCode==this.lc.int_curr_symbol.substring(0,3)){this.internationalFormatting=false;this.curSym=this.lc.currency_symbol}else{if(typeof c=="string"){this.curSym=c;this.internationalFormatting=false}else{this.internationalFormatting=true}}this.getCurrencySymbol=function(){return this.curSym};this.currencySymbolPrecedes=function(a){if(typeof a=="string"&&a=="i"){if(this.lc.int_p_cs_precedes==1)return true;else return false}else{if(this.internationalFormatting){if(this.lc.int_p_cs_precedes==1)return true;else return false}else{if(this.lc.p_cs_precedes==1)return true;else return false}}};this.getDecimalPoint=function(){return this.lc.mon_decimal_point};this.getFractionalDigits=function(a){if(typeof a=="string"&&a=="i"){return this.lc.int_frac_digits}else{if(this.internationalFormatting)return this.lc.int_frac_digits;else return this.lc.frac_digits}};this.format=function(a,b){var c;if(typeof a=="string"){a=jsworld._trim(a);c=parseFloat(a);if(typeof c!="number"||isNaN(c))throw"Error: Amount string not a number"}else if(typeof a=="number"){c=a}else{throw"Error: Amount not a number"}var d=jsworld._getPrecision(b);if(d==-1){if(this.internationalFormatting||jsworld._hasOption("i",b))d=this.lc.int_frac_digits;else d=this.lc.frac_digits}c=Math.round(c*Math.pow(10,d))/Math.pow(10,d);var e=jsworld._splitNumber(String(c));var f;if(c===0)f="0";else f=jsworld._hasOption("^",b)?e.integer:jsworld._formatIntegerPart(e.integer,this.lc.mon_grouping,this.lc.mon_thousands_sep);var g;if(d==-1){if(this.internationalFormatting||jsworld._hasOption("i",b))g=jsworld._formatFractionPart(e.fraction,this.lc.int_frac_digits);else g=jsworld._formatFractionPart(e.fraction,this.lc.frac_digits)}else{g=jsworld._formatFractionPart(e.fraction,d)}var h;if(this.lc.frac_digits>0||g.length)h=f+this.lc.mon_decimal_point+g;else h=f;if(jsworld._hasOption("~",b)){return h}else{var i=jsworld._hasOption("!",b)?true:false;var j=c<0?"-":"+";if(this.internationalFormatting||jsworld._hasOption("i",b)){if(i)return this._formatAsInternationalCurrencyWithNoSym(j,h);else return this._formatAsInternationalCurrency(j,h)}else{if(i)return this._formatAsLocalCurrencyWithNoSym(j,h);else return this._formatAsLocalCurrency(j,h)}}};this._formatAsLocalCurrency=function(a,b){if(a=="+"){if(this.lc.p_sign_posn===0&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return"("+b+this.curSym+")"}else if(this.lc.p_sign_posn===0&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return"("+this.curSym+b+")"}else if(this.lc.p_sign_posn===0&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return"("+b+" "+this.curSym+")"}else if(this.lc.p_sign_posn===0&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return"("+this.curSym+" "+b+")"}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+b+this.curSym}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+this.curSym+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+b+" "+this.curSym}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+this.curSym+" "+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+" "+b+this.curSym}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+this.curSym+b}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.curSym+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.curSym+b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.curSym+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.curSym+" "+b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.curSym+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.curSym+b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign+this.curSym}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+this.curSym+b}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign+this.curSym}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+this.curSym+" "+b}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign+" "+this.curSym}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+this.curSym+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.curSym+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.curSym+this.lc.positive_sign+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.curSym+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.curSym+this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.curSym+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.curSym+" "+this.lc.positive_sign+b}}else if(a=="-"){if(this.lc.n_sign_posn===0&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return"("+b+this.curSym+")"}else if(this.lc.n_sign_posn===0&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return"("+this.curSym+b+")"}else if(this.lc.n_sign_posn===0&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return"("+b+" "+this.curSym+")"}else if(this.lc.n_sign_posn===0&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return"("+this.curSym+" "+b+")"}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+b+this.curSym}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+this.curSym+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+b+" "+this.curSym}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+this.curSym+" "+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+" "+b+this.curSym}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+this.curSym+b}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.curSym+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.curSym+b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.curSym+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.curSym+" "+b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+this.curSym+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.curSym+b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign+this.curSym}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+this.curSym+b}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign+this.curSym}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+this.curSym+" "+b}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign+" "+this.curSym}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+this.curSym+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.curSym+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.curSym+this.lc.negative_sign+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.curSym+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.curSym+this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+this.curSym+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.curSym+" "+this.lc.negative_sign+b}}throw"Error: Invalid POSIX LC MONETARY definition"};this._formatAsInternationalCurrency=function(a,b){if(a=="+"){if(this.lc.int_p_sign_posn===0&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return"("+b+this.currencyCode+")"}else if(this.lc.int_p_sign_posn===0&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return"("+this.currencyCode+b+")"}else if(this.lc.int_p_sign_posn===0&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return"("+b+this.intSep+this.currencyCode+")"}else if(this.lc.int_p_sign_posn===0&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return"("+this.currencyCode+this.intSep+b+")"}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+b+this.currencyCode}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.currencyCode+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+b+this.intSep+this.currencyCode}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.currencyCode+this.intSep+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+this.intSep+b+this.currencyCode}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+this.currencyCode+b}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.currencyCode+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.currencyCode+b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.currencyCode+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.currencyCode+this.intSep+b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.currencyCode+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.currencyCode+b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign+this.currencyCode}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.currencyCode+b}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign+this.currencyCode}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.currencyCode+this.intSep+b}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign+this.intSep+this.currencyCode}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+this.currencyCode+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.currencyCode+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.currencyCode+this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.currencyCode+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.currencyCode+this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.currencyCode+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.currencyCode+this.intSep+this.lc.positive_sign+b}}else if(a=="-"){if(this.lc.int_n_sign_posn===0&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return"("+b+this.currencyCode+")"}else if(this.lc.int_n_sign_posn===0&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return"("+this.currencyCode+b+")"}else if(this.lc.int_n_sign_posn===0&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return"("+b+this.intSep+this.currencyCode+")"}else if(this.lc.int_n_sign_posn===0&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return"("+this.currencyCode+this.intSep+b+")"}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+b+this.currencyCode}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.currencyCode+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+b+this.intSep+this.currencyCode}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.currencyCode+this.intSep+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+this.intSep+b+this.currencyCode}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+this.currencyCode+b}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.currencyCode+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.currencyCode+b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.currencyCode+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.currencyCode+this.intSep+b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.currencyCode+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.currencyCode+b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign+this.currencyCode}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.currencyCode+b}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign+this.currencyCode}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.currencyCode+this.intSep+b}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign+this.intSep+this.currencyCode}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+this.currencyCode+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.currencyCode+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.currencyCode+this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.currencyCode+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.currencyCode+this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.currencyCode+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.currencyCode+this.intSep+this.lc.negative_sign+b}}throw"Error: Invalid POSIX LC MONETARY definition"};this._formatAsLocalCurrencyWithNoSym=function(a,b){if(a=="+"){if(this.lc.p_sign_posn===0){return"("+b+")"}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}}else if(a=="-"){if(this.lc.n_sign_posn===0){return"("+b+")"}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+b}}throw"Error: Invalid POSIX LC MONETARY definition"};this._formatAsInternationalCurrencyWithNoSym=function(a,b){if(a=="+"){if(this.lc.int_p_sign_posn===0){return"("+b+")"}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+b}}else if(a=="-"){if(this.lc.int_n_sign_posn===0){return"("+b+")"}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+b}}throw"Error: Invalid POSIX LC_MONETARY definition"}};jsworld.NumericParser=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance";this.lc=a;this.parse=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=jsworld._trim(a);b=jsworld._stringReplaceAll(a,this.lc.thousands_sep,"");b=jsworld._stringReplaceAll(b,this.lc.decimal_point,".");if(jsworld._isNumber(b))return parseFloat(b,10);else throw"Parse error: Invalid number string"}};jsworld.DateTimeParser=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance.";this.lc=a;this.parseTime=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=this._extractTokens(this.lc.t_fmt,a);var c=false;if(b.hour!==null&&b.minute!==null&&b.second!==null){c=true}else if(b.hourAmPm!==null&&b.am!==null&&b.minute!==null&&b.second!==null){if(b.am){b.hour=parseInt(b.hourAmPm,10)}else{if(b.hourAmPm==12)b.hour=0;else b.hour=parseInt(b.hourAmPm,10)+12}c=true}if(c)return jsworld._zeroPad(b.hour,2)+":"+jsworld._zeroPad(b.minute,2)+":"+jsworld._zeroPad(b.second,2);else throw"Parse error: Invalid/ambiguous time string"};this.parseDate=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=this._extractTokens(this.lc.d_fmt,a);var c=false;if(b.year!==null&&b.month!==null&&b.day!==null){c=true}if(c)return jsworld._zeroPad(b.year,4)+"-"+jsworld._zeroPad(b.month,2)+"-"+jsworld._zeroPad(b.day,2);else throw"Parse error: Invalid date string"};this.parseDateTime=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=this._extractTokens(this.lc.d_t_fmt,a);var c=false;var d=false;if(b.hour!==null&&b.minute!==null&&b.second!==null){c=true}else if(b.hourAmPm!==null&&b.am!==null&&b.minute!==null&&b.second!==null){if(b.am){b.hour=parseInt(b.hourAmPm,10)}else{if(b.hourAmPm==12)b.hour=0;else b.hour=parseInt(b.hourAmPm,10)+12}c=true}if(b.year!==null&&b.month!==null&&b.day!==null){d=true}if(d&&c)return jsworld._zeroPad(b.year,4)+"-"+jsworld._zeroPad(b.month,2)+"-"+jsworld._zeroPad(b.day,2)+" "+jsworld._zeroPad(b.hour,2)+":"+jsworld._zeroPad(b.minute,2)+":"+jsworld._zeroPad(b.second,2);else throw"Parse error: Invalid/ambiguous date/time string"};this._extractTokens=function(a,b){var c={year:null,month:null,day:null,hour:null,hourAmPm:null,am:null,minute:null,second:null,weekday:null};while(a.length>0){if(a.charAt(0)=="%"&&a.charAt(1)!=""){var d=a.substring(0,2);if(d=="%%"){b=b.substring(1)}else if(d=="%a"){for(var e=0;e<this.lc.abday.length;e++){if(jsworld._stringStartsWith(b,this.lc.abday[e])){c.weekday=e;b=b.substring(this.lc.abday[e].length);break}}if(c.weekday===null)throw"Parse error: Unrecognised abbreviated weekday name (%a)"}else if(d=="%A"){for(var e=0;e<this.lc.day.length;e++){if(jsworld._stringStartsWith(b,this.lc.day[e])){c.weekday=e;b=b.substring(this.lc.day[e].length);break}}if(c.weekday===null)throw"Parse error: Unrecognised weekday name (%A)"}else if(d=="%b"||d=="%h"){for(var e=0;e<this.lc.abmon.length;e++){if(jsworld._stringStartsWith(b,this.lc.abmon[e])){c.month=e+1;b=b.substring(this.lc.abmon[e].length);break}}if(c.month===null)throw"Parse error: Unrecognised abbreviated month name (%b)"}else if(d=="%B"){for(var e=0;e<this.lc.mon.length;e++){if(jsworld._stringStartsWith(b,this.lc.mon[e])){c.month=e+1;b=b.substring(this.lc.mon[e].length);break}}if(c.month===null)throw"Parse error: Unrecognised month name (%B)"}else if(d=="%d"){if(/^0[1-9]|[1-2][0-9]|3[0-1]/.test(b)){c.day=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised day of the month (%d)"}else if(d=="%e"){var f=b.match(/^\s?(\d{1,2})/);c.day=parseInt(f,10);if(isNaN(c.day)||c.day<1||c.day>31)throw"Parse error: Unrecognised day of the month (%e)";b=b.substring(f.length)}else if(d=="%F"){if(/^\d\d\d\d/.test(b)){c.year=parseInt(b.substring(0,4),10);b=b.substring(4)}else{throw"Parse error: Unrecognised date (%F)"}if(jsworld._stringStartsWith(b,"-"))b=b.substring(1);else throw"Parse error: Unrecognised date (%F)";if(/^0[1-9]|1[0-2]/.test(b)){c.month=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised date (%F)";if(jsworld._stringStartsWith(b,"-"))b=b.substring(1);else throw"Parse error: Unrecognised date (%F)";if(/^0[1-9]|[1-2][0-9]|3[0-1]/.test(b)){c.day=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised date (%F)"}else if(d=="%H"){if(/^[0-1][0-9]|2[0-3]/.test(b)){c.hour=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised hour (%H)"}else if(d=="%I"){if(/^0[1-9]|1[0-2]/.test(b)){c.hourAmPm=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised hour (%I)"}else if(d=="%k"){var g=b.match(/^(\d{1,2})/);c.hour=parseInt(g,10);if(isNaN(c.hour)||c.hour<0||c.hour>23)throw"Parse error: Unrecognised hour (%k)";b=b.substring(g.length)}else if(d=="%l"){var g=b.match(/^(\d{1,2})/);c.hourAmPm=parseInt(g,10);if(isNaN(c.hourAmPm)||c.hourAmPm<1||c.hourAmPm>12)throw"Parse error: Unrecognised hour (%l)";b=b.substring(g.length)}else if(d=="%m"){if(/^0[1-9]|1[0-2]/.test(b)){c.month=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised month (%m)"}else if(d=="%M"){if(/^[0-5][0-9]/.test(b)){c.minute=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised minute (%M)"}else if(d=="%n"){if(b.charAt(0)=="\n")b=b.substring(1);else throw"Parse error: Unrecognised new line (%n)"}else if(d=="%p"){if(jsworld._stringStartsWith(b,this.lc.am)){c.am=true;b=b.substring(this.lc.am.length)}else if(jsworld._stringStartsWith(b,this.lc.pm)){c.am=false;b=b.substring(this.lc.pm.length)}else throw"Parse error: Unrecognised AM/PM value (%p)"}else if(d=="%P"){if(jsworld._stringStartsWith(b,this.lc.am.toLowerCase())){c.am=true;b=b.substring(this.lc.am.length)}else if(jsworld._stringStartsWith(b,this.lc.pm.toLowerCase())){c.am=false;b=b.substring(this.lc.pm.length)}else throw"Parse error: Unrecognised AM/PM value (%P)"}else if(d=="%R"){if(/^[0-1][0-9]|2[0-3]/.test(b)){c.hour=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%R)";if(jsworld._stringStartsWith(b,":"))b=b.substring(1);else throw"Parse error: Unrecognised time (%R)";if(/^[0-5][0-9]/.test(b)){c.minute=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%R)"}else if(d=="%S"){if(/^[0-5][0-9]/.test(b)){c.second=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised second (%S)"}else if(d=="%T"){if(/^[0-1][0-9]|2[0-3]/.test(b)){c.hour=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%T)";if(jsworld._stringStartsWith(b,":"))b=b.substring(1);else throw"Parse error: Unrecognised time (%T)";if(/^[0-5][0-9]/.test(b)){c.minute=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%T)";if(jsworld._stringStartsWith(b,":"))b=b.substring(1);else throw"Parse error: Unrecognised time (%T)";if(/^[0-5][0-9]/.test(b)){c.second=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%T)"}else if(d=="%w"){if(/^\d/.test(b)){c.weekday=parseInt(b.substring(0,1),10);b=b.substring(1)}else throw"Parse error: Unrecognised weekday number (%w)"}else if(d=="%y"){if(/^\d\d/.test(b)){var h=parseInt(b.substring(0,2),10);if(h>50)c.year=1900+h;else c.year=2e3+h;b=b.substring(2)}else throw"Parse error: Unrecognised year (%y)"}else if(d=="%Y"){if(/^\d\d\d\d/.test(b)){c.year=parseInt(b.substring(0,4),10);b=b.substring(4)}else throw"Parse error: Unrecognised year (%Y)"}else if(d=="%Z"){if(a.length===0)break}a=a.substring(2)}else{if(a.charAt(0)!=b.charAt(0))throw'Parse error: Unexpected symbol "'+b.charAt(0)+'" in date/time string';a=a.substring(1);b=b.substring(1)}}return c}};jsworld.MonetaryParser=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance";this.lc=a;this.parse=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=this._detectCurrencySymbolType(a);var c,d;if(b=="local"){c="local";d=a.replace(this.lc.getCurrencySymbol(),"")}else if(b=="int"){c="int";d=a.replace(this.lc.getIntCurrencySymbol(),"")}else if(b=="none"){c="local";d=a}else throw"Parse error: Internal assert failure";d=jsworld._stringReplaceAll(d,this.lc.mon_thousands_sep,"");d=d.replace(this.lc.mon_decimal_point,".");d=d.replace(/\s*/g,"");d=this._removeLocalNonNegativeSign(d,c);d=this._normaliseNegativeSign(d,c);if(jsworld._isNumber(d))return parseFloat(d,10);else throw"Parse error: Invalid currency amount string"};this._detectCurrencySymbolType=function(a){if(this.lc.getCurrencySymbol().length>this.lc.getIntCurrencySymbol().length){if(a.indexOf(this.lc.getCurrencySymbol())!=-1)return"local";else if(a.indexOf(this.lc.getIntCurrencySymbol())!=-1)return"int";else return"none"}else{if(a.indexOf(this.lc.getIntCurrencySymbol())!=-1)return"int";else if(a.indexOf(this.lc.getCurrencySymbol())!=-1)return"local";else return"none"}};this._removeLocalNonNegativeSign=function(a,b){a=a.replace(this.lc.positive_sign,"");if((b=="local"&&this.lc.p_sign_posn===0||b=="int"&&this.lc.int_p_sign_posn===0)&&/\(\d+\.?\d*\)/.test(a)){a=a.replace("(","");a=a.replace(")","")}return a};this._normaliseNegativeSign=function(a,b){a=a.replace(this.lc.negative_sign,"-");if(b=="local"&&this.lc.n_sign_posn===0||b=="int"&&this.lc.int_n_sign_posn===0){if(/^\(\d+\.?\d*\)$/.test(a)){a=a.replace("(","");a=a.replace(")","");return"-"+a}}if(b=="local"&&this.lc.n_sign_posn==2||b=="int"&&this.lc.int_n_sign_posn==2){if(/^\d+\.?\d*-$/.test(a)){a=a.replace("-","");return"-"+a}}if(b=="local"&&this.lc.n_cs_precedes===0&&this.lc.n_sign_posn==3||b=="local"&&this.lc.n_cs_precedes===0&&this.lc.n_sign_posn==4||b=="int"&&this.lc.int_n_cs_precedes===0&&this.lc.int_n_sign_posn==3||b=="int"&&this.lc.int_n_cs_precedes===0&&this.lc.int_n_sign_posn==4){if(/^\d+\.?\d*-$/.test(a)){a=a.replace("-","");return"-"+a}}return a}}
11169
11170
11171 if(typeof POSIX_LC == "undefined") var POSIX_LC = {};
11172
11173 POSIX_LC.en_US = {
11174     "decimal_point"      : ".",
11175     "thousands_sep"      : ",",
11176     "grouping"           : "3",
11177     "abday"              : ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],
11178     "day"                : ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],
11179     "abmon"              : ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],
11180     "mon"                : ["January","February","March","April","May","June","July","August","September","October","November","December"],
11181     "d_fmt"              : "%m/%e/%y",
11182     "t_fmt"              : "%I:%M:%S %p",
11183     "d_t_fmt"            : "%B %e, %Y %I:%M:%S %p %Z",
11184     "am_pm"              : ["AM","PM"],
11185     "int_curr_symbol"    : "USD ",
11186     "currency_symbol"    : "\u0024",
11187     "mon_decimal_point"  : ".",
11188     "mon_thousands_sep"  : ",",
11189     "mon_grouping"       : "3",
11190     "positive_sign"      : "",
11191     "negative_sign"      : "-",
11192     "int_frac_digits"    : 2,
11193     "frac_digits"        : 2,
11194     "p_cs_precedes"      : 1,
11195     "n_cs_precedes"      : 1,
11196     "p_sep_by_space"     : 0,
11197     "n_sep_by_space"     : 0,
11198     "p_sign_posn"        : 1,
11199     "n_sign_posn"        : 1,
11200     "int_p_cs_precedes"  : 1,
11201     "int_n_cs_precedes"  : 1,
11202     "int_p_sep_by_space" : 0,
11203     "int_n_sep_by_space" : 0,
11204     "int_p_sign_posn"    : 1,
11205     "int_n_sign_posn"    : 1
11206 }
11207
11208 if(typeof POSIX_LC == "undefined") var POSIX_LC = {};
11209
11210 POSIX_LC.fr_FR = {
11211     "decimal_point"      : ",",
11212     "thousands_sep"      : "\u00a0",
11213     "grouping"           : "3",
11214     "abday"              : ["dim.","lun.","mar.",
11215                             "mer.","jeu.","ven.",
11216                 "sam."],
11217     "day"                : ["dimanche","lundi","mardi",
11218                             "mercredi","jeudi","vendredi",
11219                 "samedi"],
11220     "abmon"              : ["janv.","f\u00e9vr.","mars",
11221                             "avr.","mai","juin",
11222                 "juil.","ao\u00fbt","sept.",
11223                 "oct.","nov.","d\u00e9c."],
11224     "mon"                : ["janvier","f\u00e9vrier","mars",
11225                             "avril","mai","juin",
11226                 "juillet","ao\u00fbt","septembre",
11227                 "octobre","novembre","d\u00e9cembre"],
11228     "d_fmt"              : "%d/%m/%y",
11229     "t_fmt"              : "%H:%M:%S",
11230     "d_t_fmt"            : "%e %B %Y %H:%M:%S %Z",
11231     "am_pm"              : ["AM","PM"],
11232     "int_curr_symbol"    : "EUR ",
11233     "currency_symbol"    : "\u20ac",
11234     "mon_decimal_point"  : ",",
11235     "mon_thousands_sep"  : "\u00a0",
11236     "mon_grouping"       : "3",
11237     "positive_sign"      : "",
11238     "negative_sign"      : "-",
11239     "int_frac_digits"    : 2,
11240     "frac_digits"        : 2,
11241     "p_cs_precedes"      : 0,
11242     "n_cs_precedes"      : 0,
11243     "p_sep_by_space"     : 1,
11244     "n_sep_by_space"     : 1,
11245     "p_sign_posn"        : 1,
11246     "n_sign_posn"        : 1,
11247     "int_p_cs_precedes"  : 0,
11248     "int_n_cs_precedes"  : 0,
11249     "int_p_sep_by_space" : 1,
11250     "int_n_sep_by_space" : 1,
11251     "int_p_sign_posn"    : 1,
11252     "int_n_sign_posn"    : 1
11253 };
11254
11255 /** https://github.com/csnover/js-iso8601 */(function(n,f){var u=n.parse,c=[1,4,5,6,7,10,11];n.parse=function(t){var i,o,a=0;if(o=/^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(t)){for(var v=0,r;r=c[v];++v)o[r]=+o[r]||0;o[2]=(+o[2]||1)-1,o[3]=+o[3]||1,o[8]!=="Z"&&o[9]!==f&&(a=o[10]*60+o[11],o[9]==="+"&&(a=0-a)),i=n.UTC(o[1],o[2],o[3],o[4],o[5]+a,o[6],o[7])}else i=u?u(t):NaN;return i}})(Date)
11256
11257 /*!
11258  * geo-location-javascript v0.4.3
11259  * http://code.google.com/p/geo-location-javascript/
11260  *
11261  * Copyright (c) 2009 Stan Wiechers
11262  * Licensed under the MIT licenses.
11263  *
11264  * Revision: $Rev: 68 $: 
11265  * Author: $Author: whoisstan $:
11266  * Date: $Date: 2010-02-15 13:42:19 +0100 (Mon, 15 Feb 2010) $:    
11267  */
11268 var geo_position_js=function() {
11269
11270         var pub = {};
11271         var provider=null;
11272
11273         pub.getCurrentPosition = function(successCallback,errorCallback,options)
11274         {
11275                 provider.getCurrentPosition(successCallback, errorCallback,options);
11276         }
11277
11278         pub.init = function()
11279         {                       
11280                 try
11281                 {
11282                         if (typeof(geo_position_js_simulator)!="undefined")
11283                         {
11284                                 provider=geo_position_js_simulator;
11285                         }
11286                         else if (typeof(bondi)!="undefined" && typeof(bondi.geolocation)!="undefined")
11287                         {
11288                                 provider=bondi.geolocation;
11289                         }
11290                         else if (typeof(navigator.geolocation)!="undefined")
11291                         {
11292                                 provider=navigator.geolocation;
11293                                 pub.getCurrentPosition = function(successCallback, errorCallback, options)
11294                                 {
11295                                         function _successCallback(p)
11296                                         {
11297                                                 //for mozilla geode,it returns the coordinates slightly differently
11298                                                 if(typeof(p.latitude)!="undefined")
11299                                                 {
11300                                                         successCallback({timestamp:p.timestamp, coords: {latitude:p.latitude,longitude:p.longitude}});
11301                                                 }
11302                                                 else
11303                                                 {
11304                                                         successCallback(p);
11305                                                 }
11306                                         }
11307                                         provider.getCurrentPosition(_successCallback,errorCallback,options);
11308                                 }
11309                         }
11310                          else if(typeof(window.google)!="undefined" && typeof(google.gears)!="undefined")
11311                         {
11312                                 provider=google.gears.factory.create('beta.geolocation');
11313                         }
11314                         else if ( typeof(Mojo) !="undefined" && typeof(Mojo.Service.Request)!="Mojo.Service.Request")
11315                         {
11316                                 provider=true;
11317                                 pub.getCurrentPosition = function(successCallback, errorCallback, options)
11318                                 {
11319
11320                                 parameters={};
11321                                 if(options)
11322                                 {
11323                                          //http://developer.palm.com/index.php?option=com_content&view=article&id=1673#GPS-getCurrentPosition
11324                                          if (options.enableHighAccuracy && options.enableHighAccuracy==true)
11325                                          {
11326                                                 parameters.accuracy=1;
11327                                          }
11328                                          if (options.maximumAge)
11329                                          {
11330                                                 parameters.maximumAge=options.maximumAge;
11331                                          }
11332                                          if (options.responseTime)
11333                                          {
11334                                                 if(options.responseTime<5)
11335                                                 {
11336                                                         parameters.responseTime=1;
11337                                                 }
11338                                                 else if (options.responseTime<20)
11339                                                 {
11340                                                         parameters.responseTime=2;
11341                                                 }
11342                                                 else
11343                                                 {
11344                                                         parameters.timeout=3;
11345                                                 }
11346                                          }
11347                                 }
11348
11349
11350                                  r=new Mojo.Service.Request('palm://com.palm.location', {
11351                                         method:"getCurrentPosition",
11352                                             parameters:parameters,
11353                                             onSuccess: function(p){successCallback({timestamp:p.timestamp, coords: {latitude:p.latitude, longitude:p.longitude,heading:p.heading}});},
11354                                             onFailure: function(e){
11355                                                                 if (e.errorCode==1)
11356                                                                 {
11357                                                                         errorCallback({code:3,message:"Timeout"});
11358                                                                 }
11359                                                                 else if (e.errorCode==2)
11360                                                                 {
11361                                                                         errorCallback({code:2,message:"Position Unavailable"});
11362                                                                 }
11363                                                                 else
11364                                                                 {
11365                                                                         errorCallback({code:0,message:"Unknown Error: webOS-code"+errorCode});
11366                                                                 }
11367                                                         }
11368                                             });
11369                                 }
11370
11371                         }
11372                         else if (typeof(device)!="undefined" && typeof(device.getServiceObject)!="undefined")
11373                         {
11374                                 provider=device.getServiceObject("Service.Location", "ILocation");
11375
11376                                 //override default method implementation
11377                                 pub.getCurrentPosition = function(successCallback, errorCallback, options)
11378                                 {
11379                                         function callback(transId, eventCode, result) {
11380                                             if (eventCode == 4)
11381                                                 {
11382                                                 errorCallback({message:"Position unavailable", code:2});
11383                                             }
11384                                                 else
11385                                                 {
11386                                                         //no timestamp of location given?
11387                                                         successCallback({timestamp:null, coords: {latitude:result.ReturnValue.Latitude, longitude:result.ReturnValue.Longitude, altitude:result.ReturnValue.Altitude,heading:result.ReturnValue.Heading}});
11388                                                 }
11389                                         }
11390                                         //location criteria
11391                                     var criteria = new Object();
11392                                 criteria.LocationInformationClass = "BasicLocationInformation";
11393                                         //make the call
11394                                         provider.ILocation.GetLocation(criteria,callback);
11395                                 }
11396                         }
11397                 }
11398                 catch (e){ 
11399                                         alert("error="+e);
11400                                         if(typeof(console)!="undefined")
11401                                         {
11402                                                 console.log(e);
11403                                         }
11404                                         return false;
11405                                 }
11406                 return  provider!=null;
11407         }
11408
11409
11410         return pub;
11411 }();
11412 // Couldn't get unminified version to work , go here for docs => https://github.com/iamnoah/writeCapture
11413 (function(E,a){var j=a.document;function A(Q){var Z=j.createElement("div");j.body.insertBefore(Z,null);E.replaceWith(Z,'<script type="text/javascript">'+Q+"<\/script>")}E=E||(function(Q){return{ajax:Q.ajax,$:function(Z){return Q(Z)[0]},replaceWith:function(Z,ad){var ac=Q(Z)[0];var ab=ac.nextSibling,aa=ac.parentNode;Q(ac).remove();if(ab){Q(ab).before(ad)}else{Q(aa).append(ad)}},onLoad:function(Z){Q(Z)},copyAttrs:function(af,ab){var ad=Q(ab),aa=af.attributes;for(var ac=0,Z=aa.length;ac<Z;ac++){if(aa[ac]&&aa[ac].value){try{ad.attr(aa[ac].name,aa[ac].value)}catch(ae){}}}}}})(a.jQuery);E.copyAttrs=E.copyAttrs||function(){};E.onLoad=E.onLoad||function(){throw"error: autoAsync cannot be used without jQuery or defining writeCaptureSupport.onLoad"};function P(ab,aa){for(var Z=0,Q=ab.length;Z<Q;Z++){if(aa(ab[Z])===false){return}}}function v(Q){return Object.prototype.toString.call(Q)==="[object Function]"}function p(Q){return Object.prototype.toString.call(Q)==="[object String]"}function u(aa,Z,Q){return Array.prototype.slice.call(aa,Z||0,Q||aa&&aa.length)}function D(ab,aa){var Q=false;P(ab,Z);function Z(ac){return !(Q=aa(ac))}return Q}function L(Q){this._queue=[];this._children=[];this._parent=Q;if(Q){Q._addChild(this)}}L.prototype={_addChild:function(Q){this._children.push(Q)},push:function(Q){this._queue.push(Q);this._bubble("_doRun")},pause:function(){this._bubble("_doPause")},resume:function(){this._bubble("_doResume")},_bubble:function(Z){var Q=this;while(!Q[Z]){Q=Q._parent}return Q[Z]()},_next:function(){if(D(this._children,Q)){return true}function Q(aa){return aa._next()}var Z=this._queue.shift();if(Z){Z()}return !!Z}};function i(Q){if(Q){return new L(Q)}L.call(this);this.paused=0}i.prototype=(function(){function Q(){}Q.prototype=L.prototype;return new Q()})();i.prototype._doRun=function(){if(!this.running){this.running=true;try{while(this.paused<1&&this._next()){}}finally{this.running=false}}};i.prototype._doPause=function(){this.paused++};i.prototype._doResume=function(){this.paused--;this._doRun()};function M(){}M.prototype={_html:"",open:function(){this._opened=true;if(this._delegate){this._delegate.open()}},write:function(Q){if(this._closed){return}this._written=true;if(this._delegate){this._delegate.write(Q)}else{this._html+=Q}},writeln:function(Q){this.write(Q+"\n")},close:function(){this._closed=true;if(this._delegate){this._delegate.close()}},copyTo:function(Q){this._delegate=Q;Q.foobar=true;if(this._opened){Q.open()}if(this._written){Q.write(this._html)}if(this._closed){Q.close()}}};var e=(function(){var Q={f:j.getElementById};try{Q.f.call(j,"abc");return true}catch(Z){return false}})();function I(Q){P(Q,function(Z){var aa=j.getElementById(Z.id);if(!aa){l("<proxyGetElementById - finish>","no element in writen markup with id "+Z.id);return}P(Z.el.childNodes,function(ab){aa.appendChild(ab)});if(aa.contentWindow){a.setTimeout(function(){Z.el.contentWindow.document.copyTo(aa.contentWindow.document)},1)}E.copyAttrs(Z.el,aa)})}function s(Z,Q){if(Q&&Q[Z]===false){return false}return Q&&Q[Z]||o[Z]}function x(Z,ai){var ae=[],ad=s("proxyGetElementById",ai),ag=s("writeOnGetElementById",ai),Q={write:j.write,writeln:j.writeln,finish:function(){},out:""};Z.state=Q;j.write=ah;j.writeln=aa;if(ad||ag){Q.getEl=j.getElementById;j.getElementById=ab;if(ag){findEl=af}else{findEl=ac;Q.finish=function(){I(ae)}}}function ah(aj){Q.out+=aj}function aa(aj){Q.out+=aj+"\n"}function ac(ak){var aj=j.createElement("div");ae.push({id:ak,el:aj});aj.contentWindow={document:new M()};return aj}function af(al){var aj=E.$(Z.target);var ak=j.createElement("div");aj.parentNode.insertBefore(ak,aj);E.replaceWith(ak,Q.out);Q.out="";return e?Q.getEl.call(j,al):Q.getEl(al)}function ab(ak){var aj=e?Q.getEl.call(j,ak):Q.getEl(ak);return aj||findEl(ak)}return Q}function V(Q){j.write=Q.write;j.writeln=Q.writeln;if(Q.getEl){j.getElementById=Q.getEl}return Q.out}function N(Q){return Q&&Q.replace(/^\s*<!(\[CDATA\[|--)/,"").replace(/(\]\]|--)>\s*$/,"")}function b(){}function d(Z,Q){console.error("Error",Q,"executing code:",Z)}var l=v(a.console&&console.error)?d:b;function S(aa,Z,Q){var ab=x(Z,Q);try{A(N(aa))}catch(ac){l(aa,ac)}finally{V(ab)}return ab}function O(Z){var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(Z);return Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)}function T(Q){return new RegExp(Q+"=(?:([\"'])([\\s\\S]*?)\\1|([^\\s>]+))","i")}function k(Q){var Z=T(Q);return function(aa){var ab=Z.exec(aa)||[];return ab[2]||ab[3]}}var r=/(<script[\s\S]*?>)([\s\S]*?)<\/script>/ig,n=T("src"),X=k("src"),q=k("type"),Y=k("language"),C="__document_write_ajax_callbacks__",B="__document_write_ajax_div-",g="window['"+C+"']['%d']();",m=a[C]={},w='<script type="text/javascript">'+g+"<\/script>",H=0;function c(){return(++H).toString()}function G(Z,aa){var Q;if(v(Z)){Q=Z;Z=null}Z=Z||{};Q=Q||Z&&Z.done;Z.done=aa?function(){aa(Q)}:Q;return Z}var z=new i();var y=[];var f=window._debugWriteCapture?function(){}:function(Q,aa,Z){y.push({type:Q,src:aa,data:Z})};var K=window._debugWriteCapture?function(){}:function(){y.push(arguments)};function W(Q){var Z=c();m[Z]=function(){Q();delete m[Z]};return Z}function J(Q){return w.replace(/%d/,W(Q))}function R(ac,ag,aa,ae){var ad=aa&&new i(aa)||z;ag=G(ag);var ab=s("done",ag);var Q="";var Z=s("fixUrls",ag);if(!v(Z)){Z=function(ah){return ah}}if(v(ab)){Q=J(function(){ad.push(ab)})}return ac.replace(r,af)+Q;function af(aj,av,ai){var an=X(av),am=q(av)||"",aB=Y(av)||"",aA=(!am&&!aB)||am.toLowerCase().indexOf("javascript")!==-1||aB.toLowerCase().indexOf("javascript")!==-1;f("replace",an,aj);if(!aA){return aj}var aw=W(ap),ao=B+aw,au,al={target:"#"+ao,parent:ae};function ap(){ad.push(au)}if(an){an=Z(an);av=av.replace(n,"");if(O(an)){au=az}else{if(s("asyncAll",ag)){au=ay()}else{au=at}}}else{au=ax}function ax(){ah(ai)}function at(){E.ajax({url:an,type:"GET",dataType:"text",async:false,success:function(aC){ah(aC)}})}function ak(aE,aC,aD){l("<XHR for "+an+">",aD);ad.resume()}function aq(){return J(function(){ad.resume()})}function ay(){var aE,aD;function aC(aG,aF){if(!aE){aD=aG;return}try{ah(aG,aq())}catch(aH){l(aG,aH)}}E.ajax({url:an,type:"GET",dataType:"text",async:true,success:aC,error:ak});return function(){aE=true;if(aD){ah(aD)}else{ad.pause()}}}function az(aC){var aE=x(al,ag);ad.pause();f("pause",an);E.ajax({url:an,type:"GET",dataType:"script",success:aD,error:ak});function aD(aH,aG,aF){f("out",an,aE.out);ar(V(aE),J(aE.finish)+aq());f("resume",an)}}function ah(aD,aC){var aE=S(aD,al,ag);aC=J(aE.finish)+(aC||"");ar(aE.out,aC)}function ar(aD,aC){E.replaceWith(al.target,R(aD,null,ad,al)+(aC||""))}return'<div style="display: none" id="'+ao+'"></div>'+av+g.replace(/%d/,aw)+"<\/script>"}}function F(Z,aa){var Q=z;P(Z,function(ab){Q.push(ac);function ac(){ab.action(R(ab.html,ab.options,Q),ab)}});if(aa){Q.push(aa)}}function U(Q){var Z=Q;while(Z&&Z.nodeType===1){Q=Z;Z=Z.lastChild;while(Z&&Z.nodeType!==1){Z=Z.previousSibling}}return Q}function h(Q){var aa=j.write,ad=j.writeln,Z,ab=[];j.writeln=function(ae){j.write(ae+"\n")};var ac;j.write=function(af){var ae=U(j.body);if(ae!==Z){Z=ae;ab.push(ac={el:ae,out:[]})}ac.out.push(af)};E.onLoad(function(){var ah,ak,af,aj,ai;Q=G(Q);ai=Q.done;Q.done=function(){j.write=aa;j.writeln=ad;if(ai){ai()}};for(var ag=0,ae=ab.length;ag<ae;ag++){ah=ab[ag].el;ak=j.createElement("div");ah.parentNode.insertBefore(ak,ah.nextSibling);af=ab[ag].out.join("");aj=ae-ag===1?R(af,Q):R(af);E.replaceWith(ak,aj)}})}var t="writeCapture";var o=a[t]={_original:a[t],fixUrls:function(Q){return Q.replace(/&amp;/g,"&")},noConflict:function(){a[t]=this._original;return this},debug:y,proxyGetElementById:false,_forTest:{Q:i,GLOBAL_Q:z,$:E,matchAttr:k,slice:u,capture:x,uncapture:V,captureWrite:S},replaceWith:function(Q,aa,Z){E.replaceWith(Q,R(aa,Z))},html:function(Q,ab,Z){var aa=E.$(Q);aa.innerHTML="<span/>";E.replaceWith(aa.firstChild,R(ab,Z))},load:function(Q,aa,Z){E.ajax({url:aa,dataType:"text",type:"GET",success:function(ab){o.html(Q,ab,Z)}})},autoAsync:h,sanitize:R,sanitizeSerial:F}})(this.writeCaptureSupport,this);(function(g,d,n){var c={html:h};g.each(["append","prepend","after","before","wrap","wrapAll","replaceWith","wrapInner"],function(){c[this]=i(this)});function a(q){return Object.prototype.toString.call(q)=="[object String]"}function p(u,t,s,r){if(arguments.length==0){return o.call(this)}var q=c[u];if(u=="load"){return l.call(this,t,s,r)}if(!q){j(u)}return b.call(this,t,s,q)}g.fn.writeCapture=p;var k="__writeCaptureJsProxied-fghebd__";function o(){if(this[k]){return this}var r=this;function q(){var t=this,s=false;this[k]=true;g.each(c,function(v){var u=r[v];if(!u){return}t[v]=function(y,x,w){if(!s&&a(y)){try{s=true;return p.call(t,v,y,x,w)}finally{s=false}}return u.apply(t,arguments)}});this.pushStack=function(){return o.call(r.pushStack.apply(t,arguments))};this.endCapture=function(){return r}}q.prototype=r;return new q()}function b(t,s,u){var q,r=this;if(s&&s.done){q=s.done;delete s.done}else{if(g.isFunction(s)){q=s;s=null}}d.sanitizeSerial(g.map(this,function(v){return{html:t,options:s,action:function(w){u.call(v,w)}}}),q&&function(){q.call(r)}||q);return this}function h(q){g(this).html(q)}function i(q){return function(r){g(this)[q](r)}}function l(t,s,v){var r=this,q,u=t.indexOf(" ");if(u>=0){q=t.slice(u,t.length);t=t.slice(0,u)}if(g.isFunction(v)){s=s||{};s.done=v}return g.ajax({url:t,type:s&&s.type||"GET",dataType:"html",data:s&&s.params,complete:f(r,s,q)})}function f(r,s,q){return function(u,t){if(t=="success"||t=="notmodified"){var v=m(u.responseText,q);b.call(r,v,s,h)}}}var e=/jquery-writeCapture-script-placeholder-(\d+)-wc/g;function m(s,r){if(!r||!s){return s}var t=0,q={};return g("<div/>").append(s.replace(/<script(.|\s)*?\/script>/g,function(u){q[t]=u;return"jquery-writeCapture-script-placeholder-"+(t++)+"-wc"})).find(r).html().replace(e,function(u,v){return q[v]})}function j(q){throw"invalid method parameter "+q}g.writeCapture=d})(jQuery,writeCapture.noConflict());
11414
11415 /*!
11416  * Amplify Store - Persistent Client-Side Storage 1.0.0
11417  * 
11418  * Copyright 2011 appendTo LLC. (http://appendto.com/team)
11419  * Dual licensed under the MIT or GPL licenses.
11420  * http://appendto.com/open-source-licenses
11421  * 
11422  * http://amplifyjs.com
11423  */
11424 (function( amplify, undefined ) {
11425
11426 var store = amplify.store = function( key, value, options, type ) {
11427         var type = store.type;
11428         if ( options && options.type && options.type in store.types ) {
11429                 type = options.type;
11430         }
11431         return store.types[ type ]( key, value, options || {} );
11432 };
11433
11434 store.types = {};
11435 store.type = null;
11436 store.addType = function( type, storage ) {
11437         if ( !store.type ) {
11438                 store.type = type;
11439         }
11440
11441         store.types[ type ] = storage;
11442         store[ type ] = function( key, value, options ) {
11443                 options = options || {};
11444                 options.type = type;
11445                 return store( key, value, options );
11446         };
11447 }
11448 store.error = function() {
11449         return "amplify.store quota exceeded"; 
11450 };
11451
11452 var rprefix = /^__amplify__/;
11453 function createFromStorageInterface( storageType, storage ) {
11454         store.addType( storageType, function( key, value, options ) {
11455                 var storedValue, parsed, i, remove,
11456                         ret = value,
11457                         now = (new Date()).getTime();
11458
11459                 if ( !key ) {
11460                         ret = {};
11461                         remove = [];
11462                         i = 0;
11463                         try {
11464                                 // accessing the length property works around a localStorage bug
11465                                 // in Firefox 4.0 where the keys don't update cross-page
11466                                 // we assign to key just to avoid Closure Compiler from removing
11467                                 // the access as "useless code"
11468                                 // https://bugzilla.mozilla.org/show_bug.cgi?id=662511
11469                                 key = storage.length;
11470
11471                                 while ( key = storage.key( i++ ) ) {
11472                                         if ( rprefix.test( key ) ) {
11473                                                 parsed = JSON.parse( storage.getItem( key ) );
11474                                                 if ( parsed.expires && parsed.expires <= now ) {
11475                                                         remove.push( key );
11476                                                 } else {
11477                                                         ret[ key.replace( rprefix, "" ) ] = parsed.data;
11478                                                 }
11479                                         }
11480                                 }
11481                                 while ( key = remove.pop() ) {
11482                                         storage.removeItem( key );
11483                                 }
11484                         } catch ( error ) {}
11485                         return ret;
11486                 }
11487
11488                 // protect against name collisions with direct storage
11489                 key = "__amplify__" + key;
11490
11491                 if ( value === undefined ) {
11492                         storedValue = storage.getItem( key );
11493                         parsed = storedValue ? JSON.parse( storedValue ) : { expires: -1 };
11494                         if ( parsed.expires && parsed.expires <= now ) {
11495                                 storage.removeItem( key );
11496                         } else {
11497                                 return parsed.data;
11498                         }
11499                 } else {
11500                         if ( value === null ) {
11501                                 storage.removeItem( key );
11502                         } else {
11503                                 parsed = JSON.stringify({
11504                                         data: value,
11505                                         expires: options.expires ? now + options.expires : null
11506                                 });
11507                                 try {
11508                                         storage.setItem( key, parsed );
11509                                 // quota exceeded
11510                                 } catch( error ) {
11511                                         // expire old data and try again
11512                                         store[ storageType ]();
11513                                         try {
11514                                                 storage.setItem( key, parsed );
11515                                         } catch( error ) {
11516                                                 throw store.error();
11517                                         }
11518                                 }
11519                         }
11520                 }
11521
11522                 return ret;
11523         });
11524 }
11525
11526 // localStorage + sessionStorage
11527 // IE 8+, Firefox 3.5+, Safari 4+, Chrome 4+, Opera 10.5+, iPhone 2+, Android 2+
11528 for ( var webStorageType in { localStorage: 1, sessionStorage: 1 } ) {
11529         // try/catch for file protocol in Firefox
11530         try {
11531                 if ( window[ webStorageType ].getItem ) {
11532                         createFromStorageInterface( webStorageType, window[ webStorageType ] );
11533                 }
11534         } catch( e ) {}
11535 }
11536
11537 // globalStorage
11538 // non-standard: Firefox 2+
11539 // https://developer.mozilla.org/en/dom/storage#globalStorage
11540 if ( window.globalStorage ) {
11541         // try/catch for file protocol in Firefox
11542         try {
11543                 createFromStorageInterface( "globalStorage",
11544                         window.globalStorage[ window.location.hostname ] );
11545                 // Firefox 2.0 and 3.0 have sessionStorage and globalStorage
11546                 // make sure we default to globalStorage
11547                 // but don't default to globalStorage in 3.5+ which also has localStorage
11548                 if ( store.type === "sessionStorage" ) {
11549                         store.type = "globalStorage";
11550                 }
11551         } catch( e ) {}
11552 }
11553
11554 // userData
11555 // non-standard: IE 5+
11556 // http://msdn.microsoft.com/en-us/library/ms531424(v=vs.85).aspx
11557 (function() {
11558         // IE 9 has quirks in userData that are a huge pain
11559         // rather than finding a way to detect these quirks
11560         // we just don't register userData if we have localStorage
11561         if ( store.types.localStorage ) {
11562                 return;
11563         }
11564
11565         // append to html instead of body so we can do this from the head
11566         var div = document.createElement( "div" ),
11567                 attrKey = "amplify";
11568         div.style.display = "none";
11569         document.getElementsByTagName( "head" )[ 0 ].appendChild( div );
11570         if ( div.addBehavior ) {
11571                 div.addBehavior( "#default#userdata" );
11572
11573                 store.addType( "userData", function( key, value, options ) {
11574                         div.load( attrKey );
11575                         var attr, parsed, prevValue, i, remove,
11576                                 ret = value,
11577                                 now = (new Date()).getTime();
11578
11579                         if ( !key ) {
11580                                 ret = {};
11581                                 remove = [];
11582                                 i = 0;
11583                                 while ( attr = div.XMLDocument.documentElement.attributes[ i++ ] ) {
11584                                         parsed = JSON.parse( attr.value );
11585                                         if ( parsed.expires && parsed.expires <= now ) {
11586                                                 remove.push( attr.name );
11587                                         } else {
11588                                                 ret[ attr.name ] = parsed.data;
11589                                         }
11590                                 }
11591                                 while ( key = remove.pop() ) {
11592                                         div.removeAttribute( key );
11593                                 }
11594                                 div.save( attrKey );
11595                                 return ret;
11596                         }
11597
11598                         // convert invalid characters to dashes
11599                         // http://www.w3.org/TR/REC-xml/#NT-Name
11600                         // simplified to assume the starting character is valid
11601                         // also removed colon as it is invalid in HTML attribute names
11602                         //key = key.replace( /[^-._0-9A-Za-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u37f-\u1fff\u200c-\u200d\u203f\u2040\u2070-\u218f]/g, "-" );
11603
11604                         if ( value === undefined ) {
11605                                 attr = div.getAttribute( key );
11606                                 parsed = attr ? JSON.parse( attr ) : { expires: -1 };
11607                                 if ( parsed.expires && parsed.expires <= now ) {
11608                                         div.removeAttribute( key );
11609                                 } else {
11610                                         return parsed.data;
11611                                 }
11612                         } else {
11613                                 if ( value === null ) {
11614                                         div.removeAttribute( key );
11615                                 } else {
11616                                         // we need to get the previous value in case we need to rollback
11617                                         prevValue = div.getAttribute( key );
11618                                         parsed = JSON.stringify({
11619                                                 data: value,
11620                                                 expires: (options.expires ? (now + options.expires) : null)
11621                                         });
11622                                         div.setAttribute( key, parsed );
11623                                 }
11624                         }
11625
11626                         try {
11627                                 div.save( attrKey );
11628                         // quota exceeded
11629                         } catch ( error ) {
11630                                 // roll the value back to the previous value
11631                                 if ( prevValue === null ) {
11632                                         div.removeAttribute( key );
11633                                 } else {
11634                                         div.setAttribute( key, prevValue );
11635                                 }
11636
11637                                 // expire old data and try again
11638                                 store.userData();
11639                                 try {
11640                                         div.setAttribute( key, parsed );
11641                                         div.save( attrKey );
11642                                 } catch ( error ) {
11643                                         // roll the value back to the previous value
11644                                         if ( prevValue === null ) {
11645                                                 div.removeAttribute( key );
11646                                         } else {
11647                                                 div.setAttribute( key, prevValue );
11648                                         }
11649                                         throw store.error();
11650                                 }
11651                         }
11652                         return ret;
11653                 });
11654         }
11655 }() );
11656
11657 // in-memory storage
11658 // fallback for all browsers to enable the API even if we can't persist data
11659 (function() {
11660         var memory = {};
11661
11662         function copy( obj ) {
11663                 return obj === undefined ? undefined : JSON.parse( JSON.stringify( obj ) );
11664         }
11665
11666         store.addType( "memory", function( key, value, options ) {
11667                 if ( !key ) {
11668                         return copy( memory );
11669                 }
11670
11671                 if ( value === undefined ) {
11672                         return copy( memory[ key ] );
11673                 }
11674
11675                 if ( value === null ) {
11676                         delete memory[ key ];
11677                         return null;
11678                 }
11679
11680                 memory[ key ] = value;
11681                 if ( options.expires ) {
11682                         setTimeout(function() {
11683                                 delete memory[ key ];
11684                         }, options.expires );
11685                 }
11686
11687                 return value;
11688         });
11689 }() );
11690
11691 }( this.amplify = this.amplify || {} ) );
11692
11693 /*!
11694  * Modernizr v2.0.6
11695  * http://www.modernizr.com
11696  *
11697  * Copyright (c) 2009-2011 Faruk Ates, Paul Irish, Alex Sexton
11698  * Dual-licensed under the BSD or MIT licenses: www.modernizr.com/license/
11699  */
11700
11701 /*
11702  * Modernizr tests which native CSS3 and HTML5 features are available in
11703  * the current UA and makes the results available to you in two ways:
11704  * as properties on a global Modernizr object, and as classes on the
11705  * <html> element. This information allows you to progressively enhance
11706  * your pages with a granular level of control over the experience.
11707  *
11708  * Modernizr has an optional (not included) conditional resource loader
11709  * called Modernizr.load(), based on Yepnope.js (yepnopejs.com).
11710  * To get a build that includes Modernizr.load(), as well as choosing
11711  * which tests to include, go to www.modernizr.com/download/
11712  *
11713  * Authors        Faruk Ates, Paul Irish, Alex Sexton, 
11714  * Contributors   Ryan Seddon, Ben Alman
11715  */
11716
11717 window.Modernizr = (function( window, document, undefined ) {
11718
11719     var version = '2.0.6',
11720
11721     Modernizr = {},
11722     
11723     // option for enabling the HTML classes to be added
11724     enableClasses = true,
11725
11726     docElement = document.documentElement,
11727     docHead = document.head || document.getElementsByTagName('head')[0],
11728
11729     /**
11730      * Create our "modernizr" element that we do most feature tests on.
11731      */
11732     mod = 'modernizr',
11733     modElem = document.createElement(mod),
11734     mStyle = modElem.style,
11735
11736     /**
11737      * Create the input element for various Web Forms feature tests.
11738      */
11739     inputElem = document.createElement('input'),
11740
11741     smile = ':)',
11742
11743     toString = Object.prototype.toString,
11744
11745     // List of property values to set for css tests. See ticket #21
11746     prefixes = ' -webkit- -moz- -o- -ms- -khtml- '.split(' '),
11747
11748     // Following spec is to expose vendor-specific style properties as:
11749     //   elem.style.WebkitBorderRadius
11750     // and the following would be incorrect:
11751     //   elem.style.webkitBorderRadius
11752
11753     // Webkit ghosts their properties in lowercase but Opera & Moz do not.
11754     // Microsoft foregoes prefixes entirely <= IE8, but appears to
11755     //   use a lowercase `ms` instead of the correct `Ms` in IE9
11756
11757     // More here: http://github.com/Modernizr/Modernizr/issues/issue/21
11758     domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
11759
11760     ns = {'svg': 'http://www.w3.org/2000/svg'},
11761
11762     tests = {},
11763     inputs = {},
11764     attrs = {},
11765
11766     classes = [],
11767
11768     featureName, // used in testing loop
11769
11770
11771     // Inject element with style element and some CSS rules
11772     injectElementWithStyles = function( rule, callback, nodes, testnames ) {
11773
11774       var style, ret, node,
11775           div = document.createElement('div');
11776
11777       if ( parseInt(nodes, 10) ) {
11778           // In order not to give false positives we create a node for each test
11779           // This also allows the method to scale for unspecified uses
11780           while ( nodes-- ) {
11781               node = document.createElement('div');
11782               node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
11783               div.appendChild(node);
11784           }
11785       }
11786
11787       // <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed
11788       // when injected with innerHTML. To get around this you need to prepend the 'NoScope' element
11789       // with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements.
11790       // http://msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx
11791       style = ['&shy;', '<style>', rule, '</style>'].join('');
11792       div.id = mod;
11793       div.innerHTML += style;
11794       docElement.appendChild(div);
11795
11796       ret = callback(div, rule);
11797       div.parentNode.removeChild(div);
11798
11799       return !!ret;
11800
11801     },
11802
11803
11804     // adapted from matchMedia polyfill
11805     // by Scott Jehl and Paul Irish
11806     // gist.github.com/786768
11807     testMediaQuery = function( mq ) {
11808
11809       if ( window.matchMedia ) {
11810         return matchMedia(mq).matches;
11811       }
11812
11813       var bool;
11814
11815       injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
11816         bool = (window.getComputedStyle ?
11817                   getComputedStyle(node, null) :
11818                   node.currentStyle)['position'] == 'absolute';
11819       });
11820
11821       return bool;
11822
11823      },
11824
11825
11826     /**
11827       * isEventSupported determines if a given element supports the given event
11828       * function from http://yura.thinkweb2.com/isEventSupported/
11829       */
11830     isEventSupported = (function() {
11831
11832       var TAGNAMES = {
11833         'select': 'input', 'change': 'input',
11834         'submit': 'form', 'reset': 'form',
11835         'error': 'img', 'load': 'img', 'abort': 'img'
11836       };
11837
11838       function isEventSupported( eventName, element ) {
11839
11840         element = element || document.createElement(TAGNAMES[eventName] || 'div');
11841         eventName = 'on' + eventName;
11842
11843         // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
11844         var isSupported = eventName in element;
11845
11846         if ( !isSupported ) {
11847           // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
11848           if ( !element.setAttribute ) {
11849             element = document.createElement('div');
11850           }
11851           if ( element.setAttribute && element.removeAttribute ) {
11852             element.setAttribute(eventName, '');
11853             isSupported = is(element[eventName], 'function');
11854
11855             // If property was created, "remove it" (by setting value to `undefined`)
11856             if ( !is(element[eventName], undefined) ) {
11857               element[eventName] = undefined;
11858             }
11859             element.removeAttribute(eventName);
11860           }
11861         }
11862
11863         element = null;
11864         return isSupported;
11865       }
11866       return isEventSupported;
11867     })();
11868
11869     // hasOwnProperty shim by kangax needed for Safari 2.0 support
11870     var _hasOwnProperty = ({}).hasOwnProperty, hasOwnProperty;
11871     if ( !is(_hasOwnProperty, undefined) && !is(_hasOwnProperty.call, undefined) ) {
11872       hasOwnProperty = function (object, property) {
11873         return _hasOwnProperty.call(object, property);
11874       };
11875     }
11876     else {
11877       hasOwnProperty = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
11878         return ((property in object) && is(object.constructor.prototype[property], undefined));
11879       };
11880     }
11881
11882     /**
11883      * setCss applies given styles to the Modernizr DOM node.
11884      */
11885     function setCss( str ) {
11886         mStyle.cssText = str;
11887     }
11888
11889     /**
11890      * setCssAll extrapolates all vendor-specific css strings.
11891      */
11892     function setCssAll( str1, str2 ) {
11893         return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
11894     }
11895
11896     /**
11897      * is returns a boolean for if typeof obj is exactly type.
11898      */
11899     function is( obj, type ) {
11900         return typeof obj === type;
11901     }
11902
11903     /**
11904      * contains returns a boolean for if substr is found within str.
11905      */
11906     function contains( str, substr ) {
11907         return !!~('' + str).indexOf(substr);
11908     }
11909
11910     /**
11911      * testProps is a generic CSS / DOM property test; if a browser supports
11912      *   a certain property, it won't return undefined for it.
11913      *   A supported CSS property returns empty string when its not yet set.
11914      */
11915     function testProps( props, prefixed ) {
11916         for ( var i in props ) {
11917             if ( mStyle[ props[i] ] !== undefined ) {
11918                 return prefixed == 'pfx' ? props[i] : true;
11919             }
11920         }
11921         return false;
11922     }
11923
11924     /**
11925      * testPropsAll tests a list of DOM properties we want to check against.
11926      *   We specify literally ALL possible (known and/or likely) properties on
11927      *   the element including the non-vendor prefixed one, for forward-
11928      *   compatibility.
11929      */
11930     function testPropsAll( prop, prefixed ) {
11931
11932         var ucProp  = prop.charAt(0).toUpperCase() + prop.substr(1),
11933             props   = (prop + ' ' + domPrefixes.join(ucProp + ' ') + ucProp).split(' ');
11934
11935         return testProps(props, prefixed);
11936     }
11937
11938     /**
11939      * testBundle tests a list of CSS features that require element and style injection.
11940      *   By bundling them together we can reduce the need to touch the DOM multiple times.
11941      */
11942     /*>>testBundle*/
11943     var testBundle = (function( styles, tests ) {
11944         var style = styles.join(''),
11945             len = tests.length;
11946
11947         injectElementWithStyles(style, function( node, rule ) {
11948             var style = document.styleSheets[document.styleSheets.length - 1],
11949                 // IE8 will bork if you create a custom build that excludes both fontface and generatedcontent tests.
11950                 // So we check for cssRules and that there is a rule available
11951                 // More here: https://github.com/Modernizr/Modernizr/issues/288 & https://github.com/Modernizr/Modernizr/issues/293
11952                 cssText = style.cssRules && style.cssRules[0] ? style.cssRules[0].cssText : style.cssText || "",
11953                 children = node.childNodes, hash = {};
11954
11955             while ( len-- ) {
11956                 hash[children[len].id] = children[len];
11957             }
11958
11959             /*>>touch*/           Modernizr['touch'] = ('ontouchstart' in window) || hash['touch'].offsetTop === 9; /*>>touch*/
11960             /*>>csstransforms3d*/ Modernizr['csstransforms3d'] = hash['csstransforms3d'].offsetLeft === 9;          /*>>csstransforms3d*/
11961             /*>>generatedcontent*/Modernizr['generatedcontent'] = hash['generatedcontent'].offsetHeight >= 1;       /*>>generatedcontent*/
11962             /*>>fontface*/        Modernizr['fontface'] = /src/i.test(cssText) &&
11963                                                                   cssText.indexOf(rule.split(' ')[0]) === 0;        /*>>fontface*/
11964         }, len, tests);
11965
11966     })([
11967         // Pass in styles to be injected into document
11968         /*>>fontface*/        '@font-face {font-family:"font";src:url("https://")}'         /*>>fontface*/
11969         
11970         /*>>touch*/           ,['@media (',prefixes.join('touch-enabled),('),mod,')',
11971                                 '{#touch{top:9px;position:absolute}}'].join('')           /*>>touch*/
11972                                 
11973         /*>>csstransforms3d*/ ,['@media (',prefixes.join('transform-3d),('),mod,')',
11974                                 '{#csstransforms3d{left:9px;position:absolute}}'].join('')/*>>csstransforms3d*/
11975                                 
11976         /*>>generatedcontent*/,['#generatedcontent:after{content:"',smile,'";visibility:hidden}'].join('')  /*>>generatedcontent*/
11977     ],
11978       [
11979         /*>>fontface*/        'fontface'          /*>>fontface*/
11980         /*>>touch*/           ,'touch'            /*>>touch*/
11981         /*>>csstransforms3d*/ ,'csstransforms3d'  /*>>csstransforms3d*/
11982         /*>>generatedcontent*/,'generatedcontent' /*>>generatedcontent*/
11983         
11984     ]);/*>>testBundle*/
11985
11986
11987     /**
11988      * Tests
11989      * -----
11990      */
11991
11992     tests['flexbox'] = function() {
11993         /**
11994          * setPrefixedValueCSS sets the property of a specified element
11995          * adding vendor prefixes to the VALUE of the property.
11996          * @param {Element} element
11997          * @param {string} property The property name. This will not be prefixed.
11998          * @param {string} value The value of the property. This WILL be prefixed.
11999          * @param {string=} extra Additional CSS to append unmodified to the end of
12000          * the CSS string.
12001          */
12002         function setPrefixedValueCSS( element, property, value, extra ) {
12003             property += ':';
12004             element.style.cssText = (property + prefixes.join(value + ';' + property)).slice(0, -property.length) + (extra || '');
12005         }
12006
12007         /**
12008          * setPrefixedPropertyCSS sets the property of a specified element
12009          * adding vendor prefixes to the NAME of the property.
12010          * @param {Element} element
12011          * @param {string} property The property name. This WILL be prefixed.
12012          * @param {string} value The value of the property. This will not be prefixed.
12013          * @param {string=} extra Additional CSS to append unmodified to the end of
12014          * the CSS string.
12015          */
12016         function setPrefixedPropertyCSS( element, property, value, extra ) {
12017             element.style.cssText = prefixes.join(property + ':' + value + ';') + (extra || '');
12018         }
12019
12020         var c = document.createElement('div'),
12021             elem = document.createElement('div');
12022
12023         setPrefixedValueCSS(c, 'display', 'box', 'width:42px;padding:0;');
12024         setPrefixedPropertyCSS(elem, 'box-flex', '1', 'width:10px;');
12025
12026         c.appendChild(elem);
12027         docElement.appendChild(c);
12028
12029         var ret = elem.offsetWidth === 42;
12030
12031         c.removeChild(elem);
12032         docElement.removeChild(c);
12033
12034         return ret;
12035     };
12036
12037     // On the S60 and BB Storm, getContext exists, but always returns undefined
12038     // http://github.com/Modernizr/Modernizr/issues/issue/97/
12039
12040     tests['canvas'] = function() {
12041         var elem = document.createElement('canvas');
12042         return !!(elem.getContext && elem.getContext('2d'));
12043     };
12044
12045     tests['canvastext'] = function() {
12046         return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
12047     };
12048
12049     // This WebGL test may false positive. 
12050     // But really it's quite impossible to know whether webgl will succeed until after you create the context. 
12051     // You might have hardware that can support a 100x100 webgl canvas, but will not support a 1000x1000 webgl 
12052     // canvas. So this feature inference is weak, but intentionally so.
12053     
12054     // It is known to false positive in FF4 with certain hardware and the iPad 2.
12055     
12056     tests['webgl'] = function() {
12057         return !!window.WebGLRenderingContext;
12058     };
12059
12060     /*
12061      * The Modernizr.touch test only indicates if the browser supports
12062      *    touch events, which does not necessarily reflect a touchscreen
12063      *    device, as evidenced by tablets running Windows 7 or, alas,
12064      *    the Palm Pre / WebOS (touch) phones.
12065      *
12066      * Additionally, Chrome (desktop) used to lie about its support on this,
12067      *    but that has since been rectified: http://crbug.com/36415
12068      *
12069      * We also test for Firefox 4 Multitouch Support.
12070      *
12071      * For more info, see: http://modernizr.github.com/Modernizr/touch.html
12072      */
12073
12074     tests['touch'] = function() {
12075         return Modernizr['touch'];
12076     };
12077
12078     /**
12079      * geolocation tests for the new Geolocation API specification.
12080      *   This test is a standards compliant-only test; for more complete
12081      *   testing, including a Google Gears fallback, please see:
12082      *   http://code.google.com/p/geo-location-javascript/
12083      * or view a fallback solution using google's geo API:
12084      *   http://gist.github.com/366184
12085      */
12086     tests['geolocation'] = function() {
12087         return !!navigator.geolocation;
12088     };
12089
12090     // Per 1.6:
12091     // This used to be Modernizr.crosswindowmessaging but the longer
12092     // name has been deprecated in favor of a shorter and property-matching one.
12093     // The old API is still available in 1.6, but as of 2.0 will throw a warning,
12094     // and in the first release thereafter disappear entirely.
12095     tests['postmessage'] = function() {
12096       return !!window.postMessage;
12097     };
12098
12099     // Web SQL database detection is tricky:
12100
12101     // In chrome incognito mode, openDatabase is truthy, but using it will
12102     //   throw an exception: http://crbug.com/42380
12103     // We can create a dummy database, but there is no way to delete it afterwards.
12104
12105     // Meanwhile, Safari users can get prompted on any database creation.
12106     //   If they do, any page with Modernizr will give them a prompt:
12107     //   http://github.com/Modernizr/Modernizr/issues/closed#issue/113
12108
12109     // We have chosen to allow the Chrome incognito false positive, so that Modernizr
12110     //   doesn't litter the web with these test databases. As a developer, you'll have
12111     //   to account for this gotcha yourself.
12112     tests['websqldatabase'] = function() {
12113       var result = !!window.openDatabase;
12114       /*  if (result){
12115             try {
12116               result = !!openDatabase( mod + "testdb", "1.0", mod + "testdb", 2e4);
12117             } catch(e) {
12118             }
12119           }  */
12120       return result;
12121     };
12122
12123     // Vendors had inconsistent prefixing with the experimental Indexed DB:
12124     // - Webkit's implementation is accessible through webkitIndexedDB
12125     // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
12126     // For speed, we don't test the legacy (and beta-only) indexedDB
12127     tests['indexedDB'] = function() {
12128       for ( var i = -1, len = domPrefixes.length; ++i < len; ){
12129         if ( window[domPrefixes[i].toLowerCase() + 'IndexedDB'] ){
12130           return true;
12131         }
12132       }
12133       return !!window.indexedDB;
12134     };
12135
12136     // documentMode logic from YUI to filter out IE8 Compat Mode
12137     //   which false positives.
12138     tests['hashchange'] = function() {
12139       return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7);
12140     };
12141
12142     // Per 1.6:
12143     // This used to be Modernizr.historymanagement but the longer
12144     // name has been deprecated in favor of a shorter and property-matching one.
12145     // The old API is still available in 1.6, but as of 2.0 will throw a warning,
12146     // and in the first release thereafter disappear entirely.
12147     tests['history'] = function() {
12148       return !!(window.history && history.pushState);
12149     };
12150
12151     tests['draganddrop'] = function() {
12152         return isEventSupported('dragstart') && isEventSupported('drop');
12153     };
12154
12155     // Mozilla is targeting to land MozWebSocket for FF6
12156     // bugzil.la/659324
12157     tests['websockets'] = function() {
12158         for ( var i = -1, len = domPrefixes.length; ++i < len; ){
12159           if ( window[domPrefixes[i] + 'WebSocket'] ){
12160             return true;
12161           }
12162         }
12163         return 'WebSocket' in window;
12164     };
12165
12166
12167     // http://css-tricks.com/rgba-browser-support/
12168     tests['rgba'] = function() {
12169         // Set an rgba() color and check the returned value
12170
12171         setCss('background-color:rgba(150,255,150,.5)');
12172
12173         return contains(mStyle.backgroundColor, 'rgba');
12174     };
12175
12176     tests['hsla'] = function() {
12177         // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
12178         //   except IE9 who retains it as hsla
12179
12180         setCss('background-color:hsla(120,40%,100%,.5)');
12181
12182         return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
12183     };
12184
12185     tests['multiplebgs'] = function() {
12186         // Setting multiple images AND a color on the background shorthand property
12187         //  and then querying the style.background property value for the number of
12188         //  occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
12189
12190         setCss('background:url(https://),url(https://),red url(https://)');
12191
12192         // If the UA supports multiple backgrounds, there should be three occurrences
12193         //   of the string "url(" in the return value for elemStyle.background
12194
12195         return /(url\s*\(.*?){3}/.test(mStyle.background);
12196     };
12197
12198
12199     // In testing support for a given CSS property, it's legit to test:
12200     //    `elem.style[styleName] !== undefined`
12201     // If the property is supported it will return an empty string,
12202     // if unsupported it will return undefined.
12203
12204     // We'll take advantage of this quick test and skip setting a style
12205     // on our modernizr element, but instead just testing undefined vs
12206     // empty string.
12207
12208
12209     tests['backgroundsize'] = function() {
12210         return testPropsAll('backgroundSize');
12211     };
12212
12213     tests['borderimage'] = function() {
12214         return testPropsAll('borderImage');
12215     };
12216
12217
12218     // Super comprehensive table about all the unique implementations of
12219     // border-radius: http://muddledramblings.com/table-of-css3-border-radius-compliance
12220
12221     tests['borderradius'] = function() {
12222         return testPropsAll('borderRadius');
12223     };
12224
12225     // WebOS unfortunately false positives on this test.
12226     tests['boxshadow'] = function() {
12227         return testPropsAll('boxShadow');
12228     };
12229
12230     // FF3.0 will false positive on this test
12231     tests['textshadow'] = function() {
12232         return document.createElement('div').style.textShadow === '';
12233     };
12234
12235
12236     tests['opacity'] = function() {
12237         // Browsers that actually have CSS Opacity implemented have done so
12238         //  according to spec, which means their return values are within the
12239         //  range of [0.0,1.0] - including the leading zero.
12240
12241         setCssAll('opacity:.55');
12242
12243         // The non-literal . in this regex is intentional:
12244         //   German Chrome returns this value as 0,55
12245         // https://github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
12246         return /^0.55$/.test(mStyle.opacity);
12247     };
12248
12249
12250     tests['cssanimations'] = function() {
12251         return testPropsAll('animationName');
12252     };
12253
12254
12255     tests['csscolumns'] = function() {
12256         return testPropsAll('columnCount');
12257     };
12258
12259
12260     tests['cssgradients'] = function() {
12261         /**
12262          * For CSS Gradients syntax, please see:
12263          * http://webkit.org/blog/175/introducing-css-gradients/
12264          * https://developer.mozilla.org/en/CSS/-moz-linear-gradient
12265          * https://developer.mozilla.org/en/CSS/-moz-radial-gradient
12266          * http://dev.w3.org/csswg/css3-images/#gradients-
12267          */
12268
12269         var str1 = 'background-image:',
12270             str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
12271             str3 = 'linear-gradient(left top,#9f9, white);';
12272
12273         setCss(
12274             (str1 + prefixes.join(str2 + str1) + prefixes.join(str3 + str1)).slice(0, -str1.length)
12275         );
12276
12277         return contains(mStyle.backgroundImage, 'gradient');
12278     };
12279
12280
12281     tests['cssreflections'] = function() {
12282         return testPropsAll('boxReflect');
12283     };
12284
12285
12286     tests['csstransforms'] = function() {
12287         return !!testProps(['transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform']);
12288     };
12289
12290
12291     tests['csstransforms3d'] = function() {
12292
12293         var ret = !!testProps(['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']);
12294
12295         // Webkit’s 3D transforms are passed off to the browser's own graphics renderer.
12296         //   It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
12297         //   some conditions. As a result, Webkit typically recognizes the syntax but
12298         //   will sometimes throw a false positive, thus we must do a more thorough check:
12299         if ( ret && 'webkitPerspective' in docElement.style ) {
12300
12301           // Webkit allows this media query to succeed only if the feature is enabled.
12302           // `@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){ ... }`
12303           ret = Modernizr['csstransforms3d'];
12304         }
12305         return ret;
12306     };
12307
12308
12309     tests['csstransitions'] = function() {
12310         return testPropsAll('transitionProperty');
12311     };
12312
12313
12314     /*>>fontface*/
12315     // @font-face detection routine by Diego Perini
12316     // http://javascript.nwbox.com/CSSSupport/
12317     tests['fontface'] = function() {
12318         return Modernizr['fontface'];
12319     };
12320     /*>>fontface*/
12321
12322     // CSS generated content detection
12323     tests['generatedcontent'] = function() {
12324         return Modernizr['generatedcontent'];
12325     };
12326
12327
12328
12329     // These tests evaluate support of the video/audio elements, as well as
12330     // testing what types of content they support.
12331     //
12332     // We're using the Boolean constructor here, so that we can extend the value
12333     // e.g.  Modernizr.video     // true
12334     //       Modernizr.video.ogg // 'probably'
12335     //
12336     // Codec values from : http://github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
12337     //                     thx to NielsLeenheer and zcorpan
12338
12339     // Note: in FF 3.5.1 and 3.5.0, "no" was a return value instead of empty string.
12340     //   Modernizr does not normalize for that.
12341
12342     tests['video'] = function() {
12343         var elem = document.createElement('video'),
12344             bool = false;
12345             
12346         // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
12347         try {
12348             if ( bool = !!elem.canPlayType ) {
12349                 bool      = new Boolean(bool);
12350                 bool.ogg  = elem.canPlayType('video/ogg; codecs="theora"');
12351
12352                 // Workaround required for IE9, which doesn't report video support without audio codec specified.
12353                 //   bug 599718 @ msft connect
12354                 var h264 = 'video/mp4; codecs="avc1.42E01E';
12355                 bool.h264 = elem.canPlayType(h264 + '"') || elem.canPlayType(h264 + ', mp4a.40.2"');
12356
12357                 bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"');
12358             }
12359             
12360         } catch(e) { }
12361         
12362         return bool;
12363     };
12364
12365     tests['audio'] = function() {
12366         var elem = document.createElement('audio'),
12367             bool = false;
12368
12369         try { 
12370             if ( bool = !!elem.canPlayType ) {
12371                 bool      = new Boolean(bool);
12372                 bool.ogg  = elem.canPlayType('audio/ogg; codecs="vorbis"');
12373                 bool.mp3  = elem.canPlayType('audio/mpeg;');
12374
12375                 // Mimetypes accepted:
12376                 //   https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
12377                 //   http://bit.ly/iphoneoscodecs
12378                 bool.wav  = elem.canPlayType('audio/wav; codecs="1"');
12379                 bool.m4a  = elem.canPlayType('audio/x-m4a;') || elem.canPlayType('audio/aac;');
12380             }
12381         } catch(e) { }
12382         
12383         return bool;
12384     };
12385
12386
12387     // Firefox has made these tests rather unfun.
12388
12389     // In FF4, if disabled, window.localStorage should === null.
12390
12391     // Normally, we could not test that directly and need to do a
12392     //   `('localStorage' in window) && ` test first because otherwise Firefox will
12393     //   throw http://bugzil.la/365772 if cookies are disabled
12394
12395     // However, in Firefox 4 betas, if dom.storage.enabled == false, just mentioning
12396     //   the property will throw an exception. http://bugzil.la/599479
12397     // This looks to be fixed for FF4 Final.
12398
12399     // Because we are forced to try/catch this, we'll go aggressive.
12400
12401     // FWIW: IE8 Compat mode supports these features completely:
12402     //   http://www.quirksmode.org/dom/html5.html
12403     // But IE8 doesn't support either with local files
12404
12405     tests['localstorage'] = function() {
12406         try {
12407             return !!localStorage.getItem;
12408         } catch(e) {
12409             return false;
12410         }
12411     };
12412
12413     tests['sessionstorage'] = function() {
12414         try {
12415             return !!sessionStorage.getItem;
12416         } catch(e){
12417             return false;
12418         }
12419     };
12420
12421
12422     tests['webworkers'] = function() {
12423         return !!window.Worker;
12424     };
12425
12426
12427     tests['applicationcache'] = function() {
12428         return !!window.applicationCache;
12429     };
12430
12431
12432     // Thanks to Erik Dahlstrom
12433     tests['svg'] = function() {
12434         return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
12435     };
12436
12437     // specifically for SVG inline in HTML, not within XHTML
12438     // test page: paulirish.com/demo/inline-svg
12439     tests['inlinesvg'] = function() {
12440       var div = document.createElement('div');
12441       div.innerHTML = '<svg/>';
12442       return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
12443     };
12444
12445     // Thanks to F1lt3r and lucideer, ticket #35
12446     tests['smil'] = function() {
12447         return !!document.createElementNS && /SVG/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
12448     };
12449
12450     tests['svgclippaths'] = function() {
12451         // Possibly returns a false positive in Safari 3.2?
12452         return !!document.createElementNS && /SVG/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
12453     };
12454
12455     // input features and input types go directly onto the ret object, bypassing the tests loop.
12456     // Hold this guy to execute in a moment.
12457     function webforms() {
12458         // Run through HTML5's new input attributes to see if the UA understands any.
12459         // We're using f which is the <input> element created early on
12460         // Mike Taylr has created a comprehensive resource for testing these attributes
12461         //   when applied to all input types:
12462         //   http://miketaylr.com/code/input-type-attr.html
12463         // spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
12464         
12465         // Only input placeholder is tested while textarea's placeholder is not. 
12466         // Currently Safari 4 and Opera 11 have support only for the input placeholder
12467         // Both tests are available in feature-detects/forms-placeholder.js
12468         Modernizr['input'] = (function( props ) {
12469             for ( var i = 0, len = props.length; i < len; i++ ) {
12470                 attrs[ props[i] ] = !!(props[i] in inputElem);
12471             }
12472             return attrs;
12473         })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
12474
12475         // Run through HTML5's new input types to see if the UA understands any.
12476         //   This is put behind the tests runloop because it doesn't return a
12477         //   true/false like all the other tests; instead, it returns an object
12478         //   containing each input type with its corresponding true/false value
12479
12480         // Big thanks to @miketaylr for the html5 forms expertise. http://miketaylr.com/
12481         Modernizr['inputtypes'] = (function(props) {
12482
12483             for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
12484
12485                 inputElem.setAttribute('type', inputElemType = props[i]);
12486                 bool = inputElem.type !== 'text';
12487
12488                 // We first check to see if the type we give it sticks..
12489                 // If the type does, we feed it a textual value, which shouldn't be valid.
12490                 // If the value doesn't stick, we know there's input sanitization which infers a custom UI
12491                 if ( bool ) {
12492
12493                     inputElem.value         = smile;
12494                     inputElem.style.cssText = 'position:absolute;visibility:hidden;';
12495
12496                     if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
12497
12498                       docElement.appendChild(inputElem);
12499                       defaultView = document.defaultView;
12500
12501                       // Safari 2-4 allows the smiley as a value, despite making a slider
12502                       bool =  defaultView.getComputedStyle &&
12503                               defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
12504                               // Mobile android web browser has false positive, so must
12505                               // check the height to see if the widget is actually there.
12506                               (inputElem.offsetHeight !== 0);
12507
12508                       docElement.removeChild(inputElem);
12509
12510                     } else if ( /^(search|tel)$/.test(inputElemType) ){
12511                       // Spec doesnt define any special parsing or detectable UI
12512                       //   behaviors so we pass these through as true
12513
12514                       // Interestingly, opera fails the earlier test, so it doesn't
12515                       //  even make it here.
12516
12517                     } else if ( /^(url|email)$/.test(inputElemType) ) {
12518                       // Real url and email support comes with prebaked validation.
12519                       bool = inputElem.checkValidity && inputElem.checkValidity() === false;
12520
12521                     } else if ( /^color$/.test(inputElemType) ) {
12522                         // chuck into DOM and force reflow for Opera bug in 11.00
12523                         // github.com/Modernizr/Modernizr/issues#issue/159
12524                         docElement.appendChild(inputElem);
12525                         docElement.offsetWidth;
12526                         bool = inputElem.value != smile;
12527                         docElement.removeChild(inputElem);
12528
12529                     } else {
12530                       // If the upgraded input compontent rejects the :) text, we got a winner
12531                       bool = inputElem.value != smile;
12532                     }
12533                 }
12534
12535                 inputs[ props[i] ] = !!bool;
12536             }
12537             return inputs;
12538         })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
12539     }
12540
12541
12542     // End of test definitions
12543     // -----------------------
12544
12545
12546
12547     // Run through all tests and detect their support in the current UA.
12548     // todo: hypothetically we could be doing an array of tests and use a basic loop here.
12549     for ( var feature in tests ) {
12550         if ( hasOwnProperty(tests, feature) ) {
12551             // run the test, throw the return value into the Modernizr,
12552             //   then based on that boolean, define an appropriate className
12553             //   and push it into an array of classes we'll join later.
12554             featureName  = feature.toLowerCase();
12555             Modernizr[featureName] = tests[feature]();
12556
12557             classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
12558         }
12559     }
12560
12561     // input tests need to run.
12562     Modernizr.input || webforms();
12563
12564
12565     /**
12566      * addTest allows the user to define their own feature tests
12567      * the result will be added onto the Modernizr object,
12568      * as well as an appropriate className set on the html element
12569      *
12570      * @param feature - String naming the feature
12571      * @param test - Function returning true if feature is supported, false if not
12572      */
12573      Modernizr.addTest = function ( feature, test ) {
12574        if ( typeof feature == "object" ) {
12575          for ( var key in feature ) {
12576            if ( hasOwnProperty( feature, key ) ) { 
12577              Modernizr.addTest( key, feature[ key ] );
12578            }
12579          }
12580        } else {
12581
12582          feature = feature.toLowerCase();
12583
12584          if ( Modernizr[feature] !== undefined ) {
12585            // we're going to quit if you're trying to overwrite an existing test
12586            // if we were to allow it, we'd do this:
12587            //   var re = new RegExp("\\b(no-)?" + feature + "\\b");  
12588            //   docElement.className = docElement.className.replace( re, '' );
12589            // but, no rly, stuff 'em.
12590            return; 
12591          }
12592
12593          test = typeof test == "boolean" ? test : !!test();
12594
12595          docElement.className += ' ' + (test ? '' : 'no-') + feature;
12596          Modernizr[feature] = test;
12597
12598        }
12599
12600        return Modernizr; // allow chaining.
12601      };
12602     
12603
12604     // Reset modElem.cssText to nothing to reduce memory footprint.
12605     setCss('');
12606     modElem = inputElem = null;
12607
12608     //>>BEGIN IEPP
12609     // Enable HTML 5 elements for styling (and printing) in IE.
12610     if ( window.attachEvent && (function(){ var elem = document.createElement('div');
12611                                             elem.innerHTML = '<elem></elem>';
12612                                             return elem.childNodes.length !== 1; })() ) {
12613                                               
12614         // iepp v2 by @jon_neal & afarkas : github.com/aFarkas/iepp/
12615         (function(win, doc) {
12616           win.iepp = win.iepp || {};
12617           var iepp = win.iepp,
12618             elems = iepp.html5elements || 'abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video',
12619             elemsArr = elems.split('|'),
12620             elemsArrLen = elemsArr.length,
12621             elemRegExp = new RegExp('(^|\\s)('+elems+')', 'gi'),
12622             tagRegExp = new RegExp('<(\/*)('+elems+')', 'gi'),
12623             filterReg = /^\s*[\{\}]\s*$/,
12624             ruleRegExp = new RegExp('(^|[^\\n]*?\\s)('+elems+')([^\\n]*)({[\\n\\w\\W]*?})', 'gi'),
12625             docFrag = doc.createDocumentFragment(),
12626             html = doc.documentElement,
12627             head = html.firstChild,
12628             bodyElem = doc.createElement('body'),
12629             styleElem = doc.createElement('style'),
12630             printMedias = /print|all/,
12631             body;
12632           function shim(doc) {
12633             var a = -1;
12634             while (++a < elemsArrLen)
12635               // Use createElement so IE allows HTML5-named elements in a document
12636               doc.createElement(elemsArr[a]);
12637           }
12638
12639           iepp.getCSS = function(styleSheetList, mediaType) {
12640             if(styleSheetList+'' === undefined){return '';}
12641             var a = -1,
12642               len = styleSheetList.length,
12643               styleSheet,
12644               cssTextArr = [];
12645             while (++a < len) {
12646               styleSheet = styleSheetList[a];
12647               //currently no test for disabled/alternate stylesheets
12648               if(styleSheet.disabled){continue;}
12649               mediaType = styleSheet.media || mediaType;
12650               // Get css from all non-screen stylesheets and their imports
12651               if (printMedias.test(mediaType)) cssTextArr.push(iepp.getCSS(styleSheet.imports, mediaType), styleSheet.cssText);
12652               //reset mediaType to all with every new *not imported* stylesheet
12653               mediaType = 'all';
12654             }
12655             return cssTextArr.join('');
12656           };
12657
12658           iepp.parseCSS = function(cssText) {
12659             var cssTextArr = [],
12660               rule;
12661             while ((rule = ruleRegExp.exec(cssText)) != null){
12662               // Replace all html5 element references with iepp substitute classnames
12663               cssTextArr.push(( (filterReg.exec(rule[1]) ? '\n' : rule[1]) +rule[2]+rule[3]).replace(elemRegExp, '$1.iepp_$2')+rule[4]);
12664             }
12665             return cssTextArr.join('\n');
12666           };
12667
12668           iepp.writeHTML = function() {
12669             var a = -1;
12670             body = body || doc.body;
12671             while (++a < elemsArrLen) {
12672               var nodeList = doc.getElementsByTagName(elemsArr[a]),
12673                 nodeListLen = nodeList.length,
12674                 b = -1;
12675               while (++b < nodeListLen)
12676                 if (nodeList[b].className.indexOf('iepp_') < 0)
12677                   // Append iepp substitute classnames to all html5 elements
12678                   nodeList[b].className += ' iepp_'+elemsArr[a];
12679             }
12680             docFrag.appendChild(body);
12681             html.appendChild(bodyElem);
12682             // Write iepp substitute print-safe document
12683             bodyElem.className = body.className;
12684             bodyElem.id = body.id;
12685             // Replace HTML5 elements with <font> which is print-safe and shouldn't conflict since it isn't part of html5
12686             bodyElem.innerHTML = body.innerHTML.replace(tagRegExp, '<$1font');
12687           };
12688
12689
12690           iepp._beforePrint = function() {
12691             // Write iepp custom print CSS
12692             styleElem.styleSheet.cssText = iepp.parseCSS(iepp.getCSS(doc.styleSheets, 'all'));
12693             iepp.writeHTML();
12694           };
12695
12696           iepp.restoreHTML = function(){
12697             // Undo everything done in onbeforeprint
12698             bodyElem.innerHTML = '';
12699             html.removeChild(bodyElem);
12700             html.appendChild(body);
12701           };
12702
12703           iepp._afterPrint = function(){
12704             // Undo everything done in onbeforeprint
12705             iepp.restoreHTML();
12706             styleElem.styleSheet.cssText = '';
12707           };
12708
12709
12710
12711           // Shim the document and iepp fragment
12712           shim(doc);
12713           shim(docFrag);
12714
12715           //
12716           if(iepp.disablePP){return;}
12717
12718           // Add iepp custom print style element
12719           head.insertBefore(styleElem, head.firstChild);
12720           styleElem.media = 'print';
12721           styleElem.className = 'iepp-printshim';
12722           win.attachEvent(
12723             'onbeforeprint',
12724             iepp._beforePrint
12725           );
12726           win.attachEvent(
12727             'onafterprint',
12728             iepp._afterPrint
12729           );
12730         })(window, document);
12731     }
12732     //>>END IEPP
12733
12734     // Assign private properties to the return object with prefix
12735     Modernizr._version      = version;
12736
12737     // expose these for the plugin API. Look in the source for how to join() them against your input
12738     Modernizr._prefixes     = prefixes;
12739     Modernizr._domPrefixes  = domPrefixes;
12740     
12741     // Modernizr.mq tests a given media query, live against the current state of the window
12742     // A few important notes:
12743     //   * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
12744     //   * A max-width or orientation query will be evaluated against the current state, which may change later.
12745     //   * You must specify values. Eg. If you are testing support for the min-width media query use: 
12746     //       Modernizr.mq('(min-width:0)')
12747     // usage:
12748     // Modernizr.mq('only screen and (max-width:768)')
12749     Modernizr.mq            = testMediaQuery;   
12750     
12751     // Modernizr.hasEvent() detects support for a given event, with an optional element to test on
12752     // Modernizr.hasEvent('gesturestart', elem)
12753     Modernizr.hasEvent      = isEventSupported; 
12754
12755     // Modernizr.testProp() investigates whether a given style property is recognized
12756     // Note that the property names must be provided in the camelCase variant.
12757     // Modernizr.testProp('pointerEvents')
12758     Modernizr.testProp      = function(prop){
12759         return testProps([prop]);
12760     };        
12761
12762     // Modernizr.testAllProps() investigates whether a given style property,
12763     //   or any of its vendor-prefixed variants, is recognized
12764     // Note that the property names must be provided in the camelCase variant.
12765     // Modernizr.testAllProps('boxSizing')    
12766     Modernizr.testAllProps  = testPropsAll;     
12767
12768
12769     
12770     // Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards
12771     // Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... })
12772     Modernizr.testStyles    = injectElementWithStyles; 
12773
12774
12775     // Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
12776     // Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
12777     
12778     // Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
12779     // Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
12780     //
12781     //     str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
12782     
12783     // If you're trying to ascertain which transition end event to bind to, you might do something like...
12784     // 
12785     //     var transEndEventNames = {
12786     //       'WebkitTransition' : 'webkitTransitionEnd',
12787     //       'MozTransition'    : 'transitionend',
12788     //       'OTransition'      : 'oTransitionEnd',
12789     //       'msTransition'     : 'msTransitionEnd', // maybe?
12790     //       'transition'       : 'transitionEnd'
12791     //     },
12792     //     transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
12793     
12794     Modernizr.prefixed      = function(prop){
12795       return testPropsAll(prop, 'pfx');
12796     };
12797
12798
12799
12800     // Remove "no-js" class from <html> element, if it exists:
12801     docElement.className = docElement.className.replace(/\bno-js\b/, '')
12802                             
12803                             // Add the new classes to the <html> element.
12804                             + (enableClasses ? ' js ' + classes.join(' ') : '');
12805
12806     return Modernizr;
12807
12808 })(this, this.document);
12809
12810 /**\r
12811 * Array prototype extensions.\r
12812 * Extends array prototype with the following methods:\r
12813 * contains, every, exfiltrate, filter, forEach, getRange, inArray, indexOf, insertAt, map, randomize, removeAt, some, unique\r
12814\r
12815 * This extensions doesn't depend on any other code or overwrite existing methods.\r
12816\r
12817 *\r
12818 * Copyright (c) 2007 Harald Hanek (http://js-methods.googlecode.com)\r
12819 *\r
12820 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)\r
12821 * and GPL (http://www.gnu.org/licenses/gpl.html) licenses.\r
12822\r
12823 * @author Harald Hanek\r
12824 * @version 0.9\r
12825 * @lastchangeddate 10. October 2007 15:46:06\r
12826 * @revision 876\r
12827 */\r
12828 \r
12829 (function(){\r
12830 \r
12831         /**\r
12832         * Extend the array prototype with the method under the given name if it doesn't currently exist.\r
12833         *\r
12834         * @private\r
12835         */\r
12836         function append(name, method)\r
12837         {\r
12838                 if(!Array.prototype[name])\r
12839                         Array.prototype[name] = method;\r
12840         };\r
12841 \r
12842 \r
12843         /**\r
12844         * Returns true if every element in 'elements' is in the array.\r
12845         *\r
12846         * @example [1, 2, 1, 4, 5, 4].contains([1, 2, 4]);\r
12847         * @result true\r
12848         *\r
12849         * @name contains\r
12850         * @param Array elements\r
12851         * @return Boolean\r
12852         */\r
12853         append("contains", function(elements){\r
12854                 return this.every(function(element){\r
12855                         return this.indexOf(element) >= 0; }, elements);\r
12856         });\r
12857 \r
12858 \r
12859         /**\r
12860         * Returns the array without the elements in 'elements'.\r
12861         * \r
12862         * @example [1, 2, 1, 4, 5, 4].contains([1, 2, 4]);\r
12863         * @result true\r
12864         *\r
12865         * @name exfiltrate\r
12866         * @param Array elements\r
12867         * @return Boolean\r
12868         */\r
12869         append("exfiltrate", function(elements){\r
12870                 return this.filter(function(element){\r
12871                         return this.indexOf(element) < 0; }, elements);\r
12872         });\r
12873 \r
12874 \r
12875         /**\r
12876         * Tests whether all elements in the array pass the test implemented by the provided function.\r
12877         * \r
12878         * @example [22, 72, 16, 99, 254].every(function(element, index, array) {\r
12879         *   return element >= 15;\r
12880         * });\r
12881         * @result true;\r
12882         *\r
12883         * @example [12, 72, 16, 99, 254].every(function(element, index, array) {\r
12884         *   return element >= 15;\r
12885         * });\r
12886         * @result false;\r
12887         *\r
12888         * @name every\r
12889         * @param Function fn The function to be called for each element.\r
12890         * @param Object scope (optional) The scope of the function (defaults to this).\r
12891         * @return Boolean\r
12892         */\r
12893         append("every", function(fn, scope){\r
12894                 for(var i = 0; i < this.length; i++)\r
12895                         if(!fn.call(scope || window, this[i], i, this))\r
12896                                 return false;\r
12897                 return true;\r
12898         });\r
12899 \r
12900 \r
12901         /**\r
12902         * Creates a new array with all elements that pass the test implemented by the provided function.\r
12903         *\r
12904         * Natively supported in Gecko since version 1.8.\r
12905         * http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:filter\r
12906         * \r
12907         * @example [12, 5, 8, 1, 44].filter(function(element, index, array) {\r
12908         *   return element >= 10;\r
12909         * });\r
12910         * @result [12, 44];\r
12911         *\r
12912         * @name filter\r
12913         * @param Function fn The function to be called for each element.\r
12914         * @param Object scope (optional) The scope of the function (defaults to this).\r
12915         * @return Array\r
12916         */\r
12917         append("filter", function(fn, scope){\r
12918                 var r = [];\r
12919                 for(var i = 0; i < this.length; i++)\r
12920                         if(fn.call(scope || window, this[i], i, this))\r
12921                                 r.push(this[i]);\r
12922                 return r;\r
12923         });\r
12924 \r
12925 \r
12926         /**\r
12927         * Executes a provided function once per array element.\r
12928         *\r
12929         * Natively supported in Gecko since version 1.8.\r
12930         * http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:forEach\r
12931         * \r
12932         * @example var stuff = "";\r
12933         * ["Java", "Script"].forEach(function(element, index, array) {\r
12934         *   stuff += element;\r
12935         * });\r
12936         * @result "JavaScript";\r
12937         *\r
12938         * @name forEach\r
12939         * @param Function fn The function to be called for each element.\r
12940         * @param Object scope (optional) The scope of the function (defaults to this).\r
12941         * @return void\r
12942         */      \r
12943         append("forEach", function(fn, scope){\r
12944                 for(var i = 0; i < this.length; i++)\r
12945                         fn.call(scope || window, this[i], i, this);\r
12946         });\r
12947 \r
12948 \r
12949         /**\r
12950         * Returns a range of items in this collection\r
12951         *\r
12952         * @example [1, 2, 1, 4, 5, 4].getRange(2, 4);\r
12953         * @result [1, 4, 5]\r
12954         *\r
12955         * @name getRange\r
12956         * @param Number startIndex (optional) defaults to 0\r
12957         * @param Number endIndex (optional) default to the last item\r
12958         * @return Array\r
12959         */\r
12960         append("getRange", function(start, end){\r
12961                 var items = this;\r
12962                 if(items.length < 1)\r
12963                         return [];\r
12964 \r
12965                 start = start || 0;\r
12966                 end = Math.min(typeof end == "undefined" ? this.length-1 : end, this.length-1);\r
12967                 var r = [];\r
12968                 if(start <= end)\r
12969                         for(var i = start; i <= end; i++)\r
12970                                 r[r.length] = items[i];\r
12971                 else\r
12972                         for(var i = start; i >= end; i--)\r
12973                                 r[r.length] = items[i];\r
12974 \r
12975                 return r;\r
12976         });\r
12977 \r
12978 \r
12979         /**\r
12980         * Returns the first index at which a given element can be found in the array, or -1 if it is not present.\r
12981         *\r
12982         * @example [12, 5, 8, 5, 44].indexOf(5);\r
12983         * @result 1;\r
12984         *\r
12985         * @example [12, 5, 8, 5, 44].indexOf(5, 2);\r
12986         * @result 3;\r
12987         *\r
12988         * @name indexOf\r
12989         * @param Object subject Object to search for\r
12990         * @param Number offset (optional) Index at which to start searching\r
12991         * @return Int\r
12992         */\r
12993         append("indexOf", function(subject, offset){\r
12994                 for(var i = offset || 0; i < this.length; i++)\r
12995                         if(this[i] === subject)\r
12996                                 return i;\r
12997                 return -1;\r
12998         });\r
12999 \r
13000 \r
13001         /**\r
13002         * Checks if a given subject can be found in the array.\r
13003         *\r
13004         * @example [12, 5, 7, 5].inArray(7);\r
13005         * @result true;\r
13006         *\r
13007         * @example [12, 5, 7, 5].inArray(9);\r
13008         * @result false;\r
13009         *\r
13010         * @name inArray\r
13011         * @param Object subject Object to search for\r
13012         * @return Boolean\r
13013         */\r
13014         append("inArray", function(subject){\r
13015                 for(var i = 0; i < this.length; i++)\r
13016                         if(subject == this[i])\r
13017                                 return true;\r
13018                 return false;\r
13019         });\r
13020 \r
13021 \r
13022         /**\r
13023         * Inserts an item at the specified index in the array.\r
13024         *\r
13025         * @example ['dog', 'cat', 'horse'].insertAt(2, 'mouse');\r
13026         * @result ['dog', 'cat', 'mouse', 'horse']\r
13027         *\r
13028         * @name insertAt\r
13029         * @param Number index Position where to insert the element into the array\r
13030         * @param Object element The element to insert\r
13031         * @return Array\r
13032         */\r
13033         append("insertAt", function(index, element){\r
13034                 for(var k = this.length; k > index; k--)\r
13035                         this[k] = this[k-1];\r
13036                 this[index] = element;\r
13037                 return this;\r
13038         });\r
13039 \r
13040 \r
13041         /**\r
13042         * Creates a new array with the results of calling a provided function on every element in this array.\r
13043         *\r
13044         * Natively supported in Gecko since version 1.8.\r
13045         * http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:map\r
13046         * \r
13047         * @example ["my", "Name", "is", "HARRY"].map(function(element, index, array) {\r
13048         *   return element.toUpperCase();\r
13049         * });\r
13050         * @result ["MY", "NAME", "IS", "HARRY"];\r
13051         *\r
13052         * @example [1, 4, 9].map(Math.sqrt);\r
13053         * @result [1, 2, 3];\r
13054         *\r
13055         * @name map\r
13056         * @param Function fn The function to be called for each element.\r
13057         * @param Object scope (optional) The scope of the function (defaults to this).\r
13058         * @return Array\r
13059         */\r
13060         append("map", function(fn, scope){\r
13061                 scope = scope || window;\r
13062                 var r = [];\r
13063                 for(var i = 0; i < this.length; i++)\r
13064                         r[r.length] = fn.call(scope, this[i], i, this);\r
13065                 return r;\r
13066         });\r
13067 \r
13068 \r
13069         /**\r
13070         * Remove an item from a specified index in the array.\r
13071         *\r
13072         * @example ['dog', 'cat', 'mouse', 'horse'].deleteAt(2);\r
13073         * @result ['dog', 'cat', 'horse']\r
13074         *\r
13075         * @name removeAt\r
13076         * @param Number index The index within the array of the item to remove.\r
13077         * @return Array\r
13078         */\r
13079         append("removeAt", function(index){\r
13080                 for(var k = index; k < this.length-1; k++)\r
13081                         this[k] = this[k+1];\r
13082                 this.length--;\r
13083                 return this;\r
13084         });\r
13085 \r
13086 \r
13087         /**\r
13088         * Randomize the order of the elements in the Array.\r
13089         *\r
13090         * @example [2, 3, 4, 5].randomize();\r
13091         * @result [5, 2, 3, 4] randomized result\r
13092         *\r
13093         * @name randomize\r
13094         * @return Array\r
13095         */\r
13096         append("randomize", function(){\r
13097                 return this.sort(function(){return(Math.round(Math.random())-0.5)});\r
13098                 //return this.sort(function(){return(Math.round(Math.random())-0.5)}, true);\r
13099         });\r
13100 \r
13101 \r
13102         /**\r
13103         * Tests whether some element in the array passes the test implemented by the provided function.\r
13104         *\r
13105         * Natively supported in Gecko since version 1.8.\r
13106         * http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:some\r
13107         * \r
13108         * @example [101, 199, 250, 200].some(function(element, index, array) {\r
13109         *   return element >= 100;\r
13110         * });\r
13111         * @result true;\r
13112         *\r
13113         * @example [101, 99, 250, 200].some(function(element, index, array) {\r
13114         *   return element >= 100;\r
13115         * });\r
13116         * @result false;\r
13117         *\r
13118         * @name some\r
13119         * @param Function fn The function to be called for each element.\r
13120         * @param Object scope (optional) The scope of the function (defaults to this).\r
13121         * @return Boolean\r
13122         */\r
13123         append("some", function(fn, scope){\r
13124                 for(var i = 0; i < this.length; i++)\r
13125                         if(fn.call(scope || window, this[i], i, this))\r
13126                                 return true;\r
13127                 return false;\r
13128         });\r
13129 \r
13130 \r
13131         /**\r
13132         * Returns a new array that contains all unique elements of this array.\r
13133         *\r
13134         * @example [1, 2, 1, 4, 5, 4].unique();\r
13135         * @result [1, 2, 4, 5]\r
13136         *\r
13137         * @name unique\r
13138         * @return Array\r
13139         */\r
13140         append("unique", function(){\r
13141                 return this.filter(function(element, index, array){\r
13142                         return array.indexOf(element) >= index;\r
13143                 });\r
13144         });\r
13145 \r
13146 })();\r
13147 \r
13148
13149 /*
13150 Copyright 2011 The greplin-exception-catcher Authors.
13151
13152 Licensed under the Apache License, Version 2.0 (the "License");
13153 you may not use this file except in compliance with the License.
13154 You may obtain a copy of the License at
13155
13156     http://www.apache.org/licenses/LICENSE-2.0
13157
13158 Unless required by applicable law or agreed to in writing, software
13159 distributed under the License is distributed on an "AS IS" BASIS,
13160 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13161 See the License for the specific language governing permissions and
13162 limitations under the License.
13163 ====
13164
13165 This Javascript file lets web applications get stacktraces for all uncaught JS exceptions and send them to Greplin
13166 Exception Catcher.
13167
13168 Features include:
13169  - Stacktraces in IE 6-8, as well as modern versions of Firefox, Chrome, and Opera
13170  - Javascript execution entry point information (such as event type and listener) on IE 6-9 and modern versions of
13171    Firefox, Chrome, Safari, and Opera
13172  - Redaction of URLs and strings in stacktraces to avoid logging sensitive user information
13173
13174 Things that aren't done yet:
13175  - Aggregation. Due to the way GEC works now, this would be impossible to do without losing potentially useful
13176    information. To do this, GEC needs to be able to aggregate based upon a normalized stacktrace while still providing detailed information for each specific incident of the exception.
13177  - Can't wrap DOM0 events (<div onclick> for example).
13178  - Some code cleanup: Since this is a small, self-contained project, I took sort of a "hack it until it works" approach
13179    to coding it. I'd like to go back and structure the code better sometime, but I probably wont' get around to it
13180    anytime soon since it works very reliably as it is.
13181
13182 How to use it:
13183 1. Create an endpoint at your server to send this stuff to GEC.
13184 2. Modify the call to g.errorCatcher at the end of the file to pass in functions that pass exceptions to GEC and that
13185    redact URLs respectively. (Note: your URL redaction function will be passed strings that may contain URLs, not bare
13186    URLs, so keep that in mind)
13187 3. Wrap your JS files if you want to capture errors during their initial execution:
13188    
try {
 var your_js_here 
}
13189    catch(e) { window.g && g.handleInitialException && g.handleInitialException(e, '(script filename here)') }
13190    
If you use Closure Compiler, just do
13191    --output_wrapper="window.COMPILED = true; try { %%output%% } catch(e) { window.g && g.handleInitialException && g.handleInitialException(e, '(script filename here)') }"
13192 4. This exception catching script can't see exceptions that happen before it's loaded, so make sure it's loaded early in
13193    your page before most of your other scripts.
13194
13195  */
13196
13197 var g = g || {};
13198
13199
13200 /**
13201  * Captures uncaught JS exceptions on the page and passes them to GEC.
13202  * Can capture stacktraces in IE 6-8, Firefox, Chrome, and Opera, and can capture only the top of the stack in IE 9.
13203  * In Safari, only basic event information is captured.
13204  * Uses both window.onerror and wrapped DOM prototype interfaces to capture as much information as possible without
13205  * requiring JS code changes.
13206  */
13207 g.errorCatcher = function(reportHandler, redactQueryStrings) {
13208   g.errorCatcher.reportHandler_ = reportHandler;
13209   g.errorCatcher.redactQueryStrings_ = redactQueryStrings;
13210
13211   // commented out part is for weird cases where you have two exception catchers.
13212   // i haven't tested that case at all though, so i'm commenting it out for now.
13213   var wrappedProperty = 'WrappedListener'; //+ Math.floor(Math.random() * 10000000).toString(30);
13214
13215   var supportsJsErrorStack;
13216
13217   try {
13218     ({})['undefinedMethod']();
13219   } catch(error) {
13220     supportsJsErrorStack = 'stack' in error || 'stacktrace' in error;
13221   }
13222
13223   var supportsWindowOnerror = 'onerror' in window && !/^Opera/.test(navigator.userAgent);
13224
13225   var supportsWindowOnerrorStack = /MSIE /.test(navigator.userAgent);
13226
13227   // Detecting support based on a whitelist sucks, but we don't want to accidentally log personal information, so we
13228   // only allow browsers that we know that we can redact stacktrace strings for.
13229   var supportsDOMWrapping =
13230     // Chrome
13231     /Chrom(e|ium)/.test(navigator.userAgent) ||
13232
13233     // IE 9+
13234     /MSIE (9\.|[1-9][0-9]+\.)/.test(navigator.userAgent) || // XXX compat mode?
13235
13236     // Firefox 6+
13237     /Gecko\/[0-9]/.test(navigator.userAgent) && (parseInt(navigator['buildID'], 10) >= 20110830092941) ||
13238
13239     // Safari 5.1+ (AppleWebKit/534+)
13240     /AppleWebKit\/(53[4-9]|5[4-9][0-9]|[6-9][0-9]{2}|[1-9][0-9]{3})/.test(navigator.userAgent) ||
13241
13242     // Opera 11.50+
13243     /^Opera.*Presto\/(2\.9|[3-9]|[1-9][0-9])/.test(navigator.userAgent);
13244
13245   if (supportsDOMWrapping) {
13246     wrapTimeouts();
13247     wrapDOMEvents();
13248     wrapXMLHttpRequest();
13249   }
13250
13251   if (supportsWindowOnerror &&
13252       (!supportsDOMWrapping || (!supportsJsErrorStack && supportsWindowOnerrorStack))) {
13253     window.onerror = function(errorMessage, url, lineNumber) {
13254       // Grab the error provided by DOM wrappings, if it's available
13255       var errorObject = g.errorCatcher.lastDomWrapperError_ || {};
13256       delete g.errorCatcher.lastDomWrapperError_;
13257
13258       errorObject.message = errorObject.message || errorMessage;
13259       errorObject.url = errorObject.url || url;
13260       errorObject.line =  errorObject.line || lineNumber;
13261
13262       // In IE, get the character offset inside the line of the error from window.event.
13263       if (window.event && typeof window.event['errorCharacter'] == 'number') {
13264         errorObject.character = (errorObject.character || window.event['errorCharacter']) + '';
13265       }
13266
13267       // If there isn't already a stacktrace generated by the DOM wrappers, try to generate one using the old-fashioned
13268       // caller method. This only works in IE 6-8. It partially works in IE 9 -- but it only lets you get the top of the
13269       // stack.
13270       if (!errorObject.stacktrace && supportsWindowOnerrorStack) {
13271         try {
13272           errorObject.stacktrace = g.errorCatcher.getStacktrace(arguments.callee.caller);
13273         } catch(exception) {
13274           errorObject.stacktrace = '[error generating stacktrace: ' + exception.message + ']';
13275         }
13276       }
13277
13278       g.errorCatcher.reportException(errorObject);
13279     };
13280   }
13281
13282   /**
13283    * Wraps setTimeout and setInterval to handle uncaught exceptions in listeners.
13284    */
13285   function wrapTimeouts() {
13286     wrapTimeoutsHelper('setTimeout');
13287     wrapTimeoutsHelper('setInterval');
13288     function wrapTimeoutsHelper(timeoutMethodName) {
13289       var original = window[timeoutMethodName];
13290       window[timeoutMethodName] = function(listener, delay) {
13291         if (typeof listener == 'function') {
13292           var newArgs = Array.prototype.slice.call(arguments);
13293           newArgs[0] = function() {
13294             try {
13295               listener.apply(this, arguments);
13296             } catch(exception) {
13297               g.errorCatcher.handleCatchException(
13298                   exception, timeoutMethodName + '(' + g.errorCatcher.stringify(listener) + ', ' + delay + ')');
13299             }
13300           };
13301           return original.apply(this, newArgs);
13302         } else {
13303           // If someone passes a string to setTimeout, don't bother wrapping it.
13304           return original.apply(this, arguments);
13305         }
13306       }
13307     }
13308   }
13309
13310
13311   /**
13312    * Wraps DOM event interfaces (addEventListener and removeEventListener) to add try/catch wrappers to all event
13313    * listeners.
13314    */
13315   function wrapDOMEvents() {
13316     var eventsWrappedProperty = 'events' + wrappedProperty;
13317
13318     wrapDOMEventsHelper(window.XMLHttpRequest.prototype);
13319     wrapDOMEventsHelper(window.Element.prototype);
13320     wrapDOMEventsHelper(window);
13321     wrapDOMEventsHelper(window.document);
13322
13323     // Workaround for Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=456151
13324     if (document.documentElement.addEventListener != window.Element.prototype.addEventListener) {
13325       var elementNames =
13326           ('Unknown,Anchor,Applet,Area,BR,Base,Body,Button,DList,Directory,Div,Embed,FieldSet,Font,Form,Frame,' +
13327            'FrameSet,HR,Head,Heading,Html,IFrame,Image,Input,IsIndex,LI,Label,Legend,Link,Map,Menu,Meta,Span,OList,' +
13328            'Object,OptGroup,Option,Paragraph,Param,Pre,Quote,Script,Select,Style,TableCaption,TableCell,TableCol,' +
13329            'Table,TableRow,TableSection,TextArea,Title,UList,Canvas').split(',');
13330       elementNames.forEach(function(elementName) {
13331         var constructor = window['HTML' + elementName + 'Element'];
13332         if (constructor && constructor.prototype) {
13333           wrapDOMEventsHelper(constructor.prototype);
13334         }
13335       });
13336
13337     }
13338
13339     function wrapDOMEventsHelper(object) {
13340       var originalAddEventListener = object.addEventListener;
13341       var originalRemoveEventListener = object.removeEventListener;
13342       if (!originalAddEventListener || !originalRemoveEventListener) {
13343         return;
13344       }
13345       object.addEventListener = function(eventType, listener, useCapture) {
13346         // Dedupe the listener in case it is already listening unwrapped.
13347         originalRemoveEventListener.apply(this, arguments);
13348         if (typeof listener != 'function') {
13349           // TODO(david): Handle a listener that is not a function, but instead an object that implements the
13350           // EventListener interface (see http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener ).
13351           originalAddEventListener.apply(this, arguments);
13352           return;
13353         }
13354         listener[eventsWrappedProperty] = listener[eventsWrappedProperty] || {
13355           innerListener: listener,
13356           'handleEvent': g.errorCatcher.listenerWrapper_
13357         };
13358         originalAddEventListener.call(this, eventType, listener[eventsWrappedProperty], useCapture);
13359       };
13360       object.removeEventListener = function(eventType, listener, useCapture) {
13361         // Remove unwrapped listener, just to be sure.
13362         originalRemoveEventListener.apply(this, arguments);
13363         if (typeof listener != 'function') {
13364           return;
13365         }
13366         if (listener[eventsWrappedProperty]) {
13367           originalRemoveEventListener.call(this, eventType, listener[eventsWrappedProperty], useCapture);
13368         }
13369       };
13370     }
13371   }
13372
13373
13374   /**
13375    * Wrap XMLHttpRequest onreadystatechange listeners to handle uncaught JS exceptions.
13376    * This only affects the .onreadystatechange property. The addEventListener property is handled by wrapDOMEvents.
13377    */
13378   function wrapXMLHttpRequest() {
13379     var xhrWrappedProperty = 'xhr' + wrappedProperty;
13380     var ctor = XMLHttpRequest, instance = new XMLHttpRequest;
13381     if (!/(AppleWebKit|MSIE)/.test(navigator.userAgent) ||
13382         (Object.getOwnPropertyDescriptor(ctor.prototype, 'onreadystatechange') || {}).configurable &&
13383          instance.__lookupSetter__ && instance.__lookupSetter__('onreadystatechange')) {
13384       // The browser has good support for manipulating XMLHttpRequest prototypes.
13385       var onreadystatechangeSetter = instance.__lookupSetter__('onreadystatechange');
13386       ctor.prototype.__defineGetter__('onreadystatechange', function() {
13387         return this[xhrWrappedProperty];
13388       });
13389       ctor.prototype.__defineSetter__('onreadystatechange', function(listener) {
13390         this[xhrWrappedProperty] = listener;
13391         onreadystatechangeSetter.call(this, wrappedReadyStateChange);
13392       });
13393     } else {
13394       // Chrome and Safari have problems with this. Instead, check to see if onreadystatechange needs to be wrapped
13395       // from a readystatechange event listener.
13396       var send = instance.send;
13397       var addEventListener = instance.addEventListener;
13398       XMLHttpRequest.prototype.send = function() {
13399         addEventListener.call(this, 'readystatechange', wrapReadyStateChange, true);
13400         return send.apply(this, arguments);
13401       }
13402     }
13403     function wrappedReadyStateChange() {
13404       try {
13405         var onreadystatechange =
13406             (this.onreadystatechange == arguments.callee ?
13407              this[xhrWrappedProperty] : this.onreadystatechange);
13408         this[xhrWrappedProperty].apply(this, arguments);
13409       } catch(exception) {
13410         // TODO(david): Expose some information about the xmlhttprequest to the exception logging (maybe request url)
13411         g.errorCatcher.handleCatchException(exception, 'onreadystatechange');
13412       }
13413     }
13414     // Used in the wrapped XHR::send handler to wrap onreadystatechange in response to addEventListener
13415     // readystatechange events that fire first.
13416     function wrapReadyStateChange() {
13417       if (this.onreadystatechange && this.onreadystatechange != wrappedReadyStateChange) {
13418         this[xhrWrappedProperty] = this.onreadystatechange;
13419         this.onreadystatechange = wrappedReadyStateChange;
13420       }
13421     }
13422   }
13423 };
13424
13425
13426 /**
13427  * Time that the last error was reported. Used for rate-limiting.
13428  * @type {number}
13429  */
13430 g.errorCatcher.lastError_ = 0;
13431
13432
13433 /**
13434  * Delay between reporting errors. Increases dynamically.
13435  * @type {number}
13436  */
13437 g.errorCatcher.errorDelay_ = 10;
13438
13439
13440 /**
13441  * Wrapper for addEventListener/removeEventListener listeners. Global to avoid potential memory/performance impacts of a
13442  * function closure for each event listener. This is a handleEvent property of the EventHandler object passed to
13443  * addEventListener. It accesses other properties of that object to read exception information.
13444  * @param {Event} eventObject The DOM event.
13445  */
13446 g.errorCatcher.listenerWrapper_ = function(eventObject) {
13447   try {
13448     return this.innerListener.apply(eventObject.target, arguments);
13449   } catch(exception) {
13450     g.errorCatcher.handleCatchException(
13451         exception, eventObject.type + ' listener ' + g.errorCatcher.stringify(this.innerListener) + ' on ' +
13452             g.errorCatcher.stringify(eventObject.currentTarget));
13453   }
13454 };
13455
13456
13457 /**
13458  * Passes an exception to GEC.
13459  * TODO(david): show a message to the user. Let the user elect to send more detailed error information (un-redacted
13460  * strings).
13461  * @param {Object} errorObject An object describing the error.
13462  */
13463 g.errorCatcher.reportException = function(errorObject) {
13464   var d = (new Date).getTime();
13465   if (d - g.errorCatcher.lastError_ < g.errorCatcher.errorDelay_) {
13466     // Rate limited
13467     return;
13468   }
13469   g.errorCatcher.lastError_ = d;
13470   g.errorCatcher.errorDelay_ = g.errorCatcher.errorDelay_ * 2;
13471   errorObj = {
13472       'msg':g.errorCatcher.redactQueryStrings_(errorObject.message || ''),
13473       'line': errorObject.line + (typeof errorObject.character == 'string' ? ':' + errorObject.character : ''),
13474       'trace':'Type: ' + errorObject.name + '\nUser-agent: ' + navigator.userAgent +
13475           '\nURL: ' + g.errorCatcher.redactQueryStrings_(location.href) + '\n\n' +
13476           g.errorCatcher.redactQueryStrings_(errorObject.stacktrace || ''),
13477       'ts': Math.floor(new Date().getTime() / 1000),
13478       'name':g.errorCatcher.redactQueryStrings_(errorObject.context || '') || 'unidentified JS thread'};
13479   g.errorCatcher.reportHandler_(errorObj);
13480
13481 };
13482
13483
13484 /**
13485  * Handles exceptions from the try { } catch { } block added around all of our compiled JS by our Closure Compiler
13486  * configuration. This handles exceptions that occur during the intiial execution of the script.
13487  * @param {Error} caughtException The caught exception.
13488  * @param {string} fileName The name of the JS file where the exception occured.
13489  */
13490 g.errorCatcher.handleInitialException = function(caughtException, fileName) {
13491   g.errorCatcher.handleCatchException(caughtException, 'Initial execution of ' + fileName);
13492 };
13493
13494
13495 /**
13496  * Handles a caught exception. When window.onerror is available, the exception is re-thrown so that additional
13497  * information from window.onerror can be added. Otherwise, the exception is passed to reportException, where it is
13498  * sent to GEC and potentially displayed to the user.
13499  * @param {Error} caughtException The caught JS exception.
13500  * @param context
13501  */
13502 g.errorCatcher.handleCatchException = function(caughtException, context) {
13503   if (!(caughtException instanceof window.Error)) {
13504     caughtException = new Error(caughtException);
13505   }
13506
13507   var errorObject = {};
13508   errorObject.context = context;
13509   errorObject.name = caughtException.name;
13510   // Opera has both stacktrace and stack. Stacktrace is much more detailed, so use that when available.
13511   errorObject.stacktrace = caughtException['stacktrace'] || caughtException['stack'];
13512   if (/Gecko/.test(navigator.userAgent) && !/AppleWebKit/.test(navigator.userAgent)) {
13513     errorObject.stacktrace = g.errorCatcher.redactFirefoxStacktraceStrings(errorObject.stacktrace);
13514   }
13515   errorObject.message = caughtException.message;
13516   errorObject.number = caughtException.number;
13517
13518   var matches;
13519   if ('lineNumber' in caughtException) {
13520     errorObject.line = caughtException['lineNumber'];
13521   } else if ('line' in caughtException) {
13522     errorObject.line = caughtException['line'];
13523   } else if (/Chrom(e|ium)/.test(navigator.userAgent)) {
13524     matches = caughtException.stack.match(/\:(\d+)\:(\d+)\)(\n|$)/);
13525     if (matches) {
13526       errorObject.line = matches[1];
13527       errorObject.character = matches[2];
13528     }
13529   } else if (/Opera/.test(navigator.userAgent)) {
13530     matches = (errorObject['stacktrace'] || '').match(/Error thrown at line (\d+), column (\d+)/);
13531     if (matches) {
13532       errorObject.line = matches[1];
13533       errorObject.character = matches[2];
13534     } else {
13535       matches = (errorObject['stacktrace'] || '').match(/Error thrown at line (\d+)/);
13536       if (matches){
13537         errorObject.line = matches[1];
13538       }
13539     }
13540   }
13541
13542   if (window.onerror) {
13543     // window.onerror is still needed to get stack in IE, so we need to re-throw the error to that.
13544     g.errorCatcher.lastDomWrapperError_ = errorObject;
13545     throw caughtException;
13546   } else {
13547     g.errorCatcher.reportException(errorObject);
13548   }
13549 };
13550
13551
13552 /**
13553  * @param {Function} opt_topFunction The function at the top of the stack; if omitted, the caller of makeStacktrace is
13554  *     used.
13555  * @return {string} A string showing the stack of functions and arguments.
13556  */
13557 g.errorCatcher.getStacktrace = function(opt_topFunction) {
13558   var stacktrace = '';
13559   var func = opt_topFunction || arguments.callee.caller;
13560   var used = [];
13561   var length = 0;
13562   stacktraceLoop: do {
13563     stacktrace += g.errorCatcher.getFunctionName(func) + g.errorCatcher.getFunctionArgumentsString(func) + '\n';
13564     used.push(func);
13565     try {
13566       func = func.caller;
13567       for (var i = 0; i < used.length; i++) {
13568         if (used[i] == func) {
13569           stacktrace += g.errorCatcher.getFunctionName(func) + '(???)\n(...)\n';
13570           break stacktraceLoop;
13571         }
13572       }
13573     } catch(exception) {
13574       stacktrace += '(???' + exception.message + ')\n';
13575       break stacktraceLoop;
13576     }
13577     if (length > 50) {
13578       stacktrace += '(...)\n';
13579     }
13580   } while (func);
13581   return stacktrace;
13582 };
13583
13584
13585 /**
13586  * @param {string} string The string to shorten.
13587  * @param {number} maxLength The maximum length of the new string.
13588  * @return {string} The string, shortened if it exceeds maxLength.
13589  */
13590 g.errorCatcher.shortenString = function(string, maxLength) {
13591   if (string.length > maxLength) {
13592     string = string.substr(0, maxLength) + '...';
13593   }
13594   return string;
13595 };
13596
13597
13598 /**
13599  * @param {Function} func The function to get the name of.
13600  * @return {string} The name of the function, or a snippet of the function's source code if it is an anonymous function.
13601  */
13602 g.errorCatcher.getFunctionName = function(func) {
13603   var name;
13604   try {
13605     if ('name' in Function.prototype && func.name) {
13606       name = func.name;
13607     } else {
13608       var funcStr = func.toString();
13609       var matches = /function ([^\(]+)/.exec(funcStr);
13610       name = matches && matches[1] || '[anonymous function: ' + g.errorCatcher.shortenString(func.toString(), 90) + ']';
13611     }
13612   } catch(exception) {
13613     name = '[inaccessible function]'
13614   }
13615   return name;
13616 };
13617
13618
13619 /**
13620  * @param func The function to get a string describing the arguments for. Must be in the current callstack.
13621  * @return {string} A string of the arguments passed to the function.
13622  */
13623 g.errorCatcher.getFunctionArgumentsString = function(func) {
13624   var argsStrings = [];
13625   try {
13626     var args = func.arguments;
13627     if (args) {
13628       for (var i = 0, length = args.length; i < length; i++) {
13629         argsStrings.push(g.errorCatcher.stringify(args[i]));
13630       }
13631     }
13632   } catch(exception) {
13633     argsStrings.push('...?');
13634   }
13635   return '(' + argsStrings.join(',') + ')';
13636 };
13637
13638
13639 /**
13640  * Converts objects and primitives to strings describing them. String inputs are redacted.
13641  * @param {*} thing The object or primitive to describe.
13642  * @return {string} String describing the input.
13643  */
13644 g.errorCatcher.stringify = function(thing) {
13645   var string = '[???]';
13646   try {
13647     var type = typeof thing;
13648     string = '[' + type + '?]';
13649     switch (type) {
13650       case 'undefined':
13651           string = 'undefined';
13652           break;
13653       case 'number':
13654       case 'boolean':
13655           string = thing.toString();
13656           break;
13657       case 'object':
13658           if (thing == null) {
13659             string = 'null';
13660             break;
13661           }
13662           if (thing instanceof Date) {
13663             string = 'new Date("' + thing.toString() + '")';
13664             break;
13665           }
13666           var toStringValue = thing.toString();
13667           if (/^\[[a-z ]*\]$/i.test(toStringValue)) {
13668             string = toStringValue;
13669             break;
13670           }
13671           if (typeof thing.length == 'number') {
13672             string = '[arraylike object, length = ' + thing.length + ']';
13673             break;
13674           }
13675           string = '[object]';
13676           break;
13677       case 'string':
13678           string = '"' + g.errorCatcher.redactString(thing) + '"';
13679           break;
13680       case 'function':
13681           string = '/* function */ ' + g.errorCatcher.getFunctionName(thing);
13682           break;
13683       default:
13684           string = '[' + type + '???]';
13685           break;
13686     }
13687   } catch(exception) { }
13688   return string;
13689 };
13690
13691
13692 /**
13693  * Finds quoted strings in a Firefox stacktrace and replaces them with redacted versions. Handles pesky escaped quotes
13694  * too. This relies on Firefox's specific stringification/escaping behavior and might not work as consistently in other
13695  * browsers.
13696  * @param {string} stacktraceStr The stacktrace to redact strings from.
13697  * @return {string} The stacktrace, with strings redacted.
13698  */
13699 g.errorCatcher.redactFirefoxStacktraceStrings = function(stacktraceStr) {
13700   if (!/\"/.test(stacktraceStr)) {
13701     return stacktraceStr;
13702   }
13703   // We can safely use new ecmascript array methods because this code only runs in Firefox.
13704   return stacktraceStr.split('\n').map(function(stacktraceLine) {
13705     var quoteLocations = [];
13706     var index = 0;
13707     do {
13708       index = (stacktraceLine.indexOf('"', index + 1));
13709       if (index != -1) {
13710         quoteLocations.push(index);
13711       }
13712     } while (index != -1);
13713     quoteLocations = quoteLocations.filter(function(quoteLocation) {
13714       var backslashCount = 0, index = quoteLocation;
13715       while (index--) {
13716         if (stacktraceLine.charAt(index) != '\\') {
13717           break;
13718         }
13719         backslashCount = backslashCount + 1;
13720       }
13721       // If a quotation mark is preceded by a non-even number of backslashes, it is escaped. Otherwise, only the
13722       // backslashes are escaped.
13723       // \"    escaped quote
13724       // \\"   escaped backslash, unescaped quote
13725       // \\\"  escaped backslash, escaped quote
13726       // (etc)
13727       return (backslashCount % 2 == 0);
13728     });
13729     if (quoteLocations.length % 2 == 1) {
13730       quoteLocations.push(stacktraceLine.length);
13731     }
13732     for (var i = quoteLocations.length - 1; i > 0; i -= 2) {
13733       stacktraceLine = stacktraceLine.substr(0, quoteLocations[i - 1] + 1) +
13734           g.errorCatcher.redactString(stacktraceLine.substring(quoteLocations[i - 1] + 1, quoteLocations[i])) +
13735           stacktraceLine.substr(quoteLocations[i]);
13736     }
13737     return stacktraceLine;
13738   }).join('\n');
13739 };
13740
13741
13742 /**
13743  * Redacts a string for user privacy.
13744  * @param {string} str The string to redact.
13745  * @return {string} The redacted string.
13746  */
13747 g.errorCatcher.redactString = function(str) {
13748   return '[string redacted]';
13749   // This commented out alternative attempts to at least make certain types of string (HTML, for example) maintain a
13750   // recognizable pattern.
13751   // return g.errorCatcher.shortenString(str.replace(/[a-z]/g, 'x').replace(/[A-Z]/g, 'X').replace(/[0-9]/g, '#').replace(
13752   //    /[^\\\s\[\]<>xX\"\'\(\)\.\,\?\!\#\=\:\;\&\|\@\_\-]/g, '*'), 150).replace(/\r/g, '').replace(/\n/g, '\\n');
13753 };
13754
13755 // g.errorCatcher can cause problems with debuggers (it breaks the Firebug console, for example), so it should be
13756 // disabled in development environments. This if statements g.errorCatcher if you're using
13757 if (!/dev/.test(window.location.host)) {
13758   g.errorCatcher(function(errorObj) {
13759     var key = '27461631-f992-4f72-b94d-b98996ef1a53';
13760     var host = 'https://logs.loggly.com';
13761     castor = new loggly({url: host+'/inputs/'+key+'?rt=1', level: 'log'});
13762     castor.error(JSON.stringify({host: window.location.host, error: errorObj}));
13763   }, function(str) {
13764     // this is the URL redaction function. this one just removes ?q= paramter values, but you should adapt this to your own application if needed.
13765     return str.replace(/([\#\?\&][Qq]\=)[^\=\&\#\s]*/g, '$1[redacted]');
13766   });
13767 }
13768
13769 /*
13770  * Copyright 2010 Matthew Eernisse (mde@fleegix.org)
13771  * and Open Source Applications Foundation
13772  *
13773  * Licensed under the Apache License, Version 2.0 (the "License");
13774  * you may not use this file except in compliance with the License.
13775  * You may obtain a copy of the License at
13776  *
13777  *   http://www.apache.org/licenses/LICENSE-2.0
13778  *
13779  * Unless required by applicable law or agreed to in writing, software
13780  * distributed under the License is distributed on an "AS IS" BASIS,
13781  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13782  * See the License for the specific language governing permissions and
13783  * limitations under the License.
13784  *
13785  * Credits: Ideas included from incomplete JS implementation of Olson
13786  * parser, "XMLDAte" by Philippe Goetz (philippe.goetz@wanadoo.fr)
13787  *
13788  * Contributions:
13789  * Jan Niehusmann
13790  * Ricky Romero
13791  * Preston Hunt (prestonhunt@gmail.com),
13792  * Dov. B Katz (dov.katz@morganstanley.com),
13793  * Peter Bergström (pbergstr@mac.com)
13794 */
13795
13796 if (typeof timezoneJS == 'undefined') { timezoneJS = {}; }
13797
13798 timezoneJS.Date = function () {
13799   var args = Array.prototype.slice.apply(arguments);
13800   var t = null;
13801   var dt = null;
13802   var tz = null;
13803   var utc = false;
13804
13805   // No args -- create a floating date based on the current local offset
13806   if (args.length === 0) {
13807     dt = new Date();
13808   }
13809   // Date string or timestamp -- assumes floating
13810   else if (args.length == 1) {
13811     dt = new Date(args[0]);
13812   }
13813   // year, month, [date,] [hours,] [minutes,] [seconds,] [milliseconds,] [tzId,] [utc]
13814   else {
13815     t = args[args.length-1];
13816     // Last arg is utc
13817     if (typeof t == 'boolean') {
13818       utc = args.pop();
13819       tz = args.pop();
13820     }
13821     // Last arg is tzId
13822     else if (typeof t == 'string') {
13823       tz = args.pop();
13824       if (tz == 'Etc/UTC' || tz == 'Etc/GMT') {
13825         utc = true;
13826       }
13827     }
13828
13829     // Date string (e.g., '12/27/2006')
13830     t = args[args.length-1];
13831     if (typeof t == 'string') {
13832       dt = new Date(args[0]);
13833     }
13834     // Date part numbers
13835     else {
13836       var a = [];
13837       for (var i = 0; i < 8; i++) {
13838         a[i] = args[i] || 0;
13839       }
13840       dt = new Date(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]);
13841     }
13842   }
13843   this._useCache = false;
13844   this._tzInfo = {};
13845   this._tzAbbr = '';
13846   this._day = 0;
13847   this.year = 0;
13848   this.month = 0;
13849   this.date = 0;
13850   this.hours= 0;
13851   this.minutes = 0;
13852   this.seconds = 0;
13853   this.milliseconds = 0;
13854   this.timezone = tz || null;
13855   this.utc = utc || false;
13856   this.setFromDateObjProxy(dt);
13857 };
13858
13859 timezoneJS.Date.prototype = {
13860   getDate: function () { return this.date; },
13861   getDay: function () { return this._day; },
13862   getFullYear: function () { return this.year; },
13863   getMonth: function () { return this.month; },
13864   getYear: function () { return this.year; },
13865   getHours: function () {
13866     return this.hours;
13867   },
13868   getMilliseconds: function () {
13869     return this.milliseconds;
13870   },
13871   getMinutes: function () {
13872     return this.minutes;
13873   },
13874   getSeconds: function () {
13875     return this.seconds;
13876   },
13877   getTime: function () {
13878     var dt = Date.UTC(this.year, this.month, this.date,
13879       this.hours, this.minutes, this.seconds, this.milliseconds);
13880     return dt + (this.getTimezoneOffset()*60*1000);
13881   },
13882   getTimezone: function () {
13883     return this.timezone;
13884   },
13885   getTimezoneOffset: function () {
13886     var info = this.getTimezoneInfo();
13887     return info.tzOffset;
13888   },
13889   getTimezoneAbbreviation: function () {
13890     var info = this.getTimezoneInfo();
13891     return info.tzAbbr;
13892   },
13893   getTimezoneInfo: function () {
13894     var res;
13895     if (this.utc) {
13896       res = { tzOffset: 0,
13897         tzAbbr: 'UTC' };
13898     }
13899     else {
13900       if (this._useCache) {
13901         res = this._tzInfo;
13902       }
13903       else {
13904         if (this.timezone) {
13905           var dt = new Date(Date.UTC(this.year, this.month, this.date,
13906             this.hours, this.minutes, this.seconds, this.milliseconds));
13907           var tz = this.timezone;
13908           res = timezoneJS.timezone.getTzInfo(dt, tz);
13909         }
13910         // Floating -- use local offset
13911         else {
13912           res = { tzOffset: this.getLocalOffset(),
13913             tzAbbr: null };
13914         }
13915         this._tzInfo = res;
13916         this._useCache = true;
13917       }
13918     }
13919     return res;
13920   },
13921   getUTCDate: function () {
13922     return this.getUTCDateProxy().getUTCDate();
13923   },
13924   getUTCDay: function () {
13925     return this.getUTCDateProxy().getUTCDay();
13926   },
13927   getUTCFullYear: function () {
13928     return this.getUTCDateProxy().getUTCFullYear();
13929   },
13930   getUTCHours: function () {
13931     return this.getUTCDateProxy().getUTCHours();
13932   },
13933   getUTCMilliseconds: function () {
13934     return this.getUTCDateProxy().getUTCMilliseconds();
13935   },
13936   getUTCMinutes: function () {
13937     return this.getUTCDateProxy().getUTCMinutes();
13938   },
13939   getUTCMonth: function () {
13940     return this.getUTCDateProxy().getUTCMonth();
13941   },
13942   getUTCSeconds: function () {
13943     return this.getUTCDateProxy().getUTCSeconds();
13944   },
13945   setDate: function (n) {
13946     this.setAttribute('date', n);
13947   },
13948   setFullYear: function (n) {
13949     this.setAttribute('year', n);
13950   },
13951   setMonth: function (n) {
13952     this.setAttribute('month', n);
13953   },
13954   setYear: function (n) {
13955     this.setUTCAttribute('year', n);
13956   },
13957   setHours: function (n) {
13958     this.setAttribute('hours', n);
13959   },
13960   setMilliseconds: function (n) {
13961     this.setAttribute('milliseconds', n);
13962   },
13963   setMinutes: function (n) {
13964     this.setAttribute('minutes', n);
13965   },
13966   setSeconds: function (n) {
13967     this.setAttribute('seconds', n);
13968   },
13969   setTime: function (n) {
13970     if (isNaN(n)) { throw new Error('Units must be a number.'); }
13971     var dt = new Date(0);
13972     dt.setUTCMilliseconds(n - (this.getTimezoneOffset()*60*1000));
13973     this.setFromDateObjProxy(dt, true);
13974   },
13975   setUTCDate: function (n) {
13976     this.setUTCAttribute('date', n);
13977   },
13978   setUTCFullYear: function (n) {
13979     this.setUTCAttribute('year', n);
13980   },
13981   setUTCHours: function (n) {
13982     this.setUTCAttribute('hours', n);
13983   },
13984   setUTCMilliseconds: function (n) {
13985     this.setUTCAttribute('milliseconds', n);
13986   },
13987   setUTCMinutes: function (n) {
13988     this.setUTCAttribute('minutes', n);
13989   },
13990   setUTCMonth: function (n) {
13991     this.setUTCAttribute('month', n);
13992   },
13993   setUTCSeconds: function (n) {
13994     this.setUTCAttribute('seconds', n);
13995   },
13996   toGMTString: function () {},
13997   toLocaleString: function () {},
13998   toLocaleDateString: function () {},
13999   toLocaleTimeString: function () {},
14000   toSource: function () {},
14001   toString: function () {
14002     // Get a quick looky at what's in there
14003     var str = this.getFullYear() + '-' + (this.getMonth()+1) + '-' + this.getDate();
14004     var hou = this.getHours() || 12;
14005     hou = String(hou);
14006     var min = String(this.getMinutes());
14007     if (min.length == 1) { min = '0' + min; }
14008     var sec = String(this.getSeconds());
14009     if (sec.length == 1) { sec = '0' + sec; }
14010     str += ' ' + hou;
14011     str += ':' + min;
14012     str += ':' + sec;
14013     return str;
14014   },
14015   toUTCString: function () {},
14016   valueOf: function () {
14017     return this.getTime();
14018   },
14019   clone: function () {
14020     return new timezoneJS.Date(this.year, this.month, this.date,
14021       this.hours, this.minutes, this.seconds, this.milliseconds,
14022       this.timezone);
14023   },
14024   setFromDateObjProxy: function (dt, fromUTC) {
14025     this.year = fromUTC ? dt.getUTCFullYear() : dt.getFullYear();
14026     this.month = fromUTC ? dt.getUTCMonth() : dt.getMonth();
14027     this.date = fromUTC ? dt.getUTCDate() : dt.getDate();
14028     this.hours = fromUTC ? dt.getUTCHours() : dt.getHours();
14029     this.minutes = fromUTC ? dt.getUTCMinutes() : dt.getMinutes();
14030     this.seconds = fromUTC ? dt.getUTCSeconds() : dt.getSeconds();
14031     this.milliseconds = fromUTC ? dt.getUTCMilliseconds() : dt.getMilliseconds();
14032     this._day = fromUTC ? dt.getUTCDay() : dt.getDay();
14033     this._useCache = false;
14034   },
14035   getUTCDateProxy: function () {
14036     var dt = new Date(Date.UTC(this.year, this.month, this.date,
14037       this.hours, this.minutes, this.seconds, this.milliseconds));
14038     dt.setUTCMinutes(dt.getUTCMinutes() + this.getTimezoneOffset());
14039     return dt;
14040   },
14041   setAttribute: function (unit, n) {
14042     if (isNaN(n)) { throw new Error('Units must be a number.'); }
14043     var dt = new Date(this.year, this.month, this.date,
14044       this.hours, this.minutes, this.seconds, this.milliseconds);
14045     var meth = unit == 'year' ? 'FullYear' : unit.substr(0, 1).toUpperCase() +
14046       unit.substr(1);
14047     dt['set' + meth](n);
14048     this.setFromDateObjProxy(dt);
14049   },
14050   setUTCAttribute: function (unit, n) {
14051     if (isNaN(n)) { throw new Error('Units must be a number.'); }
14052     var meth = unit == 'year' ? 'FullYear' : unit.substr(0, 1).toUpperCase() +
14053       unit.substr(1);
14054     var dt = this.getUTCDateProxy();
14055     dt['setUTC' + meth](n);
14056     dt.setUTCMinutes(dt.getUTCMinutes() - this.getTimezoneOffset());
14057     this.setFromDateObjProxy(dt, true);
14058   },
14059   setTimezone: function (tz) {
14060     if (tz == 'Etc/UTC' || tz == 'Etc/GMT') {
14061       this.utc = true;
14062     } else {
14063       this.utc = false;
14064     }
14065     this.timezone = tz;
14066     this._useCache = false;
14067   },
14068   removeTimezone: function () {
14069     this.utc = false;
14070     this.timezone = null;
14071     this._useCache = false;
14072   },
14073   civilToJulianDayNumber: function (y, m, d) {
14074     var a;
14075     // Adjust for zero-based JS-style array
14076     m++;
14077     if (m > 12) {
14078       a = parseInt(m/12, 10);
14079       m = m % 12;
14080       y += a;
14081     }
14082     if (m <= 2) {
14083       y -= 1;
14084       m += 12;
14085     }
14086     a = Math.floor(y / 100);
14087     var b = 2 - a + Math.floor(a / 4);
14088     jDt = Math.floor(365.25 * (y + 4716)) +
14089       Math.floor(30.6001 * (m + 1)) +
14090       d + b - 1524;
14091     return jDt;
14092   },
14093   getLocalOffset: function () {
14094     var dt = this;
14095     var d = new Date(dt.getYear(), dt.getMonth(), dt.getDate(),
14096       dt.getHours(), dt.getMinutes(), dt.getSeconds());
14097     return d.getTimezoneOffset();
14098   },
14099   convertToTimezone: function(tz) {
14100     var dt = new Date();
14101     res = timezoneJS.timezone.getTzInfo(dt, tz);
14102     
14103     convert_offset = this.getTimezoneOffset() - res.tzOffset // offset in minutes
14104     converted_date = new timezoneJS.Date(this + convert_offset*60*1000)
14105     this.setFromDateObjProxy(converted_date, true)
14106     this.setTimezone(tz)
14107   }
14108 };
14109
14110 timezoneJS.timezone = new function() {
14111   var _this = this;
14112   var monthMap = { 'jan': 0, 'feb': 1, 'mar': 2, 'apr': 3,'may': 4, 'jun': 5, 'jul': 6, 'aug': 7, 'sep': 8, 'oct': 9, 'nov': 10, 'dec': 11 };
14113   var dayMap = {'sun': 0,'mon' :1, 'tue': 2, 'wed': 3, 'thu': 4, 'fri': 5, 'sat': 6 };
14114   var regionMap = {'EST':'northamerica','MST':'northamerica','HST':'northamerica','EST5EDT':'northamerica','CST6CDT':'northamerica','MST7MDT':'northamerica','PST8PDT':'northamerica','America':'northamerica','Pacific':'australasia','Atlantic':'europe','Africa':'africa','Indian':'africa','Antarctica':'antarctica','Asia':'asia','Australia':'australasia','Europe':'europe','WET':'europe','CET':'europe','MET':'europe','EET':'europe'};
14115   var regionExceptions = {'Pacific/Honolulu':'northamerica','Atlantic/Bermuda':'northamerica','Atlantic/Cape_Verde':'africa','Atlantic/St_Helena':'africa','Indian/Kerguelen':'antarctica','Indian/Chagos':'asia','Indian/Maldives':'asia','Indian/Christmas':'australasia','Indian/Cocos':'australasia','America/Danmarkshavn':'europe','America/Scoresbysund':'europe','America/Godthab':'europe','America/Thule':'europe','Asia/Yekaterinburg':'europe','Asia/Omsk':'europe','Asia/Novosibirsk':'europe','Asia/Krasnoyarsk':'europe','Asia/Irkutsk':'europe','Asia/Yakutsk':'europe','Asia/Vladivostok':'europe','Asia/Sakhalin':'europe','Asia/Magadan':'europe','Asia/Kamchatka':'europe','Asia/Anadyr':'europe','Africa/Ceuta':'europe','America/Argentina/Buenos_Aires':'southamerica','America/Argentina/Cordoba':'southamerica','America/Argentina/Tucuman':'southamerica','America/Argentina/La_Rioja':'southamerica','America/Argentina/San_Juan':'southamerica','America/Argentina/Jujuy':'southamerica','America/Argentina/Catamarca':'southamerica','America/Argentina/Mendoza':'southamerica','America/Argentina/Rio_Gallegos':'southamerica','America/Argentina/Ushuaia':'southamerica','America/Aruba':'southamerica','America/La_Paz':'southamerica','America/Noronha':'southamerica','America/Belem':'southamerica','America/Fortaleza':'southamerica','America/Recife':'southamerica','America/Araguaina':'southamerica','America/Maceio':'southamerica','America/Bahia':'southamerica','America/Sao_Paulo':'southamerica','America/Campo_Grande':'southamerica','America/Cuiaba':'southamerica','America/Porto_Velho':'southamerica','America/Boa_Vista':'southamerica','America/Manaus':'southamerica','America/Eirunepe':'southamerica','America/Rio_Branco':'southamerica','America/Santiago':'southamerica','Pacific/Easter':'southamerica','America/Bogota':'southamerica','America/Curacao':'southamerica','America/Guayaquil':'southamerica','Pacific/Galapagos':'southamerica','Atlantic/Stanley':'southamerica','America/Cayenne':'southamerica','America/Guyana':'southamerica','America/Asuncion':'southamerica','America/Lima':'southamerica','Atlantic/South_Georgia':'southamerica','America/Paramaribo':'southamerica','America/Port_of_Spain':'southamerica','America/Montevideo':'southamerica','America/Caracas':'southamerica'};
14116
14117   function invalidTZError(t) {
14118     throw new Error('Timezone "' + t + '" is either incorrect, or not loaded in the timezone registry.');
14119   }
14120   function getRegionForTimezone(tz) {
14121     var exc = regionExceptions[tz];
14122     var ret;
14123     if (exc) {
14124       return exc;
14125     }
14126     else {
14127       reg = tz.split('/')[0];
14128       ret = regionMap[reg];
14129       // If there's nothing listed in the main regions for
14130       // this TZ, check the 'backward' links
14131       if (!ret) {
14132         var link = _this.zones[tz];
14133         if (typeof link == 'string') {
14134           return getRegionForTimezone(link);
14135         }
14136       }
14137       return ret;
14138     }
14139   }
14140   function parseTimeString(str) {
14141     var pat = /(\d+)(?::0*(\d*))?(?::0*(\d*))?([wsugz])?$/;
14142     var hms = str.match(pat);
14143     hms[1] = parseInt(hms[1], 10);
14144     hms[2] = hms[2] ? parseInt(hms[2], 10) : 0;
14145     hms[3] = hms[3] ? parseInt(hms[3], 10) : 0;
14146     return hms;
14147   }
14148   function getZone(dt, tz) {
14149     var t = tz;
14150     var zoneList = _this.zones[t];
14151     // Follow links to get to an acutal zone
14152     while (typeof zoneList == "string") {
14153       t = zoneList;
14154       zoneList = _this.zones[t];
14155     }
14156     for(var i = 0; i < zoneList.length; i++) {
14157       var z = zoneList[i];
14158       if (!z[3]) { break; }
14159       var yea = parseInt(z[3], 10);
14160       var mon = 11;
14161       var dat = 31;
14162       if (z[4]) {
14163         mon = monthMap[z[4].substr(0, 3).toLowerCase()];
14164         dat = parseInt(z[5], 10);
14165       }
14166       var t = z[6] ? z[6] : '23:59:59';
14167       t = parseTimeString(t);
14168       var d = Date.UTC(yea, mon, dat, t[1], t[2], t[3]);
14169       if (dt.getTime() < d) { break; }
14170     }
14171     if (i == zoneList.length) { throw new Error('No Zone found for "' + timezone + '" on ' + dt); }
14172     return zoneList[i];
14173
14174   }
14175   function getBasicOffset(z) {
14176     var off = parseTimeString(z[0]);
14177     var adj = z[0].indexOf('-') == 0 ? -1 : 1
14178     off = adj * (((off[1] * 60 + off[2]) *60 + off[3]) * 1000);
14179     return -off/60/1000;
14180   }
14181
14182   // if isUTC is true, date is given in UTC, otherwise it's given
14183   // in local time (ie. date.getUTC*() returns local time components)
14184   function getRule( date, zone, isUTC ) {
14185     var ruleset = zone[1];
14186     var basicOffset = getBasicOffset( zone );
14187
14188     // Convert a date to UTC. Depending on the 'type' parameter, the date
14189     // parameter may be:
14190     // 'u', 'g', 'z': already UTC (no adjustment)
14191     // 's': standard time (adjust for time zone offset but not for DST)
14192     // 'w': wall clock time (adjust for both time zone and DST offset)
14193     //
14194     // DST adjustment is done using the rule given as third argument
14195     var convertDateToUTC = function( date, type, rule ) {
14196       var offset = 0;
14197
14198       if(type == 'u' || type == 'g' || type == 'z') { // UTC
14199           offset = 0;
14200       } else if(type == 's') { // Standard Time
14201           offset = basicOffset;
14202       } else if(type == 'w' || !type ) { // Wall Clock Time
14203           offset = getAdjustedOffset(basicOffset,rule);
14204       } else {
14205           throw("unknown type "+type);
14206       }
14207       offset *= 60*1000; // to millis
14208
14209       return new Date( date.getTime() + offset );
14210     }
14211
14212     // Step 1:  Find applicable rules for this year.
14213     // Step 2:  Sort the rules by effective date.
14214     // Step 3:  Check requested date to see if a rule has yet taken effect this year.  If not,
14215     // Step 4:  Get the rules for the previous year.  If there isn't an applicable rule for last year, then
14216     //      there probably is no current time offset since they seem to explicitly turn off the offset
14217     //      when someone stops observing DST.
14218     //      FIXME if this is not the case and we'll walk all the way back (ugh).
14219     // Step 5:  Sort the rules by effective date.
14220     // Step 6:  Apply the most recent rule before the current time.
14221
14222     var convertRuleToExactDateAndTime = function( yearAndRule, prevRule )
14223     {
14224       var year = yearAndRule[0];
14225       var rule = yearAndRule[1];
14226
14227       // Assume that the rule applies to the year of the given date.
14228       var months = {
14229         "Jan": 0, "Feb": 1, "Mar": 2, "Apr": 3, "May": 4, "Jun": 5,
14230         "Jul": 6, "Aug": 7, "Sep": 8, "Oct": 9, "Nov": 10, "Dec": 11
14231       };
14232
14233       var days = {
14234         "sun": 0, "mon": 1, "tue": 2, "wed": 3, "thu": 4, "fri": 5, "sat": 6
14235       }
14236
14237       var hms = parseTimeString( rule[ 5 ] );
14238       var effectiveDate;
14239
14240       if ( !isNaN( rule[ 4 ] ) ) // If we have a specific date, use that!
14241       {
14242         effectiveDate = new Date( Date.UTC( year, months[ rule[ 3 ] ], rule[ 4 ], hms[ 1 ], hms[ 2 ], hms[ 3 ], 0 ) );
14243       }
14244       else // Let's hunt for the date.
14245       {
14246         var targetDay,
14247           operator;
14248
14249         if ( rule[ 4 ].substr( 0, 4 ) === "last" ) // Example: lastThu
14250         {
14251           // Start at the last day of the month and work backward.
14252           effectiveDate = new Date( Date.UTC( year, months[ rule[ 3 ] ] + 1, 1, hms[ 1 ] - 24, hms[ 2 ], hms[ 3 ], 0 ) );
14253           targetDay = days[ rule[ 4 ].substr( 4, 3 ).toLowerCase( ) ];
14254           operator = "<=";
14255         }
14256         else // Example: Sun>=15
14257         {
14258           // Start at the specified date.
14259           effectiveDate = new Date( Date.UTC( year, months[ rule[ 3 ] ], rule[ 4 ].substr( 5 ), hms[ 1 ], hms[ 2 ], hms[ 3 ], 0 ) );
14260           targetDay = days[ rule[ 4 ].substr( 0, 3 ).toLowerCase( ) ];
14261           operator = rule[ 4 ].substr( 3, 2 );
14262         }
14263
14264         var ourDay = effectiveDate.getUTCDay( );
14265
14266         if ( operator === ">=" ) // Go forwards.
14267         {
14268           effectiveDate.setUTCDate( effectiveDate.getUTCDate( ) + ( targetDay - ourDay + ( ( targetDay < ourDay ) ? 7 : 0 ) ) );
14269         }
14270         else // Go backwards.  Looking for the last of a certain day, or operator is "<=" (less likely).
14271         {
14272           effectiveDate.setUTCDate( effectiveDate.getUTCDate( ) + ( targetDay - ourDay - ( ( targetDay > ourDay ) ? 7 : 0 ) ) );
14273         }
14274       }
14275
14276       // if previous rule is given, correct for the fact that the starting time of the current
14277       // rule may be specified in local time
14278       if(prevRule) {
14279         effectiveDate = convertDateToUTC(effectiveDate, hms[4], prevRule);
14280       }
14281
14282       return effectiveDate;
14283     }
14284
14285     var findApplicableRules = function( year, ruleset )
14286     {
14287       var applicableRules = [];
14288
14289       for ( var i in ruleset )
14290       {
14291         if ( Number( ruleset[ i ][ 0 ] ) <= year ) // Exclude future rules.
14292         {
14293           if (
14294             Number( ruleset[ i ][ 1 ] ) >= year                                            // Date is in a set range.
14295             || ( Number( ruleset[ i ][ 0 ] ) === year && ruleset[ i ][ 1 ] === "only" )    // Date is in an "only" year.
14296             || ruleset[ i ][ 1 ] === "max"                                                 // We're in a range from the start year to infinity.
14297           )
14298           {
14299             // It's completely okay to have any number of matches here.
14300             // Normally we should only see two, but that doesn't preclude other numbers of matches.
14301             // These matches are applicable to this year.
14302             applicableRules.push( [year, ruleset[ i ]] );
14303           }
14304         }
14305       }
14306
14307       return applicableRules;
14308     }
14309
14310     var compareDates = function( a, b, prev )
14311     {
14312       if ( a.constructor !== Date ) {
14313         a = convertRuleToExactDateAndTime( a, prev );
14314       } else if(prev) {
14315         a = convertDateToUTC(a, isUTC?'u':'w', prev);
14316       }
14317       if ( b.constructor !== Date ) {
14318         b = convertRuleToExactDateAndTime( b, prev );
14319       } else if(prev) {
14320         b = convertDateToUTC(b, isUTC?'u':'w', prev);
14321       }
14322
14323       a = Number( a );
14324       b = Number( b );
14325
14326       return a - b;
14327     }
14328
14329     var year = date.getUTCFullYear( );
14330     var applicableRules;
14331
14332     applicableRules = findApplicableRules( year, _this.rules[ ruleset ] );
14333     applicableRules.push( date );
14334     // While sorting, the time zone in which the rule starting time is specified
14335     // is ignored. This is ok as long as the timespan between two DST changes is
14336     // larger than the DST offset, which is probably always true.
14337     // As the given date may indeed be close to a DST change, it may get sorted
14338     // to a wrong position (off by one), which is corrected below.
14339     applicableRules.sort( compareDates );
14340
14341     if ( applicableRules.indexOf( date ) < 2 ) { // If there are not enough past DST rules...
14342       applicableRules = applicableRules.concat(findApplicableRules( year-1, _this.rules[ ruleset ] ));
14343       applicableRules.sort( compareDates );
14344     }
14345
14346     var pinpoint = applicableRules.indexOf( date );
14347     if ( pinpoint > 1 && compareDates( date, applicableRules[pinpoint-1], applicableRules[pinpoint-2][1] ) < 0 ) {
14348       // the previous rule does not really apply, take the one before that
14349       return applicableRules[ pinpoint - 2 ][1];
14350     } else if ( pinpoint > 0 && pinpoint < applicableRules.length - 1 && compareDates( date, applicableRules[pinpoint+1], applicableRules[pinpoint-1][1] ) > 0) {
14351       // the next rule does already apply, take that one
14352       return applicableRules[ pinpoint + 1 ][1];
14353     } else if ( pinpoint === 0 ) {
14354       // no applicable rule found in this and in previous year
14355       return null;
14356     } else {
14357       return applicableRules[ pinpoint - 1 ][1];
14358     }
14359   }
14360   function getAdjustedOffset(off, rule) {
14361     var save = rule[6];
14362     var t = parseTimeString(save);
14363     var adj = save.indexOf('-') == 0 ? -1 : 1;
14364     var ret = (adj*(((t[1] *60 + t[2]) * 60 + t[3]) * 1000));
14365     ret = ret/60/1000;
14366     ret -= off
14367     ret = -Math.ceil(ret);
14368     return ret;
14369   }
14370   function getAbbreviation(zone, rule) {
14371     var res;
14372     var base = zone[2];
14373     if (base.indexOf('%s') > -1) {
14374       var repl;
14375       if (rule) {
14376         repl = rule[7]=='-'?'':rule[7];
14377       }
14378       // FIXME: Right now just falling back to Standard --
14379       // apparently ought to use the last valid rule,
14380       // although in practice that always ought to be Standard
14381       else {
14382         repl = 'S';
14383       }
14384       res = base.replace('%s', repl);
14385     }
14386     else if (base.indexOf('/') > -1) {
14387       // chose one of two alternative strings
14388       var t = parseTimeString(rule[6]);
14389       var isDst = (t[1])||(t[2])||(t[3]);
14390       res = base.split("/",2)[isDst?1:0];
14391     } else {
14392       res = base;
14393     }
14394     return res;
14395   }
14396
14397   this.getTzInfo = function(dt, tz, isUTC) {
14398     var zone = getZone(dt, tz);
14399     var off = getBasicOffset(zone);
14400     // See if the offset needs adjustment
14401     var rule = getRule(dt, zone, isUTC);
14402     if (rule) {
14403       off = getAdjustedOffset(off, rule);
14404     }
14405     var abbr = getAbbreviation(zone, rule);
14406     return { tzOffset: off, tzAbbr: abbr };
14407   }
14408 }
14409
14410 // Timezone data for: northamerica,europe
14411 timezoneJS.timezone.zones = {"Europe/London":[["-0:01:15","-","LMT","1847","Dec","1","0:00s"],["0:00","GB-Eire","%s","1968","Oct","27"],["1:00","-","BST","1971","Oct","31","2:00u"],["0:00","GB-Eire","%s","1996"],["0:00","EU","GMT/BST"]],"Europe/Jersey":"Europe/London","Europe/Guernsey":"Europe/London","Europe/Isle_of_Man":"Europe/London","Europe/Dublin":[["-0:25:00","-","LMT","1880","Aug","2"],["-0:25:21","-","DMT","1916","May","21","2:00"],["-0:25:21","1:00","IST","1916","Oct","1","2:00s"],["0:00","GB-Eire","%s","1921","Dec","6",""],["0:00","GB-Eire","GMT/IST","1940","Feb","25","2:00"],["0:00","1:00","IST","1946","Oct","6","2:00"],["0:00","-","GMT","1947","Mar","16","2:00"],["0:00","1:00","IST","1947","Nov","2","2:00"],["0:00","-","GMT","1948","Apr","18","2:00"],["0:00","GB-Eire","GMT/IST","1968","Oct","27"],["1:00","-","IST","1971","Oct","31","2:00u"],["0:00","GB-Eire","GMT/IST","1996"],["0:00","EU","GMT/IST"]],"WET":[["0:00","EU","WE%sT"]],"CET":[["1:00","C-Eur","CE%sT"]],"MET":[["1:00","C-Eur","ME%sT"]],"EET":[["2:00","EU","EE%sT"]],"Europe/Tirane":[["1:19:20","-","LMT","1914"],["1:00","-","CET","1940","Jun","16"],["1:00","Albania","CE%sT","1984","Jul"],["1:00","EU","CE%sT"]],"Europe/Andorra":[["0:06:04","-","LMT","1901"],["0:00","-","WET","1946","Sep","30"],["1:00","-","CET","1985","Mar","31","2:00"],["1:00","EU","CE%sT"]],"Europe/Vienna":[["1:05:20","-","LMT","1893","Apr"],["1:00","C-Eur","CE%sT","1920"],["1:00","Austria","CE%sT","1940","Apr","1","2:00s"],["1:00","C-Eur","CE%sT","1945","Apr","2","2:00s"],["1:00","1:00","CEST","1945","Apr","12","2:00s"],["1:00","-","CET","1946"],["1:00","Austria","CE%sT","1981"],["1:00","EU","CE%sT"]],"Europe/Minsk":[["1:50:16","-","LMT","1880"],["1:50","-","MMT","1924","May","2",""],["2:00","-","EET","1930","Jun","21"],["3:00","-","MSK","1941","Jun","28"],["1:00","C-Eur","CE%sT","1944","Jul","3"],["3:00","Russia","MSK/MSD","1990"],["3:00","-","MSK","1991","Mar","31","2:00s"],["2:00","1:00","EEST","1991","Sep","29","2:00s"],["2:00","-","EET","1992","Mar","29","0:00s"],["2:00","1:00","EEST","1992","Sep","27","0:00s"],["2:00","Russia","EE%sT"]],"Europe/Brussels":[["0:17:30","-","LMT","1880"],["0:17:30","-","BMT","1892","May","1","12:00",""],["0:00","-","WET","1914","Nov","8"],["1:00","-","CET","1916","May","1","0:00"],["1:00","C-Eur","CE%sT","1918","Nov","11","11:00u"],["0:00","Belgium","WE%sT","1940","May","20","2:00s"],["1:00","C-Eur","CE%sT","1944","Sep","3"],["1:00","Belgium","CE%sT","1977"],["1:00","EU","CE%sT"]],"Europe/Sofia":[["1:33:16","-","LMT","1880"],["1:56:56","-","IMT","1894","Nov","30",""],["2:00","-","EET","1942","Nov","2","3:00"],["1:00","C-Eur","CE%sT","1945"],["1:00","-","CET","1945","Apr","2","3:00"],["2:00","-","EET","1979","Mar","31","23:00"],["2:00","Bulg","EE%sT","1982","Sep","26","2:00"],["2:00","C-Eur","EE%sT","1991"],["2:00","E-Eur","EE%sT","1997"],["2:00","EU","EE%sT"]],"Europe/Prague":[["0:57:44","-","LMT","1850"],["0:57:44","-","PMT","1891","Oct",""],["1:00","C-Eur","CE%sT","1944","Sep","17","2:00s"],["1:00","Czech","CE%sT","1979"],["1:00","EU","CE%sT"]],"Europe/Copenhagen":[["0:50:20","-","LMT","1890"],["0:50:20","-","CMT","1894","Jan","1",""],["1:00","Denmark","CE%sT","1942","Nov","2","2:00s"],["1:00","C-Eur","CE%sT","1945","Apr","2","2:00"],["1:00","Denmark","CE%sT","1980"],["1:00","EU","CE%sT"]],"Atlantic/Faroe":[["-0:27:04","-","LMT","1908","Jan","11",""],["0:00","-","WET","1981"],["0:00","EU","WE%sT"]],"America/Danmarkshavn":[["-1:14:40","-","LMT","1916","Jul","28"],["-3:00","-","WGT","1980","Apr","6","2:00"],["-3:00","EU","WG%sT","1996"],["0:00","-","GMT"]],"America/Scoresbysund":[["-1:27:52","-","LMT","1916","Jul","28",""],["-2:00","-","CGT","1980","Apr","6","2:00"],["-2:00","C-Eur","CG%sT","1981","Mar","29"],["-1:00","EU","EG%sT"]],"America/Godthab":[["-3:26:56","-","LMT","1916","Jul","28",""],["-3:00","-","WGT","1980","Apr","6","2:00"],["-3:00","EU","WG%sT"]],"America/Thule":[["-4:35:08","-","LMT","1916","Jul","28",""],["-4:00","Thule","A%sT"]],"Europe/Tallinn":[["1:39:00","-","LMT","1880"],["1:39:00","-","TMT","1918","Feb",""],["1:00","C-Eur","CE%sT","1919","Jul"],["1:39:00","-","TMT","1921","May"],["2:00","-","EET","1940","Aug","6"],["3:00","-","MSK","1941","Sep","15"],["1:00","C-Eur","CE%sT","1944","Sep","22"],["3:00","Russia","MSK/MSD","1989","Mar","26","2:00s"],["2:00","1:00","EEST","1989","Sep","24","2:00s"],["2:00","C-Eur","EE%sT","1998","Sep","22"],["2:00","EU","EE%sT","1999","Nov","1"],["2:00","-","EET","2002","Feb","21"],["2:00","EU","EE%sT"]],"Europe/Helsinki":[["1:39:52","-","LMT","1878","May","31"],["1:39:52","-","HMT","1921","May",""],["2:00","Finland","EE%sT","1983"],["2:00","EU","EE%sT"]],"Europe/Mariehamn":"Europe/Helsinki","Europe/Paris":[["0:09:21","-","LMT","1891","Mar","15","0:01"],["0:09:21","-","PMT","1911","Mar","11","0:01",""],["0:00","France","WE%sT","1940","Jun","14","23:00"],["1:00","C-Eur","CE%sT","1944","Aug","25"],["0:00","France","WE%sT","1945","Sep","16","3:00"],["1:00","France","CE%sT","1977"],["1:00","EU","CE%sT"]],"Europe/Berlin":[["0:53:28","-","LMT","1893","Apr"],["1:00","C-Eur","CE%sT","1945","May","24","2:00"],["1:00","SovietZone","CE%sT","1946"],["1:00","Germany","CE%sT","1980"],["1:00","EU","CE%sT"]],"Europe/Gibraltar":[["-0:21:24","-","LMT","1880","Aug","2","0:00s"],["0:00","GB-Eire","%s","1957","Apr","14","2:00"],["1:00","-","CET","1982"],["1:00","EU","CE%sT"]],"Europe/Athens":[["1:34:52","-","LMT","1895","Sep","14"],["1:34:52","-","AMT","1916","Jul","28","0:01",""],["2:00","Greece","EE%sT","1941","Apr","30"],["1:00","Greece","CE%sT","1944","Apr","4"],["2:00","Greece","EE%sT","1981"],[""],[""],["2:00","EU","EE%sT"]],"Europe/Budapest":[["1:16:20","-","LMT","1890","Oct"],["1:00","C-Eur","CE%sT","1918"],["1:00","Hungary","CE%sT","1941","Apr","6","2:00"],["1:00","C-Eur","CE%sT","1945"],["1:00","Hungary","CE%sT","1980","Sep","28","2:00s"],["1:00","EU","CE%sT"]],"Atlantic/Reykjavik":[["-1:27:24","-","LMT","1837"],["-1:27:48","-","RMT","1908",""],["-1:00","Iceland","IS%sT","1968","Apr","7","1:00s"],["0:00","-","GMT"]],"Europe/Rome":[["0:49:56","-","LMT","1866","Sep","22"],["0:49:56","-","RMT","1893","Nov","1","0:00s",""],["1:00","Italy","CE%sT","1942","Nov","2","2:00s"],["1:00","C-Eur","CE%sT","1944","Jul"],["1:00","Italy","CE%sT","1980"],["1:00","EU","CE%sT"]],"Europe/Vatican":"Europe/Rome","Europe/San_Marino":"Europe/Rome","Europe/Riga":[["1:36:24","-","LMT","1880"],["1:36:24","-","RMT","1918","Apr","15","2:00",""],["1:36:24","1:00","LST","1918","Sep","16","3:00",""],["1:36:24","-","RMT","1919","Apr","1","2:00"],["1:36:24","1:00","LST","1919","May","22","3:00"],["1:36:24","-","RMT","1926","May","11"],["2:00","-","EET","1940","Aug","5"],["3:00","-","MSK","1941","Jul"],["1:00","C-Eur","CE%sT","1944","Oct","13"],["3:00","Russia","MSK/MSD","1989","Mar","lastSun","2:00s"],["2:00","1:00","EEST","1989","Sep","lastSun","2:00s"],["2:00","Latvia","EE%sT","1997","Jan","21"],["2:00","EU","EE%sT","2000","Feb","29"],["2:00","-","EET","2001","Jan","2"],["2:00","EU","EE%sT"]],"Europe/Vaduz":[["0:38:04","-","LMT","1894","Jun"],["1:00","-","CET","1981"],["1:00","EU","CE%sT"]],"Europe/Vilnius":[["1:41:16","-","LMT","1880"],["1:24:00","-","WMT","1917",""],["1:35:36","-","KMT","1919","Oct","10",""],["1:00","-","CET","1920","Jul","12"],["2:00","-","EET","1920","Oct","9"],["1:00","-","CET","1940","Aug","3"],["3:00","-","MSK","1941","Jun","24"],["1:00","C-Eur","CE%sT","1944","Aug"],["3:00","Russia","MSK/MSD","1991","Mar","31","2:00s"],["2:00","1:00","EEST","1991","Sep","29","2:00s"],["2:00","C-Eur","EE%sT","1998"],["2:00","-","EET","1998","Mar","29","1:00u"],["1:00","EU","CE%sT","1999","Oct","31","1:00u"],["2:00","-","EET","2003","Jan","1"],["2:00","EU","EE%sT"]],"Europe/Luxembourg":[["0:24:36","-","LMT","1904","Jun"],["1:00","Lux","CE%sT","1918","Nov","25"],["0:00","Lux","WE%sT","1929","Oct","6","2:00s"],["0:00","Belgium","WE%sT","1940","May","14","3:00"],["1:00","C-Eur","WE%sT","1944","Sep","18","3:00"],["1:00","Belgium","CE%sT","1977"],["1:00","EU","CE%sT"]],"Europe/Malta":[["0:58:04","-","LMT","1893","Nov","2","0:00s",""],["1:00","Italy","CE%sT","1942","Nov","2","2:00s"],["1:00","C-Eur","CE%sT","1945","Apr","2","2:00s"],["1:00","Italy","CE%sT","1973","Mar","31"],["1:00","Malta","CE%sT","1981"],["1:00","EU","CE%sT"]],"Europe/Chisinau":[["1:55:20","-","LMT","1880"],["1:55","-","CMT","1918","Feb","15",""],["1:44:24","-","BMT","1931","Jul","24",""],["2:00","Romania","EE%sT","1940","Aug","15"],["2:00","1:00","EEST","1941","Jul","17"],["1:00","C-Eur","CE%sT","1944","Aug","24"],["3:00","Russia","MSK/MSD","1990"],["3:00","-","MSK","1990","May","6"],["2:00","-","EET","1991"],["2:00","Russia","EE%sT","1992"],["2:00","E-Eur","EE%sT","1997"],["2:00","EU","EE%sT"]],"Europe/Monaco":[["0:29:32","-","LMT","1891","Mar","15"],["0:09:21","-","PMT","1911","Mar","11",""],["0:00","France","WE%sT","1945","Sep","16","3:00"],["1:00","France","CE%sT","1977"],["1:00","EU","CE%sT"]],"Europe/Amsterdam":[["0:19:32","-","LMT","1835"],["0:19:32","Neth","%s","1937","Jul","1"],["0:20","Neth","NE%sT","1940","May","16","0:00",""],["1:00","C-Eur","CE%sT","1945","Apr","2","2:00"],["1:00","Neth","CE%sT","1977"],["1:00","EU","CE%sT"]],"Europe/Oslo":[["0:43:00","-","LMT","1895","Jan","1"],["1:00","Norway","CE%sT","1940","Aug","10","23:00"],["1:00","C-Eur","CE%sT","1945","Apr","2","2:00"],["1:00","Norway","CE%sT","1980"],["1:00","EU","CE%sT"]],"Arctic/Longyearbyen":"Europe/Oslo","Europe/Warsaw":[["1:24:00","-","LMT","1880"],["1:24:00","-","WMT","1915","Aug","5",""],["1:00","C-Eur","CE%sT","1918","Sep","16","3:00"],["2:00","Poland","EE%sT","1922","Jun"],["1:00","Poland","CE%sT","1940","Jun","23","2:00"],["1:00","C-Eur","CE%sT","1944","Oct"],["1:00","Poland","CE%sT","1977"],["1:00","W-Eur","CE%sT","1988"],["1:00","EU","CE%sT"]],"Europe/Lisbon":[["-0:36:32","-","LMT","1884"],["-0:36:32","-","LMT","1912","Jan","1",""],["0:00","Port","WE%sT","1966","Apr","3","2:00"],["1:00","-","CET","1976","Sep","26","1:00"],["0:00","Port","WE%sT","1983","Sep","25","1:00s"],["0:00","W-Eur","WE%sT","1992","Sep","27","1:00s"],["1:00","EU","CE%sT","1996","Mar","31","1:00u"],["0:00","EU","WE%sT"]],"Atlantic/Azores":[["-1:42:40","-","LMT","1884",""],["-1:54:32","-","HMT","1911","May","24",""],["-2:00","Port","AZO%sT","1966","Apr","3","2:00",""],["-1:00","Port","AZO%sT","1983","Sep","25","1:00s"],["-1:00","W-Eur","AZO%sT","1992","Sep","27","1:00s"],["0:00","EU","WE%sT","1993","Mar","28","1:00u"],["-1:00","EU","AZO%sT"]],"Atlantic/Madeira":[["-1:07:36","-","LMT","1884",""],["-1:07:36","-","FMT","1911","May","24",""],["-1:00","Port","MAD%sT","1966","Apr","3","2:00",""],["0:00","Port","WE%sT","1983","Sep","25","1:00s"],["0:00","EU","WE%sT"]],"Europe/Bucharest":[["1:44:24","-","LMT","1891","Oct"],["1:44:24","-","BMT","1931","Jul","24",""],["2:00","Romania","EE%sT","1981","Mar","29","2:00s"],["2:00","C-Eur","EE%sT","1991"],["2:00","Romania","EE%sT","1994"],["2:00","E-Eur","EE%sT","1997"],["2:00","EU","EE%sT"]],"Europe/Kaliningrad":[["1:22:00","-","LMT","1893","Apr"],["1:00","C-Eur","CE%sT","1945"],["2:00","Poland","CE%sT","1946"],["3:00","Russia","MSK/MSD","1991","Mar","31","2:00s"],["2:00","Russia","EE%sT","2011","Mar","27","2:00s"],["3:00","-","EET"]],"Europe/Moscow":[["2:30:20","-","LMT","1880"],["2:30","-","MMT","1916","Jul","3",""],["2:30:48","Russia","%s","1919","Jul","1","2:00"],["3:00","Russia","MSK/MSD","1922","Oct"],["2:00","-","EET","1930","Jun","21"],["3:00","Russia","MSK/MSD","1991","Mar","31","2:00s"],["2:00","Russia","EE%sT","1992","Jan","19","2:00s"],["3:00","Russia","MSK/MSD","2011","Mar","27","2:00s"],["4:00","-","MSK"]],"Europe/Volgograd":[["2:57:40","-","LMT","1920","Jan","3"],["3:00","-","TSAT","1925","Apr","6",""],["3:00","-","STAT","1930","Jun","21",""],["4:00","-","STAT","1961","Nov","11"],["4:00","Russia","VOL%sT","1989","Mar","26","2:00s",""],["3:00","Russia","VOL%sT","1991","Mar","31","2:00s"],["4:00","-","VOLT","1992","Mar","29","2:00s"],["3:00","Russia","VOL%sT","2011","Mar","27","2:00s"],["4:00","-","VOLT"]],"Europe/Samara":[["3:20:36","-","LMT","1919","Jul","1","2:00"],["3:00","-","SAMT","1930","Jun","21"],["4:00","-","SAMT","1935","Jan","27"],["4:00","Russia","KUY%sT","1989","Mar","26","2:00s",""],["3:00","Russia","KUY%sT","1991","Mar","31","2:00s"],["2:00","Russia","KUY%sT","1991","Sep","29","2:00s"],["3:00","-","KUYT","1991","Oct","20","3:00"],["4:00","Russia","SAM%sT","2010","Mar","28","2:00s",""],["3:00","Russia","SAM%sT","2011","Mar","27","2:00s"],["4:00","-","SAMT"]],"Asia/Yekaterinburg":[["4:02:24","-","LMT","1919","Jul","15","4:00"],["4:00","-","SVET","1930","Jun","21",""],["5:00","Russia","SVE%sT","1991","Mar","31","2:00s"],["4:00","Russia","SVE%sT","1992","Jan","19","2:00s"],["5:00","Russia","YEK%sT","2011","Mar","27","2:00s"],["6:00","-","YEKT",""]],"Asia/Omsk":[["4:53:36","-","LMT","1919","Nov","14"],["5:00","-","OMST","1930","Jun","21",""],["6:00","Russia","OMS%sT","1991","Mar","31","2:00s"],["5:00","Russia","OMS%sT","1992","Jan","19","2:00s"],["6:00","Russia","OMS%sT","2011","Mar","27","2:00s"],["7:00","-","OMST"]],"Asia/Novosibirsk":[["5:31:40","-","LMT","1919","Dec","14","6:00"],["6:00","-","NOVT","1930","Jun","21",""],["7:00","Russia","NOV%sT","1991","Mar","31","2:00s"],["6:00","Russia","NOV%sT","1992","Jan","19","2:00s"],["7:00","Russia","NOV%sT","1993","May","23",""],["6:00","Russia","NOV%sT","2011","Mar","27","2:00s"],["7:00","-","NOVT"]],"Asia/Novokuznetsk":[["5:48:48","-","NMT","1920","Jan","6"],["6:00","-","KRAT","1930","Jun","21",""],["7:00","Russia","KRA%sT","1991","Mar","31","2:00s"],["6:00","Russia","KRA%sT","1992","Jan","19","2:00s"],["7:00","Russia","KRA%sT","2010","Mar","28","2:00s"],["6:00","Russia","NOV%sT","2011","Mar","27","2:00s"],["7:00","-","NOVT",""]],"Asia/Krasnoyarsk":[["6:11:20","-","LMT","1920","Jan","6"],["6:00","-","KRAT","1930","Jun","21",""],["7:00","Russia","KRA%sT","1991","Mar","31","2:00s"],["6:00","Russia","KRA%sT","1992","Jan","19","2:00s"],["7:00","Russia","KRA%sT","2011","Mar","27","2:00s"],["8:00","-","KRAT"]],"Asia/Irkutsk":[["6:57:20","-","LMT","1880"],["6:57:20","-","IMT","1920","Jan","25",""],["7:00","-","IRKT","1930","Jun","21",""],["8:00","Russia","IRK%sT","1991","Mar","31","2:00s"],["7:00","Russia","IRK%sT","1992","Jan","19","2:00s"],["8:00","Russia","IRK%sT","2011","Mar","27","2:00s"],["9:00","-","IRKT"]],"Asia/Yakutsk":[["8:38:40","-","LMT","1919","Dec","15"],["8:00","-","YAKT","1930","Jun","21",""],["9:00","Russia","YAK%sT","1991","Mar","31","2:00s"],["8:00","Russia","YAK%sT","1992","Jan","19","2:00s"],["9:00","Russia","YAK%sT","2011","Mar","27","2:00s"],["10:00","-","YAKT"]],"Asia/Vladivostok":[["8:47:44","-","LMT","1922","Nov","15"],["9:00","-","VLAT","1930","Jun","21",""],["10:00","Russia","VLA%sT","1991","Mar","31","2:00s"],["9:00","Russia","VLA%sST","1992","Jan","19","2:00s"],["10:00","Russia","VLA%sT","2011","Mar","27","2:00s"],["11:00","-","VLAT"]],"Asia/Sakhalin":[["9:30:48","-","LMT","1905","Aug","23"],["9:00","-","CJT","1938"],["9:00","-","JST","1945","Aug","25"],["11:00","Russia","SAK%sT","1991","Mar","31","2:00s",""],["10:00","Russia","SAK%sT","1992","Jan","19","2:00s"],["11:00","Russia","SAK%sT","1997","Mar","lastSun","2:00s"],["10:00","Russia","SAK%sT","2011","Mar","27","2:00s"],["11:00","-","SAKT"]],"Asia/Magadan":[["10:03:12","-","LMT","1924","May","2"],["10:00","-","MAGT","1930","Jun","21",""],["11:00","Russia","MAG%sT","1991","Mar","31","2:00s"],["10:00","Russia","MAG%sT","1992","Jan","19","2:00s"],["11:00","Russia","MAG%sT","2011","Mar","27","2:00s"],["12:00","-","MAGT"]],"Asia/Kamchatka":[["10:34:36","-","LMT","1922","Nov","10"],["11:00","-","PETT","1930","Jun","21",""],["12:00","Russia","PET%sT","1991","Mar","31","2:00s"],["11:00","Russia","PET%sT","1992","Jan","19","2:00s"],["12:00","Russia","PET%sT","2010","Mar","28","2:00s"],["11:00","Russia","PET%sT","2011","Mar","27","2:00s"],["12:00","-","PETT"]],"Asia/Anadyr":[["11:49:56","-","LMT","1924","May","2"],["12:00","-","ANAT","1930","Jun","21",""],["13:00","Russia","ANA%sT","1982","Apr","1","0:00s"],["12:00","Russia","ANA%sT","1991","Mar","31","2:00s"],["11:00","Russia","ANA%sT","1992","Jan","19","2:00s"],["12:00","Russia","ANA%sT","2010","Mar","28","2:00s"],["11:00","Russia","ANA%sT","2011","Mar","27","2:00s"],["12:00","-","ANAT"]],"Europe/Belgrade":[["1:22:00","-","LMT","1884"],["1:00","-","CET","1941","Apr","18","23:00"],["1:00","C-Eur","CE%sT","1945"],["1:00","-","CET","1945","May","8","2:00s"],["1:00","1:00","CEST","1945","Sep","16","2:00s"],["1:00","-","CET","1982","Nov","27"],["1:00","EU","CE%sT"]],"Europe/Ljubljana":"Europe/Belgrade","Europe/Podgorica":"Europe/Belgrade","Europe/Sarajevo":"Europe/Belgrade","Europe/Skopje":"Europe/Belgrade","Europe/Zagreb":"Europe/Belgrade","Europe/Bratislava":"Europe/Prague","Europe/Madrid":[["-0:14:44","-","LMT","1901","Jan","1","0:00s"],["0:00","Spain","WE%sT","1946","Sep","30"],["1:00","Spain","CE%sT","1979"],["1:00","EU","CE%sT"]],"Africa/Ceuta":[["-0:21:16","-","LMT","1901"],["0:00","-","WET","1918","May","6","23:00"],["0:00","1:00","WEST","1918","Oct","7","23:00"],["0:00","-","WET","1924"],["0:00","Spain","WE%sT","1929"],["0:00","SpainAfrica","WE%sT","1984","Mar","16"],["1:00","-","CET","1986"],["1:00","EU","CE%sT"]],"Atlantic/Canary":[["-1:01:36","-","LMT","1922","Mar",""],["-1:00","-","CANT","1946","Sep","30","1:00",""],["0:00","-","WET","1980","Apr","6","0:00s"],["0:00","1:00","WEST","1980","Sep","28","0:00s"],["0:00","EU","WE%sT"]],"Europe/Stockholm":[["1:12:12","-","LMT","1879","Jan","1"],["1:00:14","-","SET","1900","Jan","1",""],["1:00","-","CET","1916","May","14","23:00"],["1:00","1:00","CEST","1916","Oct","1","01:00"],["1:00","-","CET","1980"],["1:00","EU","CE%sT"]],"Europe/Zurich":[["0:34:08","-","LMT","1848","Sep","12"],["0:29:44","-","BMT","1894","Jun",""],["1:00","Swiss","CE%sT","1981"],["1:00","EU","CE%sT"]],"Europe/Istanbul":[["1:55:52","-","LMT","1880"],["1:56:56","-","IMT","1910","Oct",""],["2:00","Turkey","EE%sT","1978","Oct","15"],["3:00","Turkey","TR%sT","1985","Apr","20",""],["2:00","Turkey","EE%sT","2007"],["2:00","EU","EE%sT","2011","Mar","27","1:00u"],["2:00","-","EET","2011","Mar","28","1:00u"],["2:00","EU","EE%sT"]],"Asia/Istanbul":"Europe/Istanbul","Europe/Kiev":[["2:02:04","-","LMT","1880"],["2:02:04","-","KMT","1924","May","2",""],["2:00","-","EET","1930","Jun","21"],["3:00","-","MSK","1941","Sep","20"],["1:00","C-Eur","CE%sT","1943","Nov","6"],["3:00","Russia","MSK/MSD","1990"],["3:00","-","MSK","1990","Jul","1","2:00"],["2:00","-","EET","1992"],["2:00","E-Eur","EE%sT","1995"],["2:00","EU","EE%sT"]],"Europe/Uzhgorod":[["1:29:12","-","LMT","1890","Oct"],["1:00","-","CET","1940"],["1:00","C-Eur","CE%sT","1944","Oct"],["1:00","1:00","CEST","1944","Oct","26"],["1:00","-","CET","1945","Jun","29"],["3:00","Russia","MSK/MSD","1990"],["3:00","-","MSK","1990","Jul","1","2:00"],["1:00","-","CET","1991","Mar","31","3:00"],["2:00","-","EET","1992"],["2:00","E-Eur","EE%sT","1995"],["2:00","EU","EE%sT"]],"Europe/Zaporozhye":[["2:20:40","-","LMT","1880"],["2:20","-","CUT","1924","May","2",""],["2:00","-","EET","1930","Jun","21"],["3:00","-","MSK","1941","Aug","25"],["1:00","C-Eur","CE%sT","1943","Oct","25"],["3:00","Russia","MSK/MSD","1991","Mar","31","2:00"],["2:00","E-Eur","EE%sT","1995"],["2:00","EU","EE%sT"]],"Europe/Simferopol":[["2:16:24","-","LMT","1880"],["2:16","-","SMT","1924","May","2",""],["2:00","-","EET","1930","Jun","21"],["3:00","-","MSK","1941","Nov"],["1:00","C-Eur","CE%sT","1944","Apr","13"],["3:00","Russia","MSK/MSD","1990"],["3:00","-","MSK","1990","Jul","1","2:00"],["2:00","-","EET","1992"],["2:00","E-Eur","EE%sT","1994","May"],["3:00","E-Eur","MSK/MSD","1996","Mar","31","3:00s"],["3:00","1:00","MSD","1996","Oct","27","3:00s"],["3:00","Russia","MSK/MSD","1997"],["3:00","-","MSK","1997","Mar","lastSun","1:00u"],["2:00","EU","EE%sT"]],"EST":[["-5:00","-","EST"]],"MST":[["-7:00","-","MST"]],"HST":[["-10:00","-","HST"]],"EST5EDT":[["-5:00","US","E%sT"]],"CST6CDT":[["-6:00","US","C%sT"]],"MST7MDT":[["-7:00","US","M%sT"]],"PST8PDT":[["-8:00","US","P%sT"]],"America/New_York":[["-4:56:02","-","LMT","1883","Nov","18","12:03:58"],["-5:00","US","E%sT","1920"],["-5:00","NYC","E%sT","1942"],["-5:00","US","E%sT","1946"],["-5:00","NYC","E%sT","1967"],["-5:00","US","E%sT"]],"America/Chicago":[["-5:50:36","-","LMT","1883","Nov","18","12:09:24"],["-6:00","US","C%sT","1920"],["-6:00","Chicago","C%sT","1936","Mar","1","2:00"],["-5:00","-","EST","1936","Nov","15","2:00"],["-6:00","Chicago","C%sT","1942"],["-6:00","US","C%sT","1946"],["-6:00","Chicago","C%sT","1967"],["-6:00","US","C%sT"]],"America/North_Dakota/Center":[["-6:45:12","-","LMT","1883","Nov","18","12:14:48"],["-7:00","US","M%sT","1992","Oct","25","02:00"],["-6:00","US","C%sT"]],"America/North_Dakota/New_Salem":[["-6:45:39","-","LMT","1883","Nov","18","12:14:21"],["-7:00","US","M%sT","2003","Oct","26","02:00"],["-6:00","US","C%sT"]],"America/North_Dakota/Beulah":[["-6:47:07","-","LMT","1883","Nov","18","12:12:53"],["-7:00","US","M%sT","2010","Nov","7","2:00"],["-6:00","US","C%sT"]],"America/Denver":[["-6:59:56","-","LMT","1883","Nov","18","12:00:04"],["-7:00","US","M%sT","1920"],["-7:00","Denver","M%sT","1942"],["-7:00","US","M%sT","1946"],["-7:00","Denver","M%sT","1967"],["-7:00","US","M%sT"]],"America/Los_Angeles":[["-7:52:58","-","LMT","1883","Nov","18","12:07:02"],["-8:00","US","P%sT","1946"],["-8:00","CA","P%sT","1967"],["-8:00","US","P%sT"]],"America/Juneau":[["15:02:19","-","LMT","1867","Oct","18"],["-8:57:41","-","LMT","1900","Aug","20","12:00"],["-8:00","-","PST","1942"],["-8:00","US","P%sT","1946"],["-8:00","-","PST","1969"],["-8:00","US","P%sT","1980","Apr","27","2:00"],["-9:00","US","Y%sT","1980","Oct","26","2:00",""],["-8:00","US","P%sT","1983","Oct","30","2:00"],["-9:00","US","Y%sT","1983","Nov","30"],["-9:00","US","AK%sT"]],"America/Sitka":[["-14:58:47","-","LMT","1867","Oct","18"],["-9:01:13","-","LMT","1900","Aug","20","12:00"],["-8:00","-","PST","1942"],["-8:00","US","P%sT","1946"],["-8:00","-","PST","1969"],["-8:00","US","P%sT","1983","Oct","30","2:00"],["-9:00","US","Y%sT","1983","Nov","30"],["-9:00","US","AK%sT"]],"America/Metlakatla":[["15:13:42","-","LMT","1867","Oct","18"],["-8:46:18","-","LMT","1900","Aug","20","12:00"],["-8:00","-","PST","1942"],["-8:00","US","P%sT","1946"],["-8:00","-","PST","1969"],["-8:00","US","P%sT","1983","Oct","30","2:00"],["-8:00","US","MeST"]],"America/Yakutat":[["14:41:05","-","LMT","1867","Oct","18"],["-9:18:55","-","LMT","1900","Aug","20","12:00"],["-9:00","-","YST","1942"],["-9:00","US","Y%sT","1946"],["-9:00","-","YST","1969"],["-9:00","US","Y%sT","1983","Nov","30"],["-9:00","US","AK%sT"]],"America/Anchorage":[["14:00:24","-","LMT","1867","Oct","18"],["-9:59:36","-","LMT","1900","Aug","20","12:00"],["-10:00","-","CAT","1942"],["-10:00","US","CAT/CAWT","1945","Aug","14","23:00u"],["-10:00","US","CAT/CAPT","1946",""],["-10:00","-","CAT","1967","Apr"],["-10:00","-","AHST","1969"],["-10:00","US","AH%sT","1983","Oct","30","2:00"],["-9:00","US","Y%sT","1983","Nov","30"],["-9:00","US","AK%sT"]],"America/Nome":[["12:58:21","-","LMT","1867","Oct","18"],["-11:01:38","-","LMT","1900","Aug","20","12:00"],["-11:00","-","NST","1942"],["-11:00","US","N%sT","1946"],["-11:00","-","NST","1967","Apr"],["-11:00","-","BST","1969"],["-11:00","US","B%sT","1983","Oct","30","2:00"],["-9:00","US","Y%sT","1983","Nov","30"],["-9:00","US","AK%sT"]],"America/Adak":[["12:13:21","-","LMT","1867","Oct","18"],["-11:46:38","-","LMT","1900","Aug","20","12:00"],["-11:00","-","NST","1942"],["-11:00","US","N%sT","1946"],["-11:00","-","NST","1967","Apr"],["-11:00","-","BST","1969"],["-11:00","US","B%sT","1983","Oct","30","2:00"],["-10:00","US","AH%sT","1983","Nov","30"],["-10:00","US","HA%sT"]],"Pacific/Honolulu":[["-10:31:26","-","LMT","1896","Jan","13","12:00",""],["-10:30","-","HST","1933","Apr","30","2:00",""],["-10:30","1:00","HDT","1933","May","21","12:00",""],["-10:30","-","HST","1942","Feb","09","2:00",""],["-10:30","1:00","HDT","1945","Sep","30","2:00",""],["-10:30","US","H%sT","1947","Jun","8","2:00",""],["-10:00","-","HST"]],"America/Phoenix":[["-7:28:18","-","LMT","1883","Nov","18","11:31:42"],["-7:00","US","M%sT","1944","Jan","1","00:01"],["-7:00","-","MST","1944","Apr","1","00:01"],["-7:00","US","M%sT","1944","Oct","1","00:01"],["-7:00","-","MST","1967"],["-7:00","US","M%sT","1968","Mar","21"],["-7:00","-","MST"]],"America/Shiprock":"America/Denver","America/Boise":[["-7:44:49","-","LMT","1883","Nov","18","12:15:11"],["-8:00","US","P%sT","1923","May","13","2:00"],["-7:00","US","M%sT","1974"],["-7:00","-","MST","1974","Feb","3","2:00"],["-7:00","US","M%sT"]],"America/Indiana/Indianapolis":[["-5:44:38","-","LMT","1883","Nov","18","12:15:22"],["-6:00","US","C%sT","1920"],["-6:00","Indianapolis","C%sT","1942"],["-6:00","US","C%sT","1946"],["-6:00","Indianapolis","C%sT","1955","Apr","24","2:00"],["-5:00","-","EST","1957","Sep","29","2:00"],["-6:00","-","CST","1958","Apr","27","2:00"],["-5:00","-","EST","1969"],["-5:00","US","E%sT","1971"],["-5:00","-","EST","2006"],["-5:00","US","E%sT"]],"America/Indiana/Marengo":[["-5:45:23","-","LMT","1883","Nov","18","12:14:37"],["-6:00","US","C%sT","1951"],["-6:00","Marengo","C%sT","1961","Apr","30","2:00"],["-5:00","-","EST","1969"],["-5:00","US","E%sT","1974","Jan","6","2:00"],["-6:00","1:00","CDT","1974","Oct","27","2:00"],["-5:00","US","E%sT","1976"],["-5:00","-","EST","2006"],["-5:00","US","E%sT"]],"America/Indiana/Vincennes":[["-5:50:07","-","LMT","1883","Nov","18","12:09:53"],["-6:00","US","C%sT","1946"],["-6:00","Vincennes","C%sT","1964","Apr","26","2:00"],["-5:00","-","EST","1969"],["-5:00","US","E%sT","1971"],["-5:00","-","EST","2006","Apr","2","2:00"],["-6:00","US","C%sT","2007","Nov","4","2:00"],["-5:00","US","E%sT"]],"America/Indiana/Tell_City":[["-5:47:03","-","LMT","1883","Nov","18","12:12:57"],["-6:00","US","C%sT","1946"],["-6:00","Perry","C%sT","1964","Apr","26","2:00"],["-5:00","-","EST","1969"],["-5:00","US","E%sT","1971"],["-5:00","-","EST","2006","Apr","2","2:00"],["-6:00","US","C%sT"]],"America/Indiana/Petersburg":[["-5:49:07","-","LMT","1883","Nov","18","12:10:53"],["-6:00","US","C%sT","1955"],["-6:00","Pike","C%sT","1965","Apr","25","2:00"],["-5:00","-","EST","1966","Oct","30","2:00"],["-6:00","US","C%sT","1977","Oct","30","2:00"],["-5:00","-","EST","2006","Apr","2","2:00"],["-6:00","US","C%sT","2007","Nov","4","2:00"],["-5:00","US","E%sT"]],"America/Indiana/Knox":[["-5:46:30","-","LMT","1883","Nov","18","12:13:30"],["-6:00","US","C%sT","1947"],["-6:00","Starke","C%sT","1962","Apr","29","2:00"],["-5:00","-","EST","1963","Oct","27","2:00"],["-6:00","US","C%sT","1991","Oct","27","2:00"],["-5:00","-","EST","2006","Apr","2","2:00"],["-6:00","US","C%sT"]],"America/Indiana/Winamac":[["-5:46:25","-","LMT","1883","Nov","18","12:13:35"],["-6:00","US","C%sT","1946"],["-6:00","Pulaski","C%sT","1961","Apr","30","2:00"],["-5:00","-","EST","1969"],["-5:00","US","E%sT","1971"],["-5:00","-","EST","2006","Apr","2","2:00"],["-6:00","US","C%sT","2007","Mar","11","2:00"],["-5:00","US","E%sT"]],"America/Indiana/Vevay":[["-5:40:16","-","LMT","1883","Nov","18","12:19:44"],["-6:00","US","C%sT","1954","Apr","25","2:00"],["-5:00","-","EST","1969"],["-5:00","US","E%sT","1973"],["-5:00","-","EST","2006"],["-5:00","US","E%sT"]],"America/Kentucky/Louisville":[["-5:43:02","-","LMT","1883","Nov","18","12:16:58"],["-6:00","US","C%sT","1921"],["-6:00","Louisville","C%sT","1942"],["-6:00","US","C%sT","1946"],["-6:00","Louisville","C%sT","1961","Jul","23","2:00"],["-5:00","-","EST","1968"],["-5:00","US","E%sT","1974","Jan","6","2:00"],["-6:00","1:00","CDT","1974","Oct","27","2:00"],["-5:00","US","E%sT"]],"America/Kentucky/Monticello":[["-5:39:24","-","LMT","1883","Nov","18","12:20:36"],["-6:00","US","C%sT","1946"],["-6:00","-","CST","1968"],["-6:00","US","C%sT","2000","Oct","29","2:00"],["-5:00","US","E%sT"]],"America/Detroit":[["-5:32:11","-","LMT","1905"],["-6:00","-","CST","1915","May","15","2:00"],["-5:00","-","EST","1942"],["-5:00","US","E%sT","1946"],["-5:00","Detroit","E%sT","1973"],["-5:00","US","E%sT","1975"],["-5:00","-","EST","1975","Apr","27","2:00"],["-5:00","US","E%sT"]],"America/Menominee":[["-5:50:27","-","LMT","1885","Sep","18","12:00"],["-6:00","US","C%sT","1946"],["-6:00","Menominee","C%sT","1969","Apr","27","2:00"],["-5:00","-","EST","1973","Apr","29","2:00"],["-6:00","US","C%sT"]],"America/St_Johns":[["-3:30:52","-","LMT","1884"],["-3:30:52","StJohns","N%sT","1918"],["-3:30:52","Canada","N%sT","1919"],["-3:30:52","StJohns","N%sT","1935","Mar","30"],["-3:30","StJohns","N%sT","1942","May","11"],["-3:30","Canada","N%sT","1946"],["-3:30","StJohns","N%sT"]],"America/Goose_Bay":[["-4:01:40","-","LMT","1884",""],["-3:30:52","-","NST","1918"],["-3:30:52","Canada","N%sT","1919"],["-3:30:52","-","NST","1935","Mar","30"],["-3:30","-","NST","1936"],["-3:30","StJohns","N%sT","1942","May","11"],["-3:30","Canada","N%sT","1946"],["-3:30","StJohns","N%sT","1966","Mar","15","2:00"],["-4:00","StJohns","A%sT"]],"America/Halifax":[["-4:14:24","-","LMT","1902","Jun","15"],["-4:00","Halifax","A%sT","1918"],["-4:00","Canada","A%sT","1919"],["-4:00","Halifax","A%sT","1942","Feb","9","2:00s"],["-4:00","Canada","A%sT","1946"],["-4:00","Halifax","A%sT","1974"],["-4:00","Canada","A%sT"]],"America/Glace_Bay":[["-3:59:48","-","LMT","1902","Jun","15"],["-4:00","Canada","A%sT","1953"],["-4:00","Halifax","A%sT","1954"],["-4:00","-","AST","1972"],["-4:00","Halifax","A%sT","1974"],["-4:00","Canada","A%sT"]],"America/Moncton":[["-4:19:08","-","LMT","1883","Dec","9"],["-5:00","-","EST","1902","Jun","15"],["-4:00","Canada","A%sT","1933"],["-4:00","Moncton","A%sT","1942"],["-4:00","Canada","A%sT","1946"],["-4:00","Moncton","A%sT","1973"],["-4:00","Canada","A%sT","1993"],["-4:00","Moncton","A%sT","2007"],["-4:00","Canada","A%sT"]],"America/Blanc-Sablon":[["-3:48:28","-","LMT","1884"],["-4:00","Canada","A%sT","1970"],["-4:00","-","AST"]],"America/Montreal":[["-4:54:16","-","LMT","1884"],["-5:00","Mont","E%sT","1918"],["-5:00","Canada","E%sT","1919"],["-5:00","Mont","E%sT","1942","Feb","9","2:00s"],["-5:00","Canada","E%sT","1946"],["-5:00","Mont","E%sT","1974"],["-5:00","Canada","E%sT"]],"America/Toronto":[["-5:17:32","-","LMT","1895"],["-5:00","Canada","E%sT","1919"],["-5:00","Toronto","E%sT","1942","Feb","9","2:00s"],["-5:00","Canada","E%sT","1946"],["-5:00","Toronto","E%sT","1974"],["-5:00","Canada","E%sT"]],"America/Thunder_Bay":[["-5:57:00","-","LMT","1895"],["-6:00","-","CST","1910"],["-5:00","-","EST","1942"],["-5:00","Canada","E%sT","1970"],["-5:00","Mont","E%sT","1973"],["-5:00","-","EST","1974"],["-5:00","Canada","E%sT"]],"America/Nipigon":[["-5:53:04","-","LMT","1895"],["-5:00","Canada","E%sT","1940","Sep","29"],["-5:00","1:00","EDT","1942","Feb","9","2:00s"],["-5:00","Canada","E%sT"]],"America/Rainy_River":[["-6:18:16","-","LMT","1895"],["-6:00","Canada","C%sT","1940","Sep","29"],["-6:00","1:00","CDT","1942","Feb","9","2:00s"],["-6:00","Canada","C%sT"]],"America/Atikokan":[["-6:06:28","-","LMT","1895"],["-6:00","Canada","C%sT","1940","Sep","29"],["-6:00","1:00","CDT","1942","Feb","9","2:00s"],["-6:00","Canada","C%sT","1945","Sep","30","2:00"],["-5:00","-","EST"]],"America/Winnipeg":[["-6:28:36","-","LMT","1887","Jul","16"],["-6:00","Winn","C%sT","2006"],["-6:00","Canada","C%sT"]],"America/Regina":[["-6:58:36","-","LMT","1905","Sep"],["-7:00","Regina","M%sT","1960","Apr","lastSun","2:00"],["-6:00","-","CST"]],"America/Swift_Current":[["-7:11:20","-","LMT","1905","Sep"],["-7:00","Canada","M%sT","1946","Apr","lastSun","2:00"],["-7:00","Regina","M%sT","1950"],["-7:00","Swift","M%sT","1972","Apr","lastSun","2:00"],["-6:00","-","CST"]],"America/Edmonton":[["-7:33:52","-","LMT","1906","Sep"],["-7:00","Edm","M%sT","1987"],["-7:00","Canada","M%sT"]],"America/Vancouver":[["-8:12:28","-","LMT","1884"],["-8:00","Vanc","P%sT","1987"],["-8:00","Canada","P%sT"]],"America/Dawson_Creek":[["-8:00:56","-","LMT","1884"],["-8:00","Canada","P%sT","1947"],["-8:00","Vanc","P%sT","1972","Aug","30","2:00"],["-7:00","-","MST"]],"America/Pangnirtung":[["0","-","zzz","1921",""],["-4:00","NT_YK","A%sT","1995","Apr","Sun>=1","2:00"],["-5:00","Canada","E%sT","1999","Oct","31","2:00"],["-6:00","Canada","C%sT","2000","Oct","29","2:00"],["-5:00","Canada","E%sT"]],"America/Iqaluit":[["0","-","zzz","1942","Aug",""],["-5:00","NT_YK","E%sT","1999","Oct","31","2:00"],["-6:00","Canada","C%sT","2000","Oct","29","2:00"],["-5:00","Canada","E%sT"]],"America/Resolute":[["0","-","zzz","1947","Aug","31",""],["-6:00","NT_YK","C%sT","2000","Oct","29","2:00"],["-5:00","-","EST","2001","Apr","1","3:00"],["-6:00","Canada","C%sT","2006","Oct","29","2:00"],["-5:00","Resolute","%sT"]],"America/Rankin_Inlet":[["0","-","zzz","1957",""],["-6:00","NT_YK","C%sT","2000","Oct","29","2:00"],["-5:00","-","EST","2001","Apr","1","3:00"],["-6:00","Canada","C%sT"]],"America/Cambridge_Bay":[["0","-","zzz","1920",""],["-7:00","NT_YK","M%sT","1999","Oct","31","2:00"],["-6:00","Canada","C%sT","2000","Oct","29","2:00"],["-5:00","-","EST","2000","Nov","5","0:00"],["-6:00","-","CST","2001","Apr","1","3:00"],["-7:00","Canada","M%sT"]],"America/Yellowknife":[["0","-","zzz","1935",""],["-7:00","NT_YK","M%sT","1980"],["-7:00","Canada","M%sT"]],"America/Inuvik":[["0","-","zzz","1953",""],["-8:00","NT_YK","P%sT","1979","Apr","lastSun","2:00"],["-7:00","NT_YK","M%sT","1980"],["-7:00","Canada","M%sT"]],"America/Whitehorse":[["-9:00:12","-","LMT","1900","Aug","20"],["-9:00","NT_YK","Y%sT","1966","Jul","1","2:00"],["-8:00","NT_YK","P%sT","1980"],["-8:00","Canada","P%sT"]],"America/Dawson":[["-9:17:40","-","LMT","1900","Aug","20"],["-9:00","NT_YK","Y%sT","1973","Oct","28","0:00"],["-8:00","NT_YK","P%sT","1980"],["-8:00","Canada","P%sT"]],"America/Cancun":[["-5:47:04","-","LMT","1922","Jan","1","0:12:56"],["-6:00","-","CST","1981","Dec","23"],["-5:00","Mexico","E%sT","1998","Aug","2","2:00"],["-6:00","Mexico","C%sT"]],"America/Merida":[["-5:58:28","-","LMT","1922","Jan","1","0:01:32"],["-6:00","-","CST","1981","Dec","23"],["-5:00","-","EST","1982","Dec","2"],["-6:00","Mexico","C%sT"]],"America/Matamoros":[["-6:40:00","-","LMT","1921","Dec","31","23:20:00"],["-6:00","-","CST","1988"],["-6:00","US","C%sT","1989"],["-6:00","Mexico","C%sT","2010"],["-6:00","US","C%sT"]],"America/Monterrey":[["-6:41:16","-","LMT","1921","Dec","31","23:18:44"],["-6:00","-","CST","1988"],["-6:00","US","C%sT","1989"],["-6:00","Mexico","C%sT"]],"America/Mexico_City":[["-6:36:36","-","LMT","1922","Jan","1","0:23:24"],["-7:00","-","MST","1927","Jun","10","23:00"],["-6:00","-","CST","1930","Nov","15"],["-7:00","-","MST","1931","May","1","23:00"],["-6:00","-","CST","1931","Oct"],["-7:00","-","MST","1932","Apr","1"],["-6:00","Mexico","C%sT","2001","Sep","30","02:00"],["-6:00","-","CST","2002","Feb","20"],["-6:00","Mexico","C%sT"]],"America/Ojinaga":[["-6:57:40","-","LMT","1922","Jan","1","0:02:20"],["-7:00","-","MST","1927","Jun","10","23:00"],["-6:00","-","CST","1930","Nov","15"],["-7:00","-","MST","1931","May","1","23:00"],["-6:00","-","CST","1931","Oct"],["-7:00","-","MST","1932","Apr","1"],["-6:00","-","CST","1996"],["-6:00","Mexico","C%sT","1998"],["-6:00","-","CST","1998","Apr","Sun>=1","3:00"],["-7:00","Mexico","M%sT","2010"],["-7:00","US","M%sT"]],"America/Chihuahua":[["-7:04:20","-","LMT","1921","Dec","31","23:55:40"],["-7:00","-","MST","1927","Jun","10","23:00"],["-6:00","-","CST","1930","Nov","15"],["-7:00","-","MST","1931","May","1","23:00"],["-6:00","-","CST","1931","Oct"],["-7:00","-","MST","1932","Apr","1"],["-6:00","-","CST","1996"],["-6:00","Mexico","C%sT","1998"],["-6:00","-","CST","1998","Apr","Sun>=1","3:00"],["-7:00","Mexico","M%sT"]],"America/Hermosillo":[["-7:23:52","-","LMT","1921","Dec","31","23:36:08"],["-7:00","-","MST","1927","Jun","10","23:00"],["-6:00","-","CST","1930","Nov","15"],["-7:00","-","MST","1931","May","1","23:00"],["-6:00","-","CST","1931","Oct"],["-7:00","-","MST","1932","Apr","1"],["-6:00","-","CST","1942","Apr","24"],["-7:00","-","MST","1949","Jan","14"],["-8:00","-","PST","1970"],["-7:00","Mexico","M%sT","1999"],["-7:00","-","MST"]],"America/Mazatlan":[["-7:05:40","-","LMT","1921","Dec","31","23:54:20"],["-7:00","-","MST","1927","Jun","10","23:00"],["-6:00","-","CST","1930","Nov","15"],["-7:00","-","MST","1931","May","1","23:00"],["-6:00","-","CST","1931","Oct"],["-7:00","-","MST","1932","Apr","1"],["-6:00","-","CST","1942","Apr","24"],["-7:00","-","MST","1949","Jan","14"],["-8:00","-","PST","1970"],["-7:00","Mexico","M%sT"]],"America/Bahia_Banderas":[["-7:01:00","-","LMT","1921","Dec","31","23:59:00"],["-7:00","-","MST","1927","Jun","10","23:00"],["-6:00","-","CST","1930","Nov","15"],["-7:00","-","MST","1931","May","1","23:00"],["-6:00","-","CST","1931","Oct"],["-7:00","-","MST","1932","Apr","1"],["-6:00","-","CST","1942","Apr","24"],["-7:00","-","MST","1949","Jan","14"],["-8:00","-","PST","1970"],["-7:00","Mexico","M%sT","2010","Apr","4","2:00"],["-6:00","Mexico","C%sT"]],"America/Tijuana":[["-7:48:04","-","LMT","1922","Jan","1","0:11:56"],["-7:00","-","MST","1924"],["-8:00","-","PST","1927","Jun","10","23:00"],["-7:00","-","MST","1930","Nov","15"],["-8:00","-","PST","1931","Apr","1"],["-8:00","1:00","PDT","1931","Sep","30"],["-8:00","-","PST","1942","Apr","24"],["-8:00","1:00","PWT","1945","Aug","14","23:00u"],["-8:00","1:00","PPT","1945","Nov","12",""],["-8:00","-","PST","1948","Apr","5"],["-8:00","1:00","PDT","1949","Jan","14"],["-8:00","-","PST","1954"],["-8:00","CA","P%sT","1961"],["-8:00","-","PST","1976"],["-8:00","US","P%sT","1996"],["-8:00","Mexico","P%sT","2001"],["-8:00","US","P%sT","2002","Feb","20"],["-8:00","Mexico","P%sT","2010"],["-8:00","US","P%sT"]],"America/Santa_Isabel":[["-7:39:28","-","LMT","1922","Jan","1","0:20:32"],["-7:00","-","MST","1924"],["-8:00","-","PST","1927","Jun","10","23:00"],["-7:00","-","MST","1930","Nov","15"],["-8:00","-","PST","1931","Apr","1"],["-8:00","1:00","PDT","1931","Sep","30"],["-8:00","-","PST","1942","Apr","24"],["-8:00","1:00","PWT","1945","Aug","14","23:00u"],["-8:00","1:00","PPT","1945","Nov","12",""],["-8:00","-","PST","1948","Apr","5"],["-8:00","1:00","PDT","1949","Jan","14"],["-8:00","-","PST","1954"],["-8:00","CA","P%sT","1961"],["-8:00","-","PST","1976"],["-8:00","US","P%sT","1996"],["-8:00","Mexico","P%sT","2001"],["-8:00","US","P%sT","2002","Feb","20"],["-8:00","Mexico","P%sT"]],"America/Anguilla":[["-4:12:16","-","LMT","1912","Mar","2"],["-4:00","-","AST"]],"America/Antigua":[["-4:07:12","-","LMT","1912","Mar","2"],["-5:00","-","EST","1951"],["-4:00","-","AST"]],"America/Nassau":[["-5:09:24","-","LMT","1912","Mar","2"],["-5:00","Bahamas","E%sT","1976"],["-5:00","US","E%sT"]],"America/Barbados":[["-3:58:28","-","LMT","1924",""],["-3:58:28","-","BMT","1932",""],["-4:00","Barb","A%sT"]],"America/Belize":[["-5:52:48","-","LMT","1912","Apr"],["-6:00","Belize","C%sT"]],"Atlantic/Bermuda":[["-4:19:04","-","LMT","1930","Jan","1","2:00",""],["-4:00","-","AST","1974","Apr","28","2:00"],["-4:00","Bahamas","A%sT","1976"],["-4:00","US","A%sT"]],"America/Cayman":[["-5:25:32","-","LMT","1890",""],["-5:07:12","-","KMT","1912","Feb",""],["-5:00","-","EST"]],"America/Costa_Rica":[["-5:36:20","-","LMT","1890",""],["-5:36:20","-","SJMT","1921","Jan","15",""],["-6:00","CR","C%sT"]],"America/Havana":[["-5:29:28","-","LMT","1890"],["-5:29:36","-","HMT","1925","Jul","19","12:00",""],["-5:00","Cuba","C%sT"]],"America/Dominica":[["-4:05:36","-","LMT","1911","Jul","1","0:01",""],["-4:00","-","AST"]],"America/Santo_Domingo":[["-4:39:36","-","LMT","1890"],["-4:40","-","SDMT","1933","Apr","1","12:00",""],["-5:00","DR","E%sT","1974","Oct","27"],["-4:00","-","AST","2000","Oct","29","02:00"],["-5:00","US","E%sT","2000","Dec","3","01:00"],["-4:00","-","AST"]],"America/El_Salvador":[["-5:56:48","-","LMT","1921",""],["-6:00","Salv","C%sT"]],"America/Grenada":[["-4:07:00","-","LMT","1911","Jul",""],["-4:00","-","AST"]],"America/Guadeloupe":[["-4:06:08","-","LMT","1911","Jun","8",""],["-4:00","-","AST"]],"America/St_Barthelemy":"America/Guadeloupe","America/Marigot":"America/Guadeloupe","America/Guatemala":[["-6:02:04","-","LMT","1918","Oct","5"],["-6:00","Guat","C%sT"]],"America/Port-au-Prince":[["-4:49:20","-","LMT","1890"],["-4:49","-","PPMT","1917","Jan","24","12:00",""],["-5:00","Haiti","E%sT"]],"America/Tegucigalpa":[["-5:48:52","-","LMT","1921","Apr"],["-6:00","Hond","C%sT"]],"America/Jamaica":[["-5:07:12","-","LMT","1890",""],["-5:07:12","-","KMT","1912","Feb",""],["-5:00","-","EST","1974","Apr","28","2:00"],["-5:00","US","E%sT","1984"],["-5:00","-","EST"]],"America/Martinique":[["-4:04:20","-","LMT","1890",""],["-4:04:20","-","FFMT","1911","May",""],["-4:00","-","AST","1980","Apr","6"],["-4:00","1:00","ADT","1980","Sep","28"],["-4:00","-","AST"]],"America/Montserrat":[["-4:08:52","-","LMT","1911","Jul","1","0:01",""],["-4:00","-","AST"]],"America/Managua":[["-5:45:08","-","LMT","1890"],["-5:45:12","-","MMT","1934","Jun","23",""],["-6:00","-","CST","1973","May"],["-5:00","-","EST","1975","Feb","16"],["-6:00","Nic","C%sT","1992","Jan","1","4:00"],["-5:00","-","EST","1992","Sep","24"],["-6:00","-","CST","1993"],["-5:00","-","EST","1997"],["-6:00","Nic","C%sT"]],"America/Panama":[["-5:18:08","-","LMT","1890"],["-5:19:36","-","CMT","1908","Apr","22",""],["-5:00","-","EST"]],"America/Puerto_Rico":[["-4:24:25","-","LMT","1899","Mar","28","12:00",""],["-4:00","-","AST","1942","May","3"],["-4:00","US","A%sT","1946"],["-4:00","-","AST"]],"America/St_Kitts":[["-4:10:52","-","LMT","1912","Mar","2",""],["-4:00","-","AST"]],"America/St_Lucia":[["-4:04:00","-","LMT","1890",""],["-4:04:00","-","CMT","1912",""],["-4:00","-","AST"]],"America/Miquelon":[["-3:44:40","-","LMT","1911","May","15",""],["-4:00","-","AST","1980","May"],["-3:00","-","PMST","1987",""],["-3:00","Canada","PM%sT"]],"America/St_Vincent":[["-4:04:56","-","LMT","1890",""],["-4:04:56","-","KMT","1912",""],["-4:00","-","AST"]],"America/Grand_Turk":[["-4:44:32","-","LMT","1890"],["-5:07:12","-","KMT","1912","Feb",""],["-5:00","TC","E%sT"]],"America/Tortola":[["-4:18:28","-","LMT","1911","Jul",""],["-4:00","-","AST"]],"America/St_Thomas":[["-4:19:44","-","LMT","1911","Jul",""],["-4:00","-","AST"]]};
14412 timezoneJS.timezone.rules = {"GB-Eire":[["1916","only","-","May","21","2:00s","1:00","BST"],["1916","only","-","Oct","1","2:00s","0","GMT"],["1917","only","-","Apr","8","2:00s","1:00","BST"],["1917","only","-","Sep","17","2:00s","0","GMT"],["1918","only","-","Mar","24","2:00s","1:00","BST"],["1918","only","-","Sep","30","2:00s","0","GMT"],["1919","only","-","Mar","30","2:00s","1:00","BST"],["1919","only","-","Sep","29","2:00s","0","GMT"],["1920","only","-","Mar","28","2:00s","1:00","BST"],["1920","only","-","Oct","25","2:00s","0","GMT"],["1921","only","-","Apr","3","2:00s","1:00","BST"],["1921","only","-","Oct","3","2:00s","0","GMT"],["1922","only","-","Mar","26","2:00s","1:00","BST"],["1922","only","-","Oct","8","2:00s","0","GMT"],["1923","only","-","Apr","Sun>=16","2:00s","1:00","BST"],["1923","1924","-","Sep","Sun>=16","2:00s","0","GMT"],["1924","only","-","Apr","Sun>=9","2:00s","1:00","BST"],["1925","1926","-","Apr","Sun>=16","2:00s","1:00","BST"],["1925","1938","-","Oct","Sun>=2","2:00s","0","GMT"],["1927","only","-","Apr","Sun>=9","2:00s","1:00","BST"],["1928","1929","-","Apr","Sun>=16","2:00s","1:00","BST"],["1930","only","-","Apr","Sun>=9","2:00s","1:00","BST"],["1931","1932","-","Apr","Sun>=16","2:00s","1:00","BST"],["1933","only","-","Apr","Sun>=9","2:00s","1:00","BST"],["1934","only","-","Apr","Sun>=16","2:00s","1:00","BST"],["1935","only","-","Apr","Sun>=9","2:00s","1:00","BST"],["1936","1937","-","Apr","Sun>=16","2:00s","1:00","BST"],["1938","only","-","Apr","Sun>=9","2:00s","1:00","BST"],["1939","only","-","Apr","Sun>=16","2:00s","1:00","BST"],["1939","only","-","Nov","Sun>=16","2:00s","0","GMT"],["1940","only","-","Feb","Sun>=23","2:00s","1:00","BST"],["1941","only","-","May","Sun>=2","1:00s","2:00","BDST"],["1941","1943","-","Aug","Sun>=9","1:00s","1:00","BST"],["1942","1944","-","Apr","Sun>=2","1:00s","2:00","BDST"],["1944","only","-","Sep","Sun>=16","1:00s","1:00","BST"],["1945","only","-","Apr","Mon>=2","1:00s","2:00","BDST"],["1945","only","-","Jul","Sun>=9","1:00s","1:00","BST"],["1945","1946","-","Oct","Sun>=2","2:00s","0","GMT"],["1946","only","-","Apr","Sun>=9","2:00s","1:00","BST"],["1947","only","-","Mar","16","2:00s","1:00","BST"],["1947","only","-","Apr","13","1:00s","2:00","BDST"],["1947","only","-","Aug","10","1:00s","1:00","BST"],["1947","only","-","Nov","2","2:00s","0","GMT"],["1948","only","-","Mar","14","2:00s","1:00","BST"],["1948","only","-","Oct","31","2:00s","0","GMT"],["1949","only","-","Apr","3","2:00s","1:00","BST"],["1949","only","-","Oct","30","2:00s","0","GMT"],["1950","1952","-","Apr","Sun>=14","2:00s","1:00","BST"],["1950","1952","-","Oct","Sun>=21","2:00s","0","GMT"],["1953","only","-","Apr","Sun>=16","2:00s","1:00","BST"],["1953","1960","-","Oct","Sun>=2","2:00s","0","GMT"],["1954","only","-","Apr","Sun>=9","2:00s","1:00","BST"],["1955","1956","-","Apr","Sun>=16","2:00s","1:00","BST"],["1957","only","-","Apr","Sun>=9","2:00s","1:00","BST"],["1958","1959","-","Apr","Sun>=16","2:00s","1:00","BST"],["1960","only","-","Apr","Sun>=9","2:00s","1:00","BST"],["1961","1963","-","Mar","lastSun","2:00s","1:00","BST"],["1961","1968","-","Oct","Sun>=23","2:00s","0","GMT"],["1964","1967","-","Mar","Sun>=19","2:00s","1:00","BST"],["1968","only","-","Feb","18","2:00s","1:00","BST"],["1972","1980","-","Mar","Sun>=16","2:00s","1:00","BST"],["1972","1980","-","Oct","Sun>=23","2:00s","0","GMT"],["1981","1995","-","Mar","lastSun","1:00u","1:00","BST"],["1981","1989","-","Oct","Sun>=23","1:00u","0","GMT"],["1990","1995","-","Oct","Sun>=22","1:00u","0","GMT"]],"EU":[["1977","1980","-","Apr","Sun>=1","1:00u","1:00","S"],["1977","only","-","Sep","lastSun","1:00u","0","-"],["1978","only","-","Oct","1","1:00u","0","-"],["1979","1995","-","Sep","lastSun","1:00u","0","-"],["1981","max","-","Mar","lastSun","1:00u","1:00","S"],["1996","max","-","Oct","lastSun","1:00u","0","-"]],"W-Eur":[["1977","1980","-","Apr","Sun>=1","1:00s","1:00","S"],["1977","only","-","Sep","lastSun","1:00s","0","-"],["1978","only","-","Oct","1","1:00s","0","-"],["1979","1995","-","Sep","lastSun","1:00s","0","-"],["1981","max","-","Mar","lastSun","1:00s","1:00","S"],["1996","max","-","Oct","lastSun","1:00s","0","-"]],"C-Eur":[["1916","only","-","Apr","30","23:00","1:00","S"],["1916","only","-","Oct","1","1:00","0","-"],["1917","1918","-","Apr","Mon>=15","2:00s","1:00","S"],["1917","1918","-","Sep","Mon>=15","2:00s","0","-"],["1940","only","-","Apr","1","2:00s","1:00","S"],["1942","only","-","Nov","2","2:00s","0","-"],["1943","only","-","Mar","29","2:00s","1:00","S"],["1943","only","-","Oct","4","2:00s","0","-"],["1944","1945","-","Apr","Mon>=1","2:00s","1:00","S"],["1944","only","-","Oct","2","2:00s","0","-"],["1945","only","-","Sep","16","2:00s","0","-"],["1977","1980","-","Apr","Sun>=1","2:00s","1:00","S"],["1977","only","-","Sep","lastSun","2:00s","0","-"],["1978","only","-","Oct","1","2:00s","0","-"],["1979","1995","-","Sep","lastSun","2:00s","0","-"],["1981","max","-","Mar","lastSun","2:00s","1:00","S"],["1996","max","-","Oct","lastSun","2:00s","0","-"]],"E-Eur":[["1977","1980","-","Apr","Sun>=1","0:00","1:00","S"],["1977","only","-","Sep","lastSun","0:00","0","-"],["1978","only","-","Oct","1","0:00","0","-"],["1979","1995","-","Sep","lastSun","0:00","0","-"],["1981","max","-","Mar","lastSun","0:00","1:00","S"],["1996","max","-","Oct","lastSun","0:00","0","-"]],"Russia":[["1917","only","-","Jul","1","23:00","1:00","MST",""],["1917","only","-","Dec","28","0:00","0","MMT",""],["1918","only","-","May","31","22:00","2:00","MDST",""],["1918","only","-","Sep","16","1:00","1:00","MST"],["1919","only","-","May","31","23:00","2:00","MDST"],["1919","only","-","Jul","1","2:00","1:00","S"],["1919","only","-","Aug","16","0:00","0","-"],["1921","only","-","Feb","14","23:00","1:00","S"],["1921","only","-","Mar","20","23:00","2:00","M",""],["1921","only","-","Sep","1","0:00","1:00","S"],["1921","only","-","Oct","1","0:00","0","-"],["1981","1984","-","Apr","1","0:00","1:00","S"],["1981","1983","-","Oct","1","0:00","0","-"],["1984","1991","-","Sep","lastSun","2:00s","0","-"],["1985","1991","-","Mar","lastSun","2:00s","1:00","S"],["1992","only","-","Mar","lastSat","23:00","1:00","S"],["1992","only","-","Sep","lastSat","23:00","0","-"],["1993","max","-","Mar","lastSun","2:00s","1:00","S"],["1993","1995","-","Sep","lastSun","2:00s","0","-"],["1996","max","-","Oct","lastSun","2:00s","0","-"]],"Albania":[["1940","only","-","Jun","16","0:00","1:00","S"],["1942","only","-","Nov","2","3:00","0","-"],["1943","only","-","Mar","29","2:00","1:00","S"],["1943","only","-","Apr","10","3:00","0","-"],["1974","only","-","May","4","0:00","1:00","S"],["1974","only","-","Oct","2","0:00","0","-"],["1975","only","-","May","1","0:00","1:00","S"],["1975","only","-","Oct","2","0:00","0","-"],["1976","only","-","May","2","0:00","1:00","S"],["1976","only","-","Oct","3","0:00","0","-"],["1977","only","-","May","8","0:00","1:00","S"],["1977","only","-","Oct","2","0:00","0","-"],["1978","only","-","May","6","0:00","1:00","S"],["1978","only","-","Oct","1","0:00","0","-"],["1979","only","-","May","5","0:00","1:00","S"],["1979","only","-","Sep","30","0:00","0","-"],["1980","only","-","May","3","0:00","1:00","S"],["1980","only","-","Oct","4","0:00","0","-"],["1981","only","-","Apr","26","0:00","1:00","S"],["1981","only","-","Sep","27","0:00","0","-"],["1982","only","-","May","2","0:00","1:00","S"],["1982","only","-","Oct","3","0:00","0","-"],["1983","only","-","Apr","18","0:00","1:00","S"],["1983","only","-","Oct","1","0:00","0","-"],["1984","only","-","Apr","1","0:00","1:00","S"]],"Austria":[["1920","only","-","Apr","5","2:00s","1:00","S"],["1920","only","-","Sep","13","2:00s","0","-"],["1946","only","-","Apr","14","2:00s","1:00","S"],["1946","1948","-","Oct","Sun>=1","2:00s","0","-"],["1947","only","-","Apr","6","2:00s","1:00","S"],["1948","only","-","Apr","18","2:00s","1:00","S"],["1980","only","-","Apr","6","0:00","1:00","S"],["1980","only","-","Sep","28","0:00","0","-"]],"Belgium":[["1918","only","-","Mar","9","0:00s","1:00","S"],["1918","1919","-","Oct","Sat>=1","23:00s","0","-"],["1919","only","-","Mar","1","23:00s","1:00","S"],["1920","only","-","Feb","14","23:00s","1:00","S"],["1920","only","-","Oct","23","23:00s","0","-"],["1921","only","-","Mar","14","23:00s","1:00","S"],["1921","only","-","Oct","25","23:00s","0","-"],["1922","only","-","Mar","25","23:00s","1:00","S"],["1922","1927","-","Oct","Sat>=1","23:00s","0","-"],["1923","only","-","Apr","21","23:00s","1:00","S"],["1924","only","-","Mar","29","23:00s","1:00","S"],["1925","only","-","Apr","4","23:00s","1:00","S"],["1926","only","-","Apr","17","23:00s","1:00","S"],["1927","only","-","Apr","9","23:00s","1:00","S"],["1928","only","-","Apr","14","23:00s","1:00","S"],["1928","1938","-","Oct","Sun>=2","2:00s","0","-"],["1929","only","-","Apr","21","2:00s","1:00","S"],["1930","only","-","Apr","13","2:00s","1:00","S"],["1931","only","-","Apr","19","2:00s","1:00","S"],["1932","only","-","Apr","3","2:00s","1:00","S"],["1933","only","-","Mar","26","2:00s","1:00","S"],["1934","only","-","Apr","8","2:00s","1:00","S"],["1935","only","-","Mar","31","2:00s","1:00","S"],["1936","only","-","Apr","19","2:00s","1:00","S"],["1937","only","-","Apr","4","2:00s","1:00","S"],["1938","only","-","Mar","27","2:00s","1:00","S"],["1939","only","-","Apr","16","2:00s","1:00","S"],["1939","only","-","Nov","19","2:00s","0","-"],["1940","only","-","Feb","25","2:00s","1:00","S"],["1944","only","-","Sep","17","2:00s","0","-"],["1945","only","-","Apr","2","2:00s","1:00","S"],["1945","only","-","Sep","16","2:00s","0","-"],["1946","only","-","May","19","2:00s","1:00","S"],["1946","only","-","Oct","7","2:00s","0","-"]],"Bulg":[["1979","only","-","Mar","31","23:00","1:00","S"],["1979","only","-","Oct","1","1:00","0","-"],["1980","1982","-","Apr","Sat>=1","23:00","1:00","S"],["1980","only","-","Sep","29","1:00","0","-"],["1981","only","-","Sep","27","2:00","0","-"]],"Czech":[["1945","only","-","Apr","8","2:00s","1:00","S"],["1945","only","-","Nov","18","2:00s","0","-"],["1946","only","-","May","6","2:00s","1:00","S"],["1946","1949","-","Oct","Sun>=1","2:00s","0","-"],["1947","only","-","Apr","20","2:00s","1:00","S"],["1948","only","-","Apr","18","2:00s","1:00","S"],["1949","only","-","Apr","9","2:00s","1:00","S"]],"Denmark":[["1916","only","-","May","14","23:00","1:00","S"],["1916","only","-","Sep","30","23:00","0","-"],["1940","only","-","May","15","0:00","1:00","S"],["1945","only","-","Apr","2","2:00s","1:00","S"],["1945","only","-","Aug","15","2:00s","0","-"],["1946","only","-","May","1","2:00s","1:00","S"],["1946","only","-","Sep","1","2:00s","0","-"],["1947","only","-","May","4","2:00s","1:00","S"],["1947","only","-","Aug","10","2:00s","0","-"],["1948","only","-","May","9","2:00s","1:00","S"],["1948","only","-","Aug","8","2:00s","0","-"]],"Thule":[["1991","1992","-","Mar","lastSun","2:00","1:00","D"],["1991","1992","-","Sep","lastSun","2:00","0","S"],["1993","2006","-","Apr","Sun>=1","2:00","1:00","D"],["1993","2006","-","Oct","lastSun","2:00","0","S"],["2007","max","-","Mar","Sun>=8","2:00","1:00","D"],["2007","max","-","Nov","Sun>=1","2:00","0","S"]],"Finland":[["1942","only","-","Apr","3","0:00","1:00","S"],["1942","only","-","Oct","3","0:00","0","-"],["1981","1982","-","Mar","lastSun","2:00","1:00","S"],["1981","1982","-","Sep","lastSun","3:00","0","-"]],"France":[["1916","only","-","Jun","14","23:00s","1:00","S"],["1916","1919","-","Oct","Sun>=1","23:00s","0","-"],["1917","only","-","Mar","24","23:00s","1:00","S"],["1918","only","-","Mar","9","23:00s","1:00","S"],["1919","only","-","Mar","1","23:00s","1:00","S"],["1920","only","-","Feb","14","23:00s","1:00","S"],["1920","only","-","Oct","23","23:00s","0","-"],["1921","only","-","Mar","14","23:00s","1:00","S"],["1921","only","-","Oct","25","23:00s","0","-"],["1922","only","-","Mar","25","23:00s","1:00","S"],["1922","1938","-","Oct","Sat>=1","23:00s","0","-"],["1923","only","-","May","26","23:00s","1:00","S"],["1924","only","-","Mar","29","23:00s","1:00","S"],["1925","only","-","Apr","4","23:00s","1:00","S"],["1926","only","-","Apr","17","23:00s","1:00","S"],["1927","only","-","Apr","9","23:00s","1:00","S"],["1928","only","-","Apr","14","23:00s","1:00","S"],["1929","only","-","Apr","20","23:00s","1:00","S"],["1930","only","-","Apr","12","23:00s","1:00","S"],["1931","only","-","Apr","18","23:00s","1:00","S"],["1932","only","-","Apr","2","23:00s","1:00","S"],["1933","only","-","Mar","25","23:00s","1:00","S"],["1934","only","-","Apr","7","23:00s","1:00","S"],["1935","only","-","Mar","30","23:00s","1:00","S"],["1936","only","-","Apr","18","23:00s","1:00","S"],["1937","only","-","Apr","3","23:00s","1:00","S"],["1938","only","-","Mar","26","23:00s","1:00","S"],["1939","only","-","Apr","15","23:00s","1:00","S"],["1939","only","-","Nov","18","23:00s","0","-"],["1940","only","-","Feb","25","2:00","1:00","S"],["1941","only","-","May","5","0:00","2:00","M",""],["1941","only","-","Oct","6","0:00","1:00","S"],["1942","only","-","Mar","9","0:00","2:00","M"],["1942","only","-","Nov","2","3:00","1:00","S"],["1943","only","-","Mar","29","2:00","2:00","M"],["1943","only","-","Oct","4","3:00","1:00","S"],["1944","only","-","Apr","3","2:00","2:00","M"],["1944","only","-","Oct","8","1:00","1:00","S"],["1945","only","-","Apr","2","2:00","2:00","M"],["1945","only","-","Sep","16","3:00","0","-"],["1976","only","-","Mar","28","1:00","1:00","S"],["1976","only","-","Sep","26","1:00","0","-"]],"Germany":[["1946","only","-","Apr","14","2:00s","1:00","S"],["1946","only","-","Oct","7","2:00s","0","-"],["1947","1949","-","Oct","Sun>=1","2:00s","0","-"],["1947","only","-","Apr","6","3:00s","1:00","S"],["1947","only","-","May","11","2:00s","2:00","M"],["1947","only","-","Jun","29","3:00","1:00","S"],["1948","only","-","Apr","18","2:00s","1:00","S"],["1949","only","-","Apr","10","2:00s","1:00","S"]],"SovietZone":[["1945","only","-","May","24","2:00","2:00","M",""],["1945","only","-","Sep","24","3:00","1:00","S"],["1945","only","-","Nov","18","2:00s","0","-"]],"Greece":[["1932","only","-","Jul","7","0:00","1:00","S"],["1932","only","-","Sep","1","0:00","0","-"],["1941","only","-","Apr","7","0:00","1:00","S"],["1942","only","-","Nov","2","3:00","0","-"],["1943","only","-","Mar","30","0:00","1:00","S"],["1943","only","-","Oct","4","0:00","0","-"],["1952","only","-","Jul","1","0:00","1:00","S"],["1952","only","-","Nov","2","0:00","0","-"],["1975","only","-","Apr","12","0:00s","1:00","S"],["1975","only","-","Nov","26","0:00s","0","-"],["1976","only","-","Apr","11","2:00s","1:00","S"],["1976","only","-","Oct","10","2:00s","0","-"],["1977","1978","-","Apr","Sun>=1","2:00s","1:00","S"],["1977","only","-","Sep","26","2:00s","0","-"],["1978","only","-","Sep","24","4:00","0","-"],["1979","only","-","Apr","1","9:00","1:00","S"],["1979","only","-","Sep","29","2:00","0","-"],["1980","only","-","Apr","1","0:00","1:00","S"],["1980","only","-","Sep","28","0:00","0","-"]],"Hungary":[["1918","only","-","Apr","1","3:00","1:00","S"],["1918","only","-","Sep","29","3:00","0","-"],["1919","only","-","Apr","15","3:00","1:00","S"],["1919","only","-","Sep","15","3:00","0","-"],["1920","only","-","Apr","5","3:00","1:00","S"],["1920","only","-","Sep","30","3:00","0","-"],["1945","only","-","May","1","23:00","1:00","S"],["1945","only","-","Nov","3","0:00","0","-"],["1946","only","-","Mar","31","2:00s","1:00","S"],["1946","1949","-","Oct","Sun>=1","2:00s","0","-"],["1947","1949","-","Apr","Sun>=4","2:00s","1:00","S"],["1950","only","-","Apr","17","2:00s","1:00","S"],["1950","only","-","Oct","23","2:00s","0","-"],["1954","1955","-","May","23","0:00","1:00","S"],["1954","1955","-","Oct","3","0:00","0","-"],["1956","only","-","Jun","Sun>=1","0:00","1:00","S"],["1956","only","-","Sep","lastSun","0:00","0","-"],["1957","only","-","Jun","Sun>=1","1:00","1:00","S"],["1957","only","-","Sep","lastSun","3:00","0","-"],["1980","only","-","Apr","6","1:00","1:00","S"]],"Iceland":[["1917","1918","-","Feb","19","23:00","1:00","S"],["1917","only","-","Oct","21","1:00","0","-"],["1918","only","-","Nov","16","1:00","0","-"],["1939","only","-","Apr","29","23:00","1:00","S"],["1939","only","-","Nov","29","2:00","0","-"],["1940","only","-","Feb","25","2:00","1:00","S"],["1940","only","-","Nov","3","2:00","0","-"],["1941","only","-","Mar","2","1:00s","1:00","S"],["1941","only","-","Nov","2","1:00s","0","-"],["1942","only","-","Mar","8","1:00s","1:00","S"],["1942","only","-","Oct","25","1:00s","0","-"],["1943","1946","-","Mar","Sun>=1","1:00s","1:00","S"],["1943","1948","-","Oct","Sun>=22","1:00s","0","-"],["1947","1967","-","Apr","Sun>=1","1:00s","1:00","S"],["1949","only","-","Oct","30","1:00s","0","-"],["1950","1966","-","Oct","Sun>=22","1:00s","0","-"],["1967","only","-","Oct","29","1:00s","0","-"]],"Italy":[["1916","only","-","Jun","3","0:00s","1:00","S"],["1916","only","-","Oct","1","0:00s","0","-"],["1917","only","-","Apr","1","0:00s","1:00","S"],["1917","only","-","Sep","30","0:00s","0","-"],["1918","only","-","Mar","10","0:00s","1:00","S"],["1918","1919","-","Oct","Sun>=1","0:00s","0","-"],["1919","only","-","Mar","2","0:00s","1:00","S"],["1920","only","-","Mar","21","0:00s","1:00","S"],["1920","only","-","Sep","19","0:00s","0","-"],["1940","only","-","Jun","15","0:00s","1:00","S"],["1944","only","-","Sep","17","0:00s","0","-"],["1945","only","-","Apr","2","2:00","1:00","S"],["1945","only","-","Sep","15","0:00s","0","-"],["1946","only","-","Mar","17","2:00s","1:00","S"],["1946","only","-","Oct","6","2:00s","0","-"],["1947","only","-","Mar","16","0:00s","1:00","S"],["1947","only","-","Oct","5","0:00s","0","-"],["1948","only","-","Feb","29","2:00s","1:00","S"],["1948","only","-","Oct","3","2:00s","0","-"],["1966","1968","-","May","Sun>=22","0:00","1:00","S"],["1966","1969","-","Sep","Sun>=22","0:00","0","-"],["1969","only","-","Jun","1","0:00","1:00","S"],["1970","only","-","May","31","0:00","1:00","S"],["1970","only","-","Sep","lastSun","0:00","0","-"],["1971","1972","-","May","Sun>=22","0:00","1:00","S"],["1971","only","-","Sep","lastSun","1:00","0","-"],["1972","only","-","Oct","1","0:00","0","-"],["1973","only","-","Jun","3","0:00","1:00","S"],["1973","1974","-","Sep","lastSun","0:00","0","-"],["1974","only","-","May","26","0:00","1:00","S"],["1975","only","-","Jun","1","0:00s","1:00","S"],["1975","1977","-","Sep","lastSun","0:00s","0","-"],["1976","only","-","May","30","0:00s","1:00","S"],["1977","1979","-","May","Sun>=22","0:00s","1:00","S"],["1978","only","-","Oct","1","0:00s","0","-"],["1979","only","-","Sep","30","0:00s","0","-"]],"Latvia":[["1989","1996","-","Mar","lastSun","2:00s","1:00","S"],["1989","1996","-","Sep","lastSun","2:00s","0","-"]],"Lux":[["1916","only","-","May","14","23:00","1:00","S"],["1916","only","-","Oct","1","1:00","0","-"],["1917","only","-","Apr","28","23:00","1:00","S"],["1917","only","-","Sep","17","1:00","0","-"],["1918","only","-","Apr","Mon>=15","2:00s","1:00","S"],["1918","only","-","Sep","Mon>=15","2:00s","0","-"],["1919","only","-","Mar","1","23:00","1:00","S"],["1919","only","-","Oct","5","3:00","0","-"],["1920","only","-","Feb","14","23:00","1:00","S"],["1920","only","-","Oct","24","2:00","0","-"],["1921","only","-","Mar","14","23:00","1:00","S"],["1921","only","-","Oct","26","2:00","0","-"],["1922","only","-","Mar","25","23:00","1:00","S"],["1922","only","-","Oct","Sun>=2","1:00","0","-"],["1923","only","-","Apr","21","23:00","1:00","S"],["1923","only","-","Oct","Sun>=2","2:00","0","-"],["1924","only","-","Mar","29","23:00","1:00","S"],["1924","1928","-","Oct","Sun>=2","1:00","0","-"],["1925","only","-","Apr","5","23:00","1:00","S"],["1926","only","-","Apr","17","23:00","1:00","S"],["1927","only","-","Apr","9","23:00","1:00","S"],["1928","only","-","Apr","14","23:00","1:00","S"],["1929","only","-","Apr","20","23:00","1:00","S"]],"Malta":[["1973","only","-","Mar","31","0:00s","1:00","S"],["1973","only","-","Sep","29","0:00s","0","-"],["1974","only","-","Apr","21","0:00s","1:00","S"],["1974","only","-","Sep","16","0:00s","0","-"],["1975","1979","-","Apr","Sun>=15","2:00","1:00","S"],["1975","1980","-","Sep","Sun>=15","2:00","0","-"],["1980","only","-","Mar","31","2:00","1:00","S"]],"Neth":[["1916","only","-","May","1","0:00","1:00","NST",""],["1916","only","-","Oct","1","0:00","0","AMT",""],["1917","only","-","Apr","16","2:00s","1:00","NST"],["1917","only","-","Sep","17","2:00s","0","AMT"],["1918","1921","-","Apr","Mon>=1","2:00s","1:00","NST"],["1918","1921","-","Sep","lastMon","2:00s","0","AMT"],["1922","only","-","Mar","lastSun","2:00s","1:00","NST"],["1922","1936","-","Oct","Sun>=2","2:00s","0","AMT"],["1923","only","-","Jun","Fri>=1","2:00s","1:00","NST"],["1924","only","-","Mar","lastSun","2:00s","1:00","NST"],["1925","only","-","Jun","Fri>=1","2:00s","1:00","NST"],["1926","1931","-","May","15","2:00s","1:00","NST"],["1932","only","-","May","22","2:00s","1:00","NST"],["1933","1936","-","May","15","2:00s","1:00","NST"],["1937","only","-","May","22","2:00s","1:00","NST"],["1937","only","-","Jul","1","0:00","1:00","S"],["1937","1939","-","Oct","Sun>=2","2:00s","0","-"],["1938","1939","-","May","15","2:00s","1:00","S"],["1945","only","-","Apr","2","2:00s","1:00","S"],["1945","only","-","Sep","16","2:00s","0","-"]],"Norway":[["1916","only","-","May","22","1:00","1:00","S"],["1916","only","-","Sep","30","0:00","0","-"],["1945","only","-","Apr","2","2:00s","1:00","S"],["1945","only","-","Oct","1","2:00s","0","-"],["1959","1964","-","Mar","Sun>=15","2:00s","1:00","S"],["1959","1965","-","Sep","Sun>=15","2:00s","0","-"],["1965","only","-","Apr","25","2:00s","1:00","S"]],"Poland":[["1918","1919","-","Sep","16","2:00s","0","-"],["1919","only","-","Apr","15","2:00s","1:00","S"],["1944","only","-","Apr","3","2:00s","1:00","S"],["1944","only","-","Oct","4","2:00","0","-"],["1945","only","-","Apr","29","0:00","1:00","S"],["1945","only","-","Nov","1","0:00","0","-"],["1946","only","-","Apr","14","0:00s","1:00","S"],["1946","only","-","Oct","7","2:00s","0","-"],["1947","only","-","May","4","2:00s","1:00","S"],["1947","1949","-","Oct","Sun>=1","2:00s","0","-"],["1948","only","-","Apr","18","2:00s","1:00","S"],["1949","only","-","Apr","10","2:00s","1:00","S"],["1957","only","-","Jun","2","1:00s","1:00","S"],["1957","1958","-","Sep","lastSun","1:00s","0","-"],["1958","only","-","Mar","30","1:00s","1:00","S"],["1959","only","-","May","31","1:00s","1:00","S"],["1959","1961","-","Oct","Sun>=1","1:00s","0","-"],["1960","only","-","Apr","3","1:00s","1:00","S"],["1961","1964","-","May","lastSun","1:00s","1:00","S"],["1962","1964","-","Sep","lastSun","1:00s","0","-"]],"Port":[["1916","only","-","Jun","17","23:00","1:00","S"],["1916","only","-","Nov","1","1:00","0","-"],["1917","only","-","Feb","28","23:00s","1:00","S"],["1917","1921","-","Oct","14","23:00s","0","-"],["1918","only","-","Mar","1","23:00s","1:00","S"],["1919","only","-","Feb","28","23:00s","1:00","S"],["1920","only","-","Feb","29","23:00s","1:00","S"],["1921","only","-","Feb","28","23:00s","1:00","S"],["1924","only","-","Apr","16","23:00s","1:00","S"],["1924","only","-","Oct","14","23:00s","0","-"],["1926","only","-","Apr","17","23:00s","1:00","S"],["1926","1929","-","Oct","Sat>=1","23:00s","0","-"],["1927","only","-","Apr","9","23:00s","1:00","S"],["1928","only","-","Apr","14","23:00s","1:00","S"],["1929","only","-","Apr","20","23:00s","1:00","S"],["1931","only","-","Apr","18","23:00s","1:00","S"],["1931","1932","-","Oct","Sat>=1","23:00s","0","-"],["1932","only","-","Apr","2","23:00s","1:00","S"],["1934","only","-","Apr","7","23:00s","1:00","S"],["1934","1938","-","Oct","Sat>=1","23:00s","0","-"],["1935","only","-","Mar","30","23:00s","1:00","S"],["1936","only","-","Apr","18","23:00s","1:00","S"],["1937","only","-","Apr","3","23:00s","1:00","S"],["1938","only","-","Mar","26","23:00s","1:00","S"],["1939","only","-","Apr","15","23:00s","1:00","S"],["1939","only","-","Nov","18","23:00s","0","-"],["1940","only","-","Feb","24","23:00s","1:00","S"],["1940","1941","-","Oct","5","23:00s","0","-"],["1941","only","-","Apr","5","23:00s","1:00","S"],["1942","1945","-","Mar","Sat>=8","23:00s","1:00","S"],["1942","only","-","Apr","25","22:00s","2:00","M",""],["1942","only","-","Aug","15","22:00s","1:00","S"],["1942","1945","-","Oct","Sat>=24","23:00s","0","-"],["1943","only","-","Apr","17","22:00s","2:00","M"],["1943","1945","-","Aug","Sat>=25","22:00s","1:00","S"],["1944","1945","-","Apr","Sat>=21","22:00s","2:00","M"],["1946","only","-","Apr","Sat>=1","23:00s","1:00","S"],["1946","only","-","Oct","Sat>=1","23:00s","0","-"],["1947","1949","-","Apr","Sun>=1","2:00s","1:00","S"],["1947","1949","-","Oct","Sun>=1","2:00s","0","-"],["1951","1965","-","Apr","Sun>=1","2:00s","1:00","S"],["1951","1965","-","Oct","Sun>=1","2:00s","0","-"],["1977","only","-","Mar","27","0:00s","1:00","S"],["1977","only","-","Sep","25","0:00s","0","-"],["1978","1979","-","Apr","Sun>=1","0:00s","1:00","S"],["1978","only","-","Oct","1","0:00s","0","-"],["1979","1982","-","Sep","lastSun","1:00s","0","-"],["1980","only","-","Mar","lastSun","0:00s","1:00","S"],["1981","1982","-","Mar","lastSun","1:00s","1:00","S"],["1983","only","-","Mar","lastSun","2:00s","1:00","S"]],"Romania":[["1932","only","-","May","21","0:00s","1:00","S"],["1932","1939","-","Oct","Sun>=1","0:00s","0","-"],["1933","1939","-","Apr","Sun>=2","0:00s","1:00","S"],["1979","only","-","May","27","0:00","1:00","S"],["1979","only","-","Sep","lastSun","0:00","0","-"],["1980","only","-","Apr","5","23:00","1:00","S"],["1980","only","-","Sep","lastSun","1:00","0","-"],["1991","1993","-","Mar","lastSun","0:00s","1:00","S"],["1991","1993","-","Sep","lastSun","0:00s","0","-"]],"Spain":[["1917","only","-","May","5","23:00s","1:00","S"],["1917","1919","-","Oct","6","23:00s","0","-"],["1918","only","-","Apr","15","23:00s","1:00","S"],["1919","only","-","Apr","5","23:00s","1:00","S"],["1924","only","-","Apr","16","23:00s","1:00","S"],["1924","only","-","Oct","4","23:00s","0","-"],["1926","only","-","Apr","17","23:00s","1:00","S"],["1926","1929","-","Oct","Sat>=1","23:00s","0","-"],["1927","only","-","Apr","9","23:00s","1:00","S"],["1928","only","-","Apr","14","23:00s","1:00","S"],["1929","only","-","Apr","20","23:00s","1:00","S"],["1937","only","-","May","22","23:00s","1:00","S"],["1937","1939","-","Oct","Sat>=1","23:00s","0","-"],["1938","only","-","Mar","22","23:00s","1:00","S"],["1939","only","-","Apr","15","23:00s","1:00","S"],["1940","only","-","Mar","16","23:00s","1:00","S"],["1942","only","-","May","2","22:00s","2:00","M",""],["1942","only","-","Sep","1","22:00s","1:00","S"],["1943","1946","-","Apr","Sat>=13","22:00s","2:00","M"],["1943","only","-","Oct","3","22:00s","1:00","S"],["1944","only","-","Oct","10","22:00s","1:00","S"],["1945","only","-","Sep","30","1:00","1:00","S"],["1946","only","-","Sep","30","0:00","0","-"],["1949","only","-","Apr","30","23:00","1:00","S"],["1949","only","-","Sep","30","1:00","0","-"],["1974","1975","-","Apr","Sat>=13","23:00","1:00","S"],["1974","1975","-","Oct","Sun>=1","1:00","0","-"],["1976","only","-","Mar","27","23:00","1:00","S"],["1976","1977","-","Sep","lastSun","1:00","0","-"],["1977","1978","-","Apr","2","23:00","1:00","S"],["1978","only","-","Oct","1","1:00","0","-"]],"SpainAfrica":[["1967","only","-","Jun","3","12:00","1:00","S"],["1967","only","-","Oct","1","0:00","0","-"],["1974","only","-","Jun","24","0:00","1:00","S"],["1974","only","-","Sep","1","0:00","0","-"],["1976","1977","-","May","1","0:00","1:00","S"],["1976","only","-","Aug","1","0:00","0","-"],["1977","only","-","Sep","28","0:00","0","-"],["1978","only","-","Jun","1","0:00","1:00","S"],["1978","only","-","Aug","4","0:00","0","-"]],"Swiss":[["1941","1942","-","May","Mon>=1","1:00","1:00","S"],["1941","1942","-","Oct","Mon>=1","2:00","0","-"]],"Turkey":[["1916","only","-","May","1","0:00","1:00","S"],["1916","only","-","Oct","1","0:00","0","-"],["1920","only","-","Mar","28","0:00","1:00","S"],["1920","only","-","Oct","25","0:00","0","-"],["1921","only","-","Apr","3","0:00","1:00","S"],["1921","only","-","Oct","3","0:00","0","-"],["1922","only","-","Mar","26","0:00","1:00","S"],["1922","only","-","Oct","8","0:00","0","-"],["1924","only","-","May","13","0:00","1:00","S"],["1924","1925","-","Oct","1","0:00","0","-"],["1925","only","-","May","1","0:00","1:00","S"],["1940","only","-","Jun","30","0:00","1:00","S"],["1940","only","-","Oct","5","0:00","0","-"],["1940","only","-","Dec","1","0:00","1:00","S"],["1941","only","-","Sep","21","0:00","0","-"],["1942","only","-","Apr","1","0:00","1:00","S"],["1942","only","-","Nov","1","0:00","0","-"],["1945","only","-","Apr","2","0:00","1:00","S"],["1945","only","-","Oct","8","0:00","0","-"],["1946","only","-","Jun","1","0:00","1:00","S"],["1946","only","-","Oct","1","0:00","0","-"],["1947","1948","-","Apr","Sun>=16","0:00","1:00","S"],["1947","1950","-","Oct","Sun>=2","0:00","0","-"],["1949","only","-","Apr","10","0:00","1:00","S"],["1950","only","-","Apr","19","0:00","1:00","S"],["1951","only","-","Apr","22","0:00","1:00","S"],["1951","only","-","Oct","8","0:00","0","-"],["1962","only","-","Jul","15","0:00","1:00","S"],["1962","only","-","Oct","8","0:00","0","-"],["1964","only","-","May","15","0:00","1:00","S"],["1964","only","-","Oct","1","0:00","0","-"],["1970","1972","-","May","Sun>=2","0:00","1:00","S"],["1970","1972","-","Oct","Sun>=2","0:00","0","-"],["1973","only","-","Jun","3","1:00","1:00","S"],["1973","only","-","Nov","4","3:00","0","-"],["1974","only","-","Mar","31","2:00","1:00","S"],["1974","only","-","Nov","3","5:00","0","-"],["1975","only","-","Mar","30","0:00","1:00","S"],["1975","1976","-","Oct","lastSun","0:00","0","-"],["1976","only","-","Jun","1","0:00","1:00","S"],["1977","1978","-","Apr","Sun>=1","0:00","1:00","S"],["1977","only","-","Oct","16","0:00","0","-"],["1979","1980","-","Apr","Sun>=1","3:00","1:00","S"],["1979","1982","-","Oct","Mon>=11","0:00","0","-"],["1981","1982","-","Mar","lastSun","3:00","1:00","S"],["1983","only","-","Jul","31","0:00","1:00","S"],["1983","only","-","Oct","2","0:00","0","-"],["1985","only","-","Apr","20","0:00","1:00","S"],["1985","only","-","Sep","28","0:00","0","-"],["1986","1990","-","Mar","lastSun","2:00s","1:00","S"],["1986","1990","-","Sep","lastSun","2:00s","0","-"],["1991","2006","-","Mar","lastSun","1:00s","1:00","S"],["1991","1995","-","Sep","lastSun","1:00s","0","-"],["1996","2006","-","Oct","lastSun","1:00s","0","-"]],"US":[["1918","1919","-","Mar","lastSun","2:00","1:00","D"],["1918","1919","-","Oct","lastSun","2:00","0","S"],["1942","only","-","Feb","9","2:00","1:00","W",""],["1945","only","-","Aug","14","23:00u","1:00","P",""],["1945","only","-","Sep","30","2:00","0","S"],["1967","2006","-","Oct","lastSun","2:00","0","S"],["1967","1973","-","Apr","lastSun","2:00","1:00","D"],["1974","only","-","Jan","6","2:00","1:00","D"],["1975","only","-","Feb","23","2:00","1:00","D"],["1976","1986","-","Apr","lastSun","2:00","1:00","D"],["1987","2006","-","Apr","Sun>=1","2:00","1:00","D"],["2007","max","-","Mar","Sun>=8","2:00","1:00","D"],["2007","max","-","Nov","Sun>=1","2:00","0","S"]],"NYC":[["1920","only","-","Mar","lastSun","2:00","1:00","D"],["1920","only","-","Oct","lastSun","2:00","0","S"],["1921","1966","-","Apr","lastSun","2:00","1:00","D"],["1921","1954","-","Sep","lastSun","2:00","0","S"],["1955","1966","-","Oct","lastSun","2:00","0","S"]],"Chicago":[["1920","only","-","Jun","13","2:00","1:00","D"],["1920","1921","-","Oct","lastSun","2:00","0","S"],["1921","only","-","Mar","lastSun","2:00","1:00","D"],["1922","1966","-","Apr","lastSun","2:00","1:00","D"],["1922","1954","-","Sep","lastSun","2:00","0","S"],["1955","1966","-","Oct","lastSun","2:00","0","S"]],"Denver":[["1920","1921","-","Mar","lastSun","2:00","1:00","D"],["1920","only","-","Oct","lastSun","2:00","0","S"],["1921","only","-","May","22","2:00","0","S"],["1965","1966","-","Apr","lastSun","2:00","1:00","D"],["1965","1966","-","Oct","lastSun","2:00","0","S"]],"CA":[["1948","only","-","Mar","14","2:00","1:00","D"],["1949","only","-","Jan","1","2:00","0","S"],["1950","1966","-","Apr","lastSun","2:00","1:00","D"],["1950","1961","-","Sep","lastSun","2:00","0","S"],["1962","1966","-","Oct","lastSun","2:00","0","S"]],"Indianapolis":[["1941","only","-","Jun","22","2:00","1:00","D"],["1941","1954","-","Sep","lastSun","2:00","0","S"],["1946","1954","-","Apr","lastSun","2:00","1:00","D"]],"Marengo":[["1951","only","-","Apr","lastSun","2:00","1:00","D"],["1951","only","-","Sep","lastSun","2:00","0","S"],["1954","1960","-","Apr","lastSun","2:00","1:00","D"],["1954","1960","-","Sep","lastSun","2:00","0","S"]],"Vincennes":[["1946","only","-","Apr","lastSun","2:00","1:00","D"],["1946","only","-","Sep","lastSun","2:00","0","S"],["1953","1954","-","Apr","lastSun","2:00","1:00","D"],["1953","1959","-","Sep","lastSun","2:00","0","S"],["1955","only","-","May","1","0:00","1:00","D"],["1956","1963","-","Apr","lastSun","2:00","1:00","D"],["1960","only","-","Oct","lastSun","2:00","0","S"],["1961","only","-","Sep","lastSun","2:00","0","S"],["1962","1963","-","Oct","lastSun","2:00","0","S"]],"Perry":[["1946","only","-","Apr","lastSun","2:00","1:00","D"],["1946","only","-","Sep","lastSun","2:00","0","S"],["1953","1954","-","Apr","lastSun","2:00","1:00","D"],["1953","1959","-","Sep","lastSun","2:00","0","S"],["1955","only","-","May","1","0:00","1:00","D"],["1956","1963","-","Apr","lastSun","2:00","1:00","D"],["1960","only","-","Oct","lastSun","2:00","0","S"],["1961","only","-","Sep","lastSun","2:00","0","S"],["1962","1963","-","Oct","lastSun","2:00","0","S"]],"Pike":[["1955","only","-","May","1","0:00","1:00","D"],["1955","1960","-","Sep","lastSun","2:00","0","S"],["1956","1964","-","Apr","lastSun","2:00","1:00","D"],["1961","1964","-","Oct","lastSun","2:00","0","S"]],"Starke":[["1947","1961","-","Apr","lastSun","2:00","1:00","D"],["1947","1954","-","Sep","lastSun","2:00","0","S"],["1955","1956","-","Oct","lastSun","2:00","0","S"],["1957","1958","-","Sep","lastSun","2:00","0","S"],["1959","1961","-","Oct","lastSun","2:00","0","S"]],"Pulaski":[["1946","1960","-","Apr","lastSun","2:00","1:00","D"],["1946","1954","-","Sep","lastSun","2:00","0","S"],["1955","1956","-","Oct","lastSun","2:00","0","S"],["1957","1960","-","Sep","lastSun","2:00","0","S"]],"Louisville":[["1921","only","-","May","1","2:00","1:00","D"],["1921","only","-","Sep","1","2:00","0","S"],["1941","1961","-","Apr","lastSun","2:00","1:00","D"],["1941","only","-","Sep","lastSun","2:00","0","S"],["1946","only","-","Jun","2","2:00","0","S"],["1950","1955","-","Sep","lastSun","2:00","0","S"],["1956","1960","-","Oct","lastSun","2:00","0","S"]],"Detroit":[["1948","only","-","Apr","lastSun","2:00","1:00","D"],["1948","only","-","Sep","lastSun","2:00","0","S"],["1967","only","-","Jun","14","2:00","1:00","D"],["1967","only","-","Oct","lastSun","2:00","0","S"]],"Menominee":[["1946","only","-","Apr","lastSun","2:00","1:00","D"],["1946","only","-","Sep","lastSun","2:00","0","S"],["1966","only","-","Apr","lastSun","2:00","1:00","D"],["1966","only","-","Oct","lastSun","2:00","0","S"]],"Canada":[["1918","only","-","Apr","14","2:00","1:00","D"],["1918","only","-","Oct","31","2:00","0","S"],["1942","only","-","Feb","9","2:00","1:00","W",""],["1945","only","-","Aug","14","23:00u","1:00","P",""],["1945","only","-","Sep","30","2:00","0","S"],["1974","1986","-","Apr","lastSun","2:00","1:00","D"],["1974","2006","-","Oct","lastSun","2:00","0","S"],["1987","2006","-","Apr","Sun>=1","2:00","1:00","D"],["2007","max","-","Mar","Sun>=8","2:00","1:00","D"],["2007","max","-","Nov","Sun>=1","2:00","0","S"]],"StJohns":[["1917","only","-","Apr","8","2:00","1:00","D"],["1917","only","-","Sep","17","2:00","0","S"],["1919","only","-","May","5","23:00","1:00","D"],["1919","only","-","Aug","12","23:00","0","S"],["1920","1935","-","May","Sun>=1","23:00","1:00","D"],["1920","1935","-","Oct","lastSun","23:00","0","S"],["1936","1941","-","May","Mon>=9","0:00","1:00","D"],["1936","1941","-","Oct","Mon>=2","0:00","0","S"],["1946","1950","-","May","Sun>=8","2:00","1:00","D"],["1946","1950","-","Oct","Sun>=2","2:00","0","S"],["1951","1986","-","Apr","lastSun","2:00","1:00","D"],["1951","1959","-","Sep","lastSun","2:00","0","S"],["1960","1986","-","Oct","lastSun","2:00","0","S"],["1987","only","-","Apr","Sun>=1","0:01","1:00","D"],["1987","2006","-","Oct","lastSun","0:01","0","S"],["1988","only","-","Apr","Sun>=1","0:01","2:00","DD"],["1989","2006","-","Apr","Sun>=1","0:01","1:00","D"],["2007","max","-","Mar","Sun>=8","0:01","1:00","D"],["2007","max","-","Nov","Sun>=1","0:01","0","S"]],"Halifax":[["1916","only","-","Apr","1","0:00","1:00","D"],["1916","only","-","Oct","1","0:00","0","S"],["1920","only","-","May","9","0:00","1:00","D"],["1920","only","-","Aug","29","0:00","0","S"],["1921","only","-","May","6","0:00","1:00","D"],["1921","1922","-","Sep","5","0:00","0","S"],["1922","only","-","Apr","30","0:00","1:00","D"],["1923","1925","-","May","Sun>=1","0:00","1:00","D"],["1923","only","-","Sep","4","0:00","0","S"],["1924","only","-","Sep","15","0:00","0","S"],["1925","only","-","Sep","28","0:00","0","S"],["1926","only","-","May","16","0:00","1:00","D"],["1926","only","-","Sep","13","0:00","0","S"],["1927","only","-","May","1","0:00","1:00","D"],["1927","only","-","Sep","26","0:00","0","S"],["1928","1931","-","May","Sun>=8","0:00","1:00","D"],["1928","only","-","Sep","9","0:00","0","S"],["1929","only","-","Sep","3","0:00","0","S"],["1930","only","-","Sep","15","0:00","0","S"],["1931","1932","-","Sep","Mon>=24","0:00","0","S"],["1932","only","-","May","1","0:00","1:00","D"],["1933","only","-","Apr","30","0:00","1:00","D"],["1933","only","-","Oct","2","0:00","0","S"],["1934","only","-","May","20","0:00","1:00","D"],["1934","only","-","Sep","16","0:00","0","S"],["1935","only","-","Jun","2","0:00","1:00","D"],["1935","only","-","Sep","30","0:00","0","S"],["1936","only","-","Jun","1","0:00","1:00","D"],["1936","only","-","Sep","14","0:00","0","S"],["1937","1938","-","May","Sun>=1","0:00","1:00","D"],["1937","1941","-","Sep","Mon>=24","0:00","0","S"],["1939","only","-","May","28","0:00","1:00","D"],["1940","1941","-","May","Sun>=1","0:00","1:00","D"],["1946","1949","-","Apr","lastSun","2:00","1:00","D"],["1946","1949","-","Sep","lastSun","2:00","0","S"],["1951","1954","-","Apr","lastSun","2:00","1:00","D"],["1951","1954","-","Sep","lastSun","2:00","0","S"],["1956","1959","-","Apr","lastSun","2:00","1:00","D"],["1956","1959","-","Sep","lastSun","2:00","0","S"],["1962","1973","-","Apr","lastSun","2:00","1:00","D"],["1962","1973","-","Oct","lastSun","2:00","0","S"]],"Moncton":[["1933","1935","-","Jun","Sun>=8","1:00","1:00","D"],["1933","1935","-","Sep","Sun>=8","1:00","0","S"],["1936","1938","-","Jun","Sun>=1","1:00","1:00","D"],["1936","1938","-","Sep","Sun>=1","1:00","0","S"],["1939","only","-","May","27","1:00","1:00","D"],["1939","1941","-","Sep","Sat>=21","1:00","0","S"],["1940","only","-","May","19","1:00","1:00","D"],["1941","only","-","May","4","1:00","1:00","D"],["1946","1972","-","Apr","lastSun","2:00","1:00","D"],["1946","1956","-","Sep","lastSun","2:00","0","S"],["1957","1972","-","Oct","lastSun","2:00","0","S"],["1993","2006","-","Apr","Sun>=1","0:01","1:00","D"],["1993","2006","-","Oct","lastSun","0:01","0","S"]],"Mont":[["1917","only","-","Mar","25","2:00","1:00","D"],["1917","only","-","Apr","24","0:00","0","S"],["1919","only","-","Mar","31","2:30","1:00","D"],["1919","only","-","Oct","25","2:30","0","S"],["1920","only","-","May","2","2:30","1:00","D"],["1920","1922","-","Oct","Sun>=1","2:30","0","S"],["1921","only","-","May","1","2:00","1:00","D"],["1922","only","-","Apr","30","2:00","1:00","D"],["1924","only","-","May","17","2:00","1:00","D"],["1924","1926","-","Sep","lastSun","2:30","0","S"],["1925","1926","-","May","Sun>=1","2:00","1:00","D"],["1927","only","-","May","1","0:00","1:00","D"],["1927","1932","-","Sep","lastSun","0:00","0","S"],["1928","1931","-","Apr","lastSun","0:00","1:00","D"],["1932","only","-","May","1","0:00","1:00","D"],["1933","1940","-","Apr","lastSun","0:00","1:00","D"],["1933","only","-","Oct","1","0:00","0","S"],["1934","1939","-","Sep","lastSun","0:00","0","S"],["1946","1973","-","Apr","lastSun","2:00","1:00","D"],["1945","1948","-","Sep","lastSun","2:00","0","S"],["1949","1950","-","Oct","lastSun","2:00","0","S"],["1951","1956","-","Sep","lastSun","2:00","0","S"],["1957","1973","-","Oct","lastSun","2:00","0","S"]],"Toronto":[["1919","only","-","Mar","30","23:30","1:00","D"],["1919","only","-","Oct","26","0:00","0","S"],["1920","only","-","May","2","2:00","1:00","D"],["1920","only","-","Sep","26","0:00","0","S"],["1921","only","-","May","15","2:00","1:00","D"],["1921","only","-","Sep","15","2:00","0","S"],["1922","1923","-","May","Sun>=8","2:00","1:00","D"],["1922","1926","-","Sep","Sun>=15","2:00","0","S"],["1924","1927","-","May","Sun>=1","2:00","1:00","D"],["1927","1932","-","Sep","lastSun","2:00","0","S"],["1928","1931","-","Apr","lastSun","2:00","1:00","D"],["1932","only","-","May","1","2:00","1:00","D"],["1933","1940","-","Apr","lastSun","2:00","1:00","D"],["1933","only","-","Oct","1","2:00","0","S"],["1934","1939","-","Sep","lastSun","2:00","0","S"],["1945","1946","-","Sep","lastSun","2:00","0","S"],["1946","only","-","Apr","lastSun","2:00","1:00","D"],["1947","1949","-","Apr","lastSun","0:00","1:00","D"],["1947","1948","-","Sep","lastSun","0:00","0","S"],["1949","only","-","Nov","lastSun","0:00","0","S"],["1950","1973","-","Apr","lastSun","2:00","1:00","D"],["1950","only","-","Nov","lastSun","2:00","0","S"],["1951","1956","-","Sep","lastSun","2:00","0","S"],["1957","1973","-","Oct","lastSun","2:00","0","S"]],"Winn":[["1916","only","-","Apr","23","0:00","1:00","D"],["1916","only","-","Sep","17","0:00","0","S"],["1918","only","-","Apr","14","2:00","1:00","D"],["1918","only","-","Oct","31","2:00","0","S"],["1937","only","-","May","16","2:00","1:00","D"],["1937","only","-","Sep","26","2:00","0","S"],["1942","only","-","Feb","9","2:00","1:00","W",""],["1945","only","-","Aug","14","23:00u","1:00","P",""],["1945","only","-","Sep","lastSun","2:00","0","S"],["1946","only","-","May","12","2:00","1:00","D"],["1946","only","-","Oct","13","2:00","0","S"],["1947","1949","-","Apr","lastSun","2:00","1:00","D"],["1947","1949","-","Sep","lastSun","2:00","0","S"],["1950","only","-","May","1","2:00","1:00","D"],["1950","only","-","Sep","30","2:00","0","S"],["1951","1960","-","Apr","lastSun","2:00","1:00","D"],["1951","1958","-","Sep","lastSun","2:00","0","S"],["1959","only","-","Oct","lastSun","2:00","0","S"],["1960","only","-","Sep","lastSun","2:00","0","S"],["1963","only","-","Apr","lastSun","2:00","1:00","D"],["1963","only","-","Sep","22","2:00","0","S"],["1966","1986","-","Apr","lastSun","2:00s","1:00","D"],["1966","2005","-","Oct","lastSun","2:00s","0","S"],["1987","2005","-","Apr","Sun>=1","2:00s","1:00","D"]],"Regina":[["1918","only","-","Apr","14","2:00","1:00","D"],["1918","only","-","Oct","31","2:00","0","S"],["1930","1934","-","May","Sun>=1","0:00","1:00","D"],["1930","1934","-","Oct","Sun>=1","0:00","0","S"],["1937","1941","-","Apr","Sun>=8","0:00","1:00","D"],["1937","only","-","Oct","Sun>=8","0:00","0","S"],["1938","only","-","Oct","Sun>=1","0:00","0","S"],["1939","1941","-","Oct","Sun>=8","0:00","0","S"],["1942","only","-","Feb","9","2:00","1:00","W",""],["1945","only","-","Aug","14","23:00u","1:00","P",""],["1945","only","-","Sep","lastSun","2:00","0","S"],["1946","only","-","Apr","Sun>=8","2:00","1:00","D"],["1946","only","-","Oct","Sun>=8","2:00","0","S"],["1947","1957","-","Apr","lastSun","2:00","1:00","D"],["1947","1957","-","Sep","lastSun","2:00","0","S"],["1959","only","-","Apr","lastSun","2:00","1:00","D"],["1959","only","-","Oct","lastSun","2:00","0","S"]],"Swift":[["1957","only","-","Apr","lastSun","2:00","1:00","D"],["1957","only","-","Oct","lastSun","2:00","0","S"],["1959","1961","-","Apr","lastSun","2:00","1:00","D"],["1959","only","-","Oct","lastSun","2:00","0","S"],["1960","1961","-","Sep","lastSun","2:00","0","S"]],"Edm":[["1918","1919","-","Apr","Sun>=8","2:00","1:00","D"],["1918","only","-","Oct","31","2:00","0","S"],["1919","only","-","May","27","2:00","0","S"],["1920","1923","-","Apr","lastSun","2:00","1:00","D"],["1920","only","-","Oct","lastSun","2:00","0","S"],["1921","1923","-","Sep","lastSun","2:00","0","S"],["1942","only","-","Feb","9","2:00","1:00","W",""],["1945","only","-","Aug","14","23:00u","1:00","P",""],["1945","only","-","Sep","lastSun","2:00","0","S"],["1947","only","-","Apr","lastSun","2:00","1:00","D"],["1947","only","-","Sep","lastSun","2:00","0","S"],["1967","only","-","Apr","lastSun","2:00","1:00","D"],["1967","only","-","Oct","lastSun","2:00","0","S"],["1969","only","-","Apr","lastSun","2:00","1:00","D"],["1969","only","-","Oct","lastSun","2:00","0","S"],["1972","1986","-","Apr","lastSun","2:00","1:00","D"],["1972","2006","-","Oct","lastSun","2:00","0","S"]],"Vanc":[["1918","only","-","Apr","14","2:00","1:00","D"],["1918","only","-","Oct","31","2:00","0","S"],["1942","only","-","Feb","9","2:00","1:00","W",""],["1945","only","-","Aug","14","23:00u","1:00","P",""],["1945","only","-","Sep","30","2:00","0","S"],["1946","1986","-","Apr","lastSun","2:00","1:00","D"],["1946","only","-","Oct","13","2:00","0","S"],["1947","1961","-","Sep","lastSun","2:00","0","S"],["1962","2006","-","Oct","lastSun","2:00","0","S"]],"NT_YK":[["1918","only","-","Apr","14","2:00","1:00","D"],["1918","only","-","Oct","27","2:00","0","S"],["1919","only","-","May","25","2:00","1:00","D"],["1919","only","-","Nov","1","0:00","0","S"],["1942","only","-","Feb","9","2:00","1:00","W",""],["1945","only","-","Aug","14","23:00u","1:00","P",""],["1945","only","-","Sep","30","2:00","0","S"],["1965","only","-","Apr","lastSun","0:00","2:00","DD"],["1965","only","-","Oct","lastSun","2:00","0","S"],["1980","1986","-","Apr","lastSun","2:00","1:00","D"],["1980","2006","-","Oct","lastSun","2:00","0","S"],["1987","2006","-","Apr","Sun>=1","2:00","1:00","D"]],"Resolute":[["2006","max","-","Nov","Sun>=1","2:00","0","ES"],["2007","max","-","Mar","Sun>=8","2:00","0","CD"]],"Mexico":[["1939","only","-","Feb","5","0:00","1:00","D"],["1939","only","-","Jun","25","0:00","0","S"],["1940","only","-","Dec","9","0:00","1:00","D"],["1941","only","-","Apr","1","0:00","0","S"],["1943","only","-","Dec","16","0:00","1:00","W",""],["1944","only","-","May","1","0:00","0","S"],["1950","only","-","Feb","12","0:00","1:00","D"],["1950","only","-","Jul","30","0:00","0","S"],["1996","2000","-","Apr","Sun>=1","2:00","1:00","D"],["1996","2000","-","Oct","lastSun","2:00","0","S"],["2001","only","-","May","Sun>=1","2:00","1:00","D"],["2001","only","-","Sep","lastSun","2:00","0","S"],["2002","max","-","Apr","Sun>=1","2:00","1:00","D"],["2002","max","-","Oct","lastSun","2:00","0","S"]],"Bahamas":[["1964","1975","-","Oct","lastSun","2:00","0","S"],["1964","1975","-","Apr","lastSun","2:00","1:00","D"]],"Barb":[["1977","only","-","Jun","12","2:00","1:00","D"],["1977","1978","-","Oct","Sun>=1","2:00","0","S"],["1978","1980","-","Apr","Sun>=15","2:00","1:00","D"],["1979","only","-","Sep","30","2:00","0","S"],["1980","only","-","Sep","25","2:00","0","S"]],"Belize":[["1918","1942","-","Oct","Sun>=2","0:00","0:30","HD"],["1919","1943","-","Feb","Sun>=9","0:00","0","S"],["1973","only","-","Dec","5","0:00","1:00","D"],["1974","only","-","Feb","9","0:00","0","S"],["1982","only","-","Dec","18","0:00","1:00","D"],["1983","only","-","Feb","12","0:00","0","S"]],"CR":[["1979","1980","-","Feb","lastSun","0:00","1:00","D"],["1979","1980","-","Jun","Sun>=1","0:00","0","S"],["1991","1992","-","Jan","Sat>=15","0:00","1:00","D"],["1991","only","-","Jul","1","0:00","0","S"],["1992","only","-","Mar","15","0:00","0","S"]],"Cuba":[["1928","only","-","Jun","10","0:00","1:00","D"],["1928","only","-","Oct","10","0:00","0","S"],["1940","1942","-","Jun","Sun>=1","0:00","1:00","D"],["1940","1942","-","Sep","Sun>=1","0:00","0","S"],["1945","1946","-","Jun","Sun>=1","0:00","1:00","D"],["1945","1946","-","Sep","Sun>=1","0:00","0","S"],["1965","only","-","Jun","1","0:00","1:00","D"],["1965","only","-","Sep","30","0:00","0","S"],["1966","only","-","May","29","0:00","1:00","D"],["1966","only","-","Oct","2","0:00","0","S"],["1967","only","-","Apr","8","0:00","1:00","D"],["1967","1968","-","Sep","Sun>=8","0:00","0","S"],["1968","only","-","Apr","14","0:00","1:00","D"],["1969","1977","-","Apr","lastSun","0:00","1:00","D"],["1969","1971","-","Oct","lastSun","0:00","0","S"],["1972","1974","-","Oct","8","0:00","0","S"],["1975","1977","-","Oct","lastSun","0:00","0","S"],["1978","only","-","May","7","0:00","1:00","D"],["1978","1990","-","Oct","Sun>=8","0:00","0","S"],["1979","1980","-","Mar","Sun>=15","0:00","1:00","D"],["1981","1985","-","May","Sun>=5","0:00","1:00","D"],["1986","1989","-","Mar","Sun>=14","0:00","1:00","D"],["1990","1997","-","Apr","Sun>=1","0:00","1:00","D"],["1991","1995","-","Oct","Sun>=8","0:00s","0","S"],["1996","only","-","Oct","6","0:00s","0","S"],["1997","only","-","Oct","12","0:00s","0","S"],["1998","1999","-","Mar","lastSun","0:00s","1:00","D"],["1998","2003","-","Oct","lastSun","0:00s","0","S"],["2000","2004","-","Apr","Sun>=1","0:00s","1:00","D"],["2006","max","-","Oct","lastSun","0:00s","0","S"],["2007","only","-","Mar","Sun>=8","0:00s","1:00","D"],["2008","only","-","Mar","Sun>=15","0:00s","1:00","D"],["2009","2010","-","Mar","Sun>=8","0:00s","1:00","D"],["2011","only","-","Mar","Sun>=15","0:00s","1:00","D"],["2012","max","-","Mar","Sun>=8","0:00s","1:00","D"]],"DR":[["1966","only","-","Oct","30","0:00","1:00","D"],["1967","only","-","Feb","28","0:00","0","S"],["1969","1973","-","Oct","lastSun","0:00","0:30","HD"],["1970","only","-","Feb","21","0:00","0","S"],["1971","only","-","Jan","20","0:00","0","S"],["1972","1974","-","Jan","21","0:00","0","S"]],"Salv":[["1987","1988","-","May","Sun>=1","0:00","1:00","D"],["1987","1988","-","Sep","lastSun","0:00","0","S"]],"Guat":[["1973","only","-","Nov","25","0:00","1:00","D"],["1974","only","-","Feb","24","0:00","0","S"],["1983","only","-","May","21","0:00","1:00","D"],["1983","only","-","Sep","22","0:00","0","S"],["1991","only","-","Mar","23","0:00","1:00","D"],["1991","only","-","Sep","7","0:00","0","S"],["2006","only","-","Apr","30","0:00","1:00","D"],["2006","only","-","Oct","1","0:00","0","S"]],"Haiti":[["1983","only","-","May","8","0:00","1:00","D"],["1984","1987","-","Apr","lastSun","0:00","1:00","D"],["1983","1987","-","Oct","lastSun","0:00","0","S"],["1988","1997","-","Apr","Sun>=1","1:00s","1:00","D"],["1988","1997","-","Oct","lastSun","1:00s","0","S"],["2005","2006","-","Apr","Sun>=1","0:00","1:00","D"],["2005","2006","-","Oct","lastSun","0:00","0","S"]],"Hond":[["1987","1988","-","May","Sun>=1","0:00","1:00","D"],["1987","1988","-","Sep","lastSun","0:00","0","S"],["2006","only","-","May","Sun>=1","0:00","1:00","D"],["2006","only","-","Aug","Mon>=1","0:00","0","S"]],"Nic":[["1979","1980","-","Mar","Sun>=16","0:00","1:00","D"],["1979","1980","-","Jun","Mon>=23","0:00","0","S"],["2005","only","-","Apr","10","0:00","1:00","D"],["2005","only","-","Oct","Sun>=1","0:00","0","S"],["2006","only","-","Apr","30","2:00","1:00","D"],["2006","only","-","Oct","Sun>=1","1:00","0","S"]],"TC":[["1979","1986","-","Apr","lastSun","2:00","1:00","D"],["1979","2006","-","Oct","lastSun","2:00","0","S"],["1987","2006","-","Apr","Sun>=1","2:00","1:00","D"],["2007","max","-","Mar","Sun>=8","2:00","1:00","D"],["2007","max","-","Nov","Sun>=1","2:00","0","S"]]};
14413
14414 /*
14415  * jQuery Impromptu
14416  * By: Trent Richardson [http://trentrichardson.com]
14417  * Version 3.1
14418  * Last Modified: 3/30/2010
14419  * 
14420  * Copyright 2010 Trent Richardson
14421  * Dual licensed under the MIT and GPL licenses.
14422  * http://trentrichardson.com/Impromptu/GPL-LICENSE.txt
14423  * http://trentrichardson.com/Impromptu/MIT-LICENSE.txt
14424  * 
14425  */
14426  
14427 (function($) {
14428   $.prompt = function(message, options) {
14429     options = $.extend({},$.prompt.defaults,options);
14430     $.prompt.currentPrefix = options.prefix;
14431
14432     var ie6   = ($.browser.msie && $.browser.version < 7);
14433     var $body = $(document.body);
14434     var $window = $(window);
14435     
14436     options.classes = $.trim(options.classes);
14437     if(options.classes != '')
14438       options.classes = ' '+ options.classes;
14439       
14440     //build the box and fade
14441     var msgbox = '<div class="'+ options.prefix +'box'+ options.classes +'" id="'+ options.prefix +'box">';
14442     if(options.useiframe && (($('object, applet').length > 0) || ie6)) {
14443       msgbox += '<iframe src="javascript:false;" style="display:block;position:absolute;z-index:-1;" class="'+ options.prefix +'fade" id="'+ options.prefix +'fade"></iframe>';
14444     } else {
14445       if(ie6) {
14446         $('select').css('visibility','hidden');
14447       }
14448       msgbox +='<div class="'+ options.prefix +'fade" id="'+ options.prefix +'fade"></div>';
14449     }
14450     msgbox += '<div class="'+ options.prefix +'" id="'+ options.prefix +'"><div class="'+ options.prefix +'container"><div class="';
14451     msgbox += options.prefix +'close">X</div><div id="'+ options.prefix +'states"></div>';
14452     msgbox += '</div></div></div>';
14453
14454     var $jqib = $(msgbox).appendTo($body);
14455     var $jqi  = $jqib.children('#'+ options.prefix);
14456     var $jqif = $jqib.children('#'+ options.prefix +'fade');
14457
14458     //if a string was passed, convert to a single state
14459     if(message.constructor == String){
14460       message = {
14461         state0: {
14462           html: message,
14463           buttons: options.buttons,
14464           focus: options.focus,
14465           submit: options.submit
14466         }
14467       };
14468     }
14469
14470     //build the states
14471     var states = "";
14472
14473     $.each(message,function(statename,stateobj){
14474       stateobj = $.extend({},$.prompt.defaults.state,stateobj);
14475       message[statename] = stateobj;
14476
14477       states += '<div id="'+ options.prefix +'_state_'+ statename +'" class="'+ options.prefix + '_state" style="display:none;"><div class="'+ options.prefix +'message">' + stateobj.html +'</div><div class="'+ options.prefix +'buttons">';
14478       $.each(stateobj.buttons, function(k, v){
14479         if(typeof v == 'object')
14480           states += '<button name="' + options.prefix + '_' + statename + '_button' + v.title.replace(/[^a-z0-9]+/gi,'') + '" id="' + options.prefix + '_' + statename + '_button' + v.title.replace(/[^a-z0-9]+/gi,'') + '" value="' + v.value + '">' + v.title + '</button>';
14481         else states += '<button name="' + options.prefix + '_' + statename + '_button' + k + '" id="' + options.prefix +  '_' + statename + '_button' + k + '" value="' + v + '">' + k + '</button>';
14482       });
14483       states += '</div></div>';
14484     });
14485
14486     //insert the states...
14487     $jqi.find('#'+ options.prefix +'states').html(states).children('.'+ options.prefix +'_state:first').css('display','block');
14488     $jqi.find('.'+ options.prefix +'buttons:empty').css('display','none');
14489     
14490     //Events
14491     $.each(message,function(statename,stateobj){
14492       var $state = $jqi.find('#'+ options.prefix +'_state_'+ statename);
14493
14494       $state.children('.'+ options.prefix +'buttons').children('button').click(function(){
14495         var msg = $state.children('.'+ options.prefix +'message');
14496         var clicked = stateobj.buttons[$(this).text()];
14497         if(clicked == undefined){
14498           for(var i in stateobj.buttons)
14499             if(stateobj.buttons[i].title == $(this).text())
14500               clicked = stateobj.buttons[i].value;
14501         }
14502         
14503         if(typeof clicked == 'object')
14504           clicked = clicked.value;
14505         var forminputs = {};
14506
14507         //collect all form element values from all states
14508         $.each($jqi.find('#'+ options.prefix +'states :input').serializeArray(),function(i,obj){
14509           if (forminputs[obj.name] === undefined) {
14510             forminputs[obj.name] = obj.value;
14511           } else if (typeof forminputs[obj.name] == Array || typeof forminputs[obj.name] == 'object') {
14512             forminputs[obj.name].push(obj.value);
14513           } else {
14514             forminputs[obj.name] = [forminputs[obj.name],obj.value];  
14515           } 
14516         });
14517
14518         var close = stateobj.submit(clicked,msg,forminputs);
14519         if(close === undefined || close) {
14520           removePrompt(true,clicked,msg,forminputs);
14521         }
14522       });
14523       $state.find('.'+ options.prefix +'buttons button:eq('+ stateobj.focus +')').addClass(options.prefix +'defaultbutton');
14524
14525     });
14526
14527     var ie6scroll = function(){
14528       $jqib.css({ top: $window.scrollTop() });
14529     };
14530
14531     var fadeClicked = function(){
14532       if(options.persistent){
14533         var i = 0;
14534         $jqib.addClass(options.prefix +'warning');
14535         var intervalid = setInterval(function(){
14536           $jqib.toggleClass(options.prefix +'warning');
14537           if(i++ > 1){
14538             clearInterval(intervalid);
14539             $jqib.removeClass(options.prefix +'warning');
14540           }
14541         }, 100);
14542       }
14543       else {
14544         removePrompt();
14545       }
14546     };
14547     
14548     var keyPressEventHandler = function(e){
14549       var key = (window.event) ? event.keyCode : e.keyCode; // MSIE or Firefox?
14550       
14551       //escape key closes
14552       if(key==27) {
14553         fadeClicked();  
14554       }
14555       
14556       //constrain tabs
14557       if (key == 9){
14558         var $inputels = $(':input:enabled:visible',$jqib);
14559         var fwd = !e.shiftKey && e.target == $inputels[$inputels.length-1];
14560         var back = e.shiftKey && e.target == $inputels[0];
14561         if (fwd || back) {
14562         setTimeout(function(){ 
14563           if (!$inputels)
14564             return;
14565           var el = $inputels[back===true ? $inputels.length-1 : 0];
14566
14567           if (el)
14568             el.focus();           
14569         },10);
14570         return false;
14571         }
14572       }
14573     };
14574     
14575     var positionPrompt = function(){
14576       $jqib.css({
14577         position: (ie6) ? "absolute" : "fixed",
14578         height: $window.height(),
14579         width: "100%",
14580         top: (ie6)? $window.scrollTop() : 0,
14581         left: 0,
14582         right: 0,
14583         bottom: 0
14584       });
14585       $jqif.css({
14586         position: "absolute",
14587         height: $window.height(),
14588         width: "100%",
14589         top: 0,
14590         left: 0,
14591         right: 0,
14592         bottom: 0
14593       });
14594       $jqi.css({
14595         position: "absolute",
14596         top: options.top,
14597         left: "50%",
14598         marginLeft: (($jqi.outerWidth()/2)*-1)
14599       });
14600     };
14601
14602     var stylePrompt = function(){
14603       $jqif.css({
14604         zIndex: options.zIndex,
14605         display: "none",
14606         opacity: options.opacity
14607       });
14608       $jqi.css({
14609         zIndex: options.zIndex+1,
14610         display: "none"
14611       });
14612       $jqib.css({
14613         zIndex: options.zIndex
14614       });
14615     };
14616
14617     var removePrompt = function(callCallback, clicked, msg, formvals){
14618       $jqi.remove();
14619       //ie6, remove the scroll event
14620       if(ie6) {
14621         $body.unbind('scroll',ie6scroll);
14622       }
14623       $window.unbind('resize',positionPrompt);
14624       $jqif.fadeOut(options.overlayspeed,function(){
14625         $jqif.unbind('click',fadeClicked);
14626         $jqif.remove();
14627         if(callCallback) {
14628           options.callback(clicked,msg,formvals);
14629         }
14630         $jqib.unbind('keypress',keyPressEventHandler);
14631         $jqib.remove();
14632         if(ie6 && !options.useiframe) {
14633           $('select').css('visibility','visible');
14634         }
14635       });
14636     };
14637
14638     positionPrompt();
14639     stylePrompt();
14640     
14641     //ie6, add a scroll event to fix position:fixed
14642     if(ie6) {
14643       $window.scroll(ie6scroll);
14644     }
14645     $jqif.click(fadeClicked);
14646     $window.resize(positionPrompt);
14647     $jqib.bind("keydown keypress",keyPressEventHandler);
14648     $jqi.find('.'+ options.prefix +'close').click(removePrompt);
14649
14650     //Show it
14651     $jqif.fadeIn(options.overlayspeed);
14652     $jqi[options.show](options.promptspeed,options.loaded);
14653     $jqi.find('#'+ options.prefix +'states .'+ options.prefix +'_state:first .'+ options.prefix +'defaultbutton').focus();
14654     
14655     if(options.timeout > 0)
14656       setTimeout($.prompt.close,options.timeout);
14657
14658     return $jqib;
14659   };
14660   
14661   $.prompt.defaults = {
14662     prefix:'jqi',
14663     classes: '',
14664     buttons: {
14665       Ok: true
14666     },
14667     loaded: function(){
14668
14669     },
14670       submit: function(){
14671         return true;
14672     },
14673     callback: function(){
14674
14675     },
14676     opacity: 0.6,
14677     zIndex: 999,
14678       overlayspeed: 'slow',
14679       promptspeed: 'fast',
14680       show: 'fadeIn',
14681       focus: 0,
14682       useiframe: false,
14683     top: "15%",
14684       persistent: true,
14685       timeout: 0,
14686       state: {
14687       html: '',
14688       buttons: {
14689         Ok: true
14690       },
14691         focus: 0,
14692         submit: function(){
14693           return true;
14694        }
14695       }
14696   };
14697   
14698   $.prompt.currentPrefix = $.prompt.defaults.prefix;
14699
14700   $.prompt.setDefaults = function(o) {
14701     $.prompt.defaults = $.extend({}, $.prompt.defaults, o);
14702   };
14703   
14704   $.prompt.setStateDefaults = function(o) {
14705     $.prompt.defaults.state = $.extend({}, $.prompt.defaults.state, o);
14706   };
14707   
14708   $.prompt.getStateContent = function(state) {
14709     return $('#'+ $.prompt.currentPrefix +'_state_'+ state);
14710   };
14711   
14712   $.prompt.getCurrentState = function() {
14713     return $('.'+ $.prompt.currentPrefix +'_state:visible');
14714   };
14715   
14716   $.prompt.getCurrentStateName = function() {
14717     var stateid = $.prompt.getCurrentState().attr('id');
14718     
14719     return stateid.replace($.prompt.currentPrefix +'_state_','');
14720   };
14721   
14722   $.prompt.goToState = function(state, callback) {
14723     $('.'+ $.prompt.currentPrefix +'_state').slideUp('slow');
14724     $('#'+ $.prompt.currentPrefix +'_state_'+ state).slideDown('slow',function(){
14725       $(this).find('.'+ $.prompt.currentPrefix +'defaultbutton').focus();
14726       if (typeof callback == 'function')
14727         callback();
14728     });
14729   };
14730   
14731   $.prompt.nextState = function(callback) {
14732     var $next = $('.'+ $.prompt.currentPrefix +'_state:visible').next();
14733
14734     $('.'+ $.prompt.currentPrefix +'_state').slideUp('slow');
14735     
14736     $next.slideDown('slow',function(){
14737       $next.find('.'+ $.prompt.currentPrefix +'defaultbutton').focus();
14738       if (typeof callback == 'function')
14739         callback();
14740     });
14741   };
14742   
14743   $.prompt.prevState = function(callback) {
14744     var $next = $('.'+ $.prompt.currentPrefix +'_state:visible').prev();
14745
14746     $('.'+ $.prompt.currentPrefix +'_state').slideUp('slow');
14747     
14748     $next.slideDown('slow',function(){
14749       $next.find('.'+ $.prompt.currentPrefix +'defaultbutton').focus();
14750       if (typeof callback == 'function')
14751         callback();
14752     });
14753   };
14754   
14755   $.prompt.close = function() {
14756     $('#'+ $.prompt.currentPrefix +'box').fadeOut('fast',function(){
14757             $(this).remove();
14758     });
14759   };
14760   
14761   $.fn.prompt = function(options){
14762     if(options == undefined) 
14763       options = {};
14764     if(options.withDataAndEvents == undefined)
14765       options.withDataAndEvents = false;
14766       
14767     $.prompt($(this).clone(options.withDataAndEvents).html(),options);
14768   }
14769   
14770 })(jQuery);
14771 (function($) {
14772   $.fn.serializeToJson = function() {
14773     attrs = {};
14774     this.find('[name]').each(function(i, field) {
14775       $field = $(field);
14776       if ($field.is(':checkbox')) {
14777         val = $field.is(':checked');
14778       } else {
14779         val = $field.val();
14780       }
14781       attrs[$field.attr('name')] = val;
14782     });
14783     return attrs;
14784   };
14785 })(jQuery);
14786
14787 /*
14788     http://www.JSON.org/json2.js
14789     2011-02-23
14790
14791     Public Domain.
14792
14793     NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
14794
14795     See http://www.JSON.org/js.html
14796
14797
14798     This code should be minified before deployment.
14799     See http://javascript.crockford.com/jsmin.html
14800
14801     USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
14802     NOT CONTROL.
14803
14804
14805     This file creates a global JSON object containing two methods: stringify
14806     and parse.
14807
14808         JSON.stringify(value, replacer, space)
14809             value       any JavaScript value, usually an object or array.
14810
14811             replacer    an optional parameter that determines how object
14812                         values are stringified for objects. It can be a
14813                         function or an array of strings.
14814
14815             space       an optional parameter that specifies the indentation
14816                         of nested structures. If it is omitted, the text will
14817                         be packed without extra whitespace. If it is a number,
14818                         it will specify the number of spaces to indent at each
14819                         level. If it is a string (such as '\t' or '&nbsp;'),
14820                         it contains the characters used to indent at each level.
14821
14822             This method produces a JSON text from a JavaScript value.
14823
14824             When an object value is found, if the object contains a toJSON
14825             method, its toJSON method will be called and the result will be
14826             stringified. A toJSON method does not serialize: it returns the
14827             value represented by the name/value pair that should be serialized,
14828             or undefined if nothing should be serialized. The toJSON method
14829             will be passed the key associated with the value, and this will be
14830             bound to the value
14831
14832             For example, this would serialize Dates as ISO strings.
14833
14834                 Date.prototype.toJSON = function (key) {
14835                     function f(n) {
14836                         // Format integers to have at least two digits.
14837                         return n < 10 ? '0' + n : n;
14838                     }
14839
14840                     return this.getUTCFullYear()   + '-' +
14841                          f(this.getUTCMonth() + 1) + '-' +
14842                          f(this.getUTCDate())      + 'T' +
14843                          f(this.getUTCHours())     + ':' +
14844                          f(this.getUTCMinutes())   + ':' +
14845                          f(this.getUTCSeconds())   + 'Z';
14846                 };
14847
14848             You can provide an optional replacer method. It will be passed the
14849             key and value of each member, with this bound to the containing
14850             object. The value that is returned from your method will be
14851             serialized. If your method returns undefined, then the member will
14852             be excluded from the serialization.
14853
14854             If the replacer parameter is an array of strings, then it will be
14855             used to select the members to be serialized. It filters the results
14856             such that only members with keys listed in the replacer array are
14857             stringified.
14858
14859             Values that do not have JSON representations, such as undefined or
14860             functions, will not be serialized. Such values in objects will be
14861             dropped; in arrays they will be replaced with null. You can use
14862             a replacer function to replace those with JSON values.
14863             JSON.stringify(undefined) returns undefined.
14864
14865             The optional space parameter produces a stringification of the
14866             value that is filled with line breaks and indentation to make it
14867             easier to read.
14868
14869             If the space parameter is a non-empty string, then that string will
14870             be used for indentation. If the space parameter is a number, then
14871             the indentation will be that many spaces.
14872
14873             Example:
14874
14875             text = JSON.stringify(['e', {pluribus: 'unum'}]);
14876             // text is '["e",{"pluribus":"unum"}]'
14877
14878
14879             text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
14880             // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
14881
14882             text = JSON.stringify([new Date()], function (key, value) {
14883                 return this[key] instanceof Date ?
14884                     'Date(' + this[key] + ')' : value;
14885             });
14886             // text is '["Date(---current time---)"]'
14887
14888
14889         JSON.parse(text, reviver)
14890             This method parses a JSON text to produce an object or array.
14891             It can throw a SyntaxError exception.
14892
14893             The optional reviver parameter is a function that can filter and
14894             transform the results. It receives each of the keys and values,
14895             and its return value is used instead of the original value.
14896             If it returns what it received, then the structure is not modified.
14897             If it returns undefined then the member is deleted.
14898
14899             Example:
14900
14901             // Parse the text. Values that look like ISO date strings will
14902             // be converted to Date objects.
14903
14904             myData = JSON.parse(text, function (key, value) {
14905                 var a;
14906                 if (typeof value === 'string') {
14907                     a =
14908 /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
14909                     if (a) {
14910                         return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
14911                             +a[5], +a[6]));
14912                     }
14913                 }
14914                 return value;
14915             });
14916
14917             myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
14918                 var d;
14919                 if (typeof value === 'string' &&
14920                         value.slice(0, 5) === 'Date(' &&
14921                         value.slice(-1) === ')') {
14922                     d = new Date(value.slice(5, -1));
14923                     if (d) {
14924                         return d;
14925                     }
14926                 }
14927                 return value;
14928             });
14929
14930
14931     This is a reference implementation. You are free to copy, modify, or
14932     redistribute.
14933 */
14934
14935 /*jslint evil: true, strict: false, regexp: false */
14936
14937 /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
14938     call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
14939     getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
14940     lastIndex, length, parse, prototype, push, replace, slice, stringify,
14941     test, toJSON, toString, valueOf
14942 */
14943
14944
14945 // Create a JSON object only if one does not already exist. We create the
14946 // methods in a closure to avoid creating global variables.
14947
14948 var JSON;
14949 if (!JSON) {
14950     JSON = {};
14951 }
14952
14953 (function () {
14954     "use strict";
14955
14956     function f(n) {
14957         // Format integers to have at least two digits.
14958         return n < 10 ? '0' + n : n;
14959     }
14960
14961     if (typeof Date.prototype.toJSON !== 'function') {
14962
14963         Date.prototype.toJSON = function (key) {
14964
14965             return isFinite(this.valueOf()) ?
14966                 this.getUTCFullYear()     + '-' +
14967                 f(this.getUTCMonth() + 1) + '-' +
14968                 f(this.getUTCDate())      + 'T' +
14969                 f(this.getUTCHours())     + ':' +
14970                 f(this.getUTCMinutes())   + ':' +
14971                 f(this.getUTCSeconds())   + 'Z' : null;
14972         };
14973
14974         String.prototype.toJSON      =
14975             Number.prototype.toJSON  =
14976             Boolean.prototype.toJSON = function (key) {
14977                 return this.valueOf();
14978             };
14979     }
14980
14981     var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
14982         escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
14983         gap,
14984         indent,
14985         meta = {    // table of character substitutions
14986             '\b': '\\b',
14987             '\t': '\\t',
14988             '\n': '\\n',
14989             '\f': '\\f',
14990             '\r': '\\r',
14991             '"' : '\\"',
14992             '\\': '\\\\'
14993         },
14994         rep;
14995
14996
14997     function quote(string) {
14998
14999 // If the string contains no control characters, no quote characters, and no
15000 // backslash characters, then we can safely slap some quotes around it.
15001 // Otherwise we must also replace the offending characters with safe escape
15002 // sequences.
15003
15004         escapable.lastIndex = 0;
15005         return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
15006             var c = meta[a];
15007             return typeof c === 'string' ? c :
15008                 '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
15009         }) + '"' : '"' + string + '"';
15010     }
15011
15012
15013     function str(key, holder) {
15014
15015 // Produce a string from holder[key].
15016
15017         var i,          // The loop counter.
15018             k,          // The member key.
15019             v,          // The member value.
15020             length,
15021             mind = gap,
15022             partial,
15023             value = holder[key];
15024
15025 // If the value has a toJSON method, call it to obtain a replacement value.
15026
15027         if (value && typeof value === 'object' &&
15028                 typeof value.toJSON === 'function') {
15029             value = value.toJSON(key);
15030         }
15031
15032 // If we were called with a replacer function, then call the replacer to
15033 // obtain a replacement value.
15034
15035         if (typeof rep === 'function') {
15036             value = rep.call(holder, key, value);
15037         }
15038
15039 // What happens next depends on the value's type.
15040
15041         switch (typeof value) {
15042         case 'string':
15043             return quote(value);
15044
15045         case 'number':
15046
15047 // JSON numbers must be finite. Encode non-finite numbers as null.
15048
15049             return isFinite(value) ? String(value) : 'null';
15050
15051         case 'boolean':
15052         case 'null':
15053
15054 // If the value is a boolean or null, convert it to a string. Note:
15055 // typeof null does not produce 'null'. The case is included here in
15056 // the remote chance that this gets fixed someday.
15057
15058             return String(value);
15059
15060 // If the type is 'object', we might be dealing with an object or an array or
15061 // null.
15062
15063         case 'object':
15064
15065 // Due to a specification blunder in ECMAScript, typeof null is 'object',
15066 // so watch out for that case.
15067
15068             if (!value) {
15069                 return 'null';
15070             }
15071
15072 // Make an array to hold the partial results of stringifying this object value.
15073
15074             gap += indent;
15075             partial = [];
15076
15077 // Is the value an array?
15078
15079             if (Object.prototype.toString.apply(value) === '[object Array]') {
15080
15081 // The value is an array. Stringify every element. Use null as a placeholder
15082 // for non-JSON values.
15083
15084                 length = value.length;
15085                 for (i = 0; i < length; i += 1) {
15086                     partial[i] = str(i, value) || 'null';
15087                 }
15088
15089 // Join all of the elements together, separated with commas, and wrap them in
15090 // brackets.
15091
15092                 v = partial.length === 0 ? '[]' : gap ?
15093                     '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
15094                     '[' + partial.join(',') + ']';
15095                 gap = mind;
15096                 return v;
15097             }
15098
15099 // If the replacer is an array, use it to select the members to be stringified.
15100
15101             if (rep && typeof rep === 'object') {
15102                 length = rep.length;
15103                 for (i = 0; i < length; i += 1) {
15104                     if (typeof rep[i] === 'string') {
15105                         k = rep[i];
15106                         v = str(k, value);
15107                         if (v) {
15108                             partial.push(quote(k) + (gap ? ': ' : ':') + v);
15109                         }
15110                     }
15111                 }
15112             } else {
15113
15114 // Otherwise, iterate through all of the keys in the object.
15115
15116                 for (k in value) {
15117                     if (Object.prototype.hasOwnProperty.call(value, k)) {
15118                         v = str(k, value);
15119                         if (v) {
15120                             partial.push(quote(k) + (gap ? ': ' : ':') + v);
15121                         }
15122                     }
15123                 }
15124             }
15125
15126 // Join all of the member texts together, separated with commas,
15127 // and wrap them in braces.
15128
15129             v = partial.length === 0 ? '{}' : gap ?
15130                 '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
15131                 '{' + partial.join(',') + '}';
15132             gap = mind;
15133             return v;
15134         }
15135     }
15136
15137 // If the JSON object does not yet have a stringify method, give it one.
15138
15139     if (typeof JSON.stringify !== 'function') {
15140         JSON.stringify = function (value, replacer, space) {
15141
15142 // The stringify method takes a value and an optional replacer, and an optional
15143 // space parameter, and returns a JSON text. The replacer can be a function
15144 // that can replace values, or an array of strings that will select the keys.
15145 // A default replacer method can be provided. Use of the space parameter can
15146 // produce text that is more easily readable.
15147
15148             var i;
15149             gap = '';
15150             indent = '';
15151
15152 // If the space parameter is a number, make an indent string containing that
15153 // many spaces.
15154
15155             if (typeof space === 'number') {
15156                 for (i = 0; i < space; i += 1) {
15157                     indent += ' ';
15158                 }
15159
15160 // If the space parameter is a string, it will be used as the indent string.
15161
15162             } else if (typeof space === 'string') {
15163                 indent = space;
15164             }
15165
15166 // If there is a replacer, it must be a function or an array.
15167 // Otherwise, throw an error.
15168
15169             rep = replacer;
15170             if (replacer && typeof replacer !== 'function' &&
15171                     (typeof replacer !== 'object' ||
15172                     typeof replacer.length !== 'number')) {
15173                 throw new Error('JSON.stringify');
15174             }
15175
15176 // Make a fake root object containing our value under the key of ''.
15177 // Return the result of stringifying the value.
15178
15179             return str('', {'': value});
15180         };
15181     }
15182
15183
15184 // If the JSON object does not yet have a parse method, give it one.
15185
15186     if (typeof JSON.parse !== 'function') {
15187         JSON.parse = function (text, reviver) {
15188
15189 // The parse method takes a text and an optional reviver function, and returns
15190 // a JavaScript value if the text is a valid JSON text.
15191
15192             var j;
15193
15194             function walk(holder, key) {
15195
15196 // The walk method is used to recursively walk the resulting structure so
15197 // that modifications can be made.
15198
15199                 var k, v, value = holder[key];
15200                 if (value && typeof value === 'object') {
15201                     for (k in value) {
15202                         if (Object.prototype.hasOwnProperty.call(value, k)) {
15203                             v = walk(value, k);
15204                             if (v !== undefined) {
15205                                 value[k] = v;
15206                             } else {
15207                                 delete value[k];
15208                             }
15209                         }
15210                     }
15211                 }
15212                 return reviver.call(holder, key, value);
15213             }
15214
15215
15216 // Parsing happens in four stages. In the first stage, we replace certain
15217 // Unicode characters with escape sequences. JavaScript handles many characters
15218 // incorrectly, either silently deleting them, or treating them as line endings.
15219
15220             text = String(text);
15221             cx.lastIndex = 0;
15222             if (cx.test(text)) {
15223                 text = text.replace(cx, function (a) {
15224                     return '\\u' +
15225                         ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
15226                 });
15227             }
15228
15229 // In the second stage, we run the text against regular expressions that look
15230 // for non-JSON patterns. We are especially concerned with '()' and 'new'
15231 // because they can cause invocation, and '=' because it can cause mutation.
15232 // But just to be safe, we want to reject all unexpected forms.
15233
15234 // We split the second stage into 4 regexp operations in order to work around
15235 // crippling inefficiencies in IE's and Safari's regexp engines. First we
15236 // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
15237 // replace all simple value tokens with ']' characters. Third, we delete all
15238 // open brackets that follow a colon or comma or that begin the text. Finally,
15239 // we look to see that the remaining characters are only whitespace or ']' or
15240 // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
15241
15242             if (/^[\],:{}\s]*$/
15243                     .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
15244                         .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
15245                         .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
15246
15247 // In the third stage we use the eval function to compile the text into a
15248 // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
15249 // in JavaScript: it can begin a block or an object literal. We wrap the text
15250 // in parens to eliminate the ambiguity.
15251
15252                 j = eval('(' + text + ')');
15253
15254 // In the optional fourth stage, we recursively walk the new structure, passing
15255 // each name/value pair to a reviver function for possible transformation.
15256
15257                 return typeof reviver === 'function' ?
15258                     walk({'': j}, '') : j;
15259             }
15260
15261 // If the text is not JSON parseable, then a SyntaxError is thrown.
15262
15263             throw new SyntaxError('JSON.parse');
15264         };
15265     }
15266 }());
15267
15268 \r
15269 jQuery.extend({\r
15270         \r
15271 \r
15272     createUploadIframe: function(id, uri)\r
15273         {\r
15274                         //create frame\r
15275             var frameId = 'jUploadFrame' + id;\r
15276             var iframeHtml = '<iframe id="' + frameId + '" name="' + frameId + '" style="position:absolute; top:-9999px; left:-9999px"';\r
15277                         if(window.ActiveXObject)\r
15278                         {\r
15279                 if(typeof uri== 'boolean'){\r
15280                                         iframeHtml += ' src="' + 'javascript:false' + '"';\r
15281 \r
15282                 }\r
15283                 else if(typeof uri== 'string'){\r
15284                                         iframeHtml += ' src="' + uri + '"';\r
15285 \r
15286                 }       \r
15287                         }\r
15288                         iframeHtml += ' />';\r
15289                         jQuery(iframeHtml).appendTo(document.body);\r
15290 \r
15291             return jQuery('#' + frameId).get(0);                        \r
15292     },\r
15293     createUploadForm: function(id, fileElementId, data)\r
15294         {\r
15295                 //create form   \r
15296                 var formId = 'jUploadForm' + id;\r
15297                 var fileId = 'jUploadFile' + id;\r
15298                 var form = jQuery('<form  action="" method="POST" name="' + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');    \r
15299                 if(data)\r
15300                 {\r
15301                         for(var i in data)\r
15302                         {\r
15303                                 jQuery('<input type="hidden" name="' + i + '" value="' + data[i] + '" />').appendTo(form);\r
15304                         }                       \r
15305                 }               \r
15306                 var oldElement = jQuery('#' + fileElementId);\r
15307                 var newElement = jQuery(oldElement).clone();\r
15308                 jQuery(oldElement).attr('id', fileId);\r
15309                 jQuery(oldElement).before(newElement);\r
15310                 jQuery(oldElement).appendTo(form);\r
15311 \r
15312 \r
15313                 \r
15314                 //set attributes\r
15315                 jQuery(form).css('position', 'absolute');\r
15316                 jQuery(form).css('top', '-1200px');\r
15317                 jQuery(form).css('left', '-1200px');\r
15318                 jQuery(form).appendTo('body');          \r
15319                 return form;\r
15320     },\r
15321 \r
15322     ajaxFileUpload: function(s) {\r
15323         // TODO introduce global settings, allowing the client to modify them for all requests, not only timeout                \r
15324         s = jQuery.extend({}, jQuery.ajaxSettings, s);\r
15325         var id = new Date().getTime()        \r
15326                 var form = jQuery.createUploadForm(id, s.fileElementId, (typeof(s.data)=='undefined'?false:s.data));\r
15327                 var io = jQuery.createUploadIframe(id, s.secureuri);\r
15328                 var frameId = 'jUploadFrame' + id;\r
15329                 var formId = 'jUploadForm' + id;                \r
15330         // Watch for a new set of requests\r
15331         if ( s.global && ! jQuery.active++ )\r
15332                 {\r
15333                         jQuery.event.trigger( "ajaxStart" );\r
15334                 }            \r
15335         var requestDone = false;\r
15336         // Create the request object\r
15337         var xml = {}   \r
15338         if ( s.global )\r
15339             jQuery.event.trigger("ajaxSend", [xml, s]);\r
15340         // Wait for a response to come back\r
15341         var uploadCallback = function(isTimeout)\r
15342                 {                       \r
15343                         var io = document.getElementById(frameId);\r
15344             try \r
15345                         {                               \r
15346                                 if(io.contentWindow)\r
15347                                 {\r
15348                                          xml.responseText = io.contentWindow.document.body?io.contentWindow.document.body.innerHTML:null;\r
15349                          xml.responseXML = io.contentWindow.document.XMLDocument?io.contentWindow.document.XMLDocument:io.contentWindow.document;\r
15350                                          \r
15351                                 }else if(io.contentDocument)\r
15352                                 {\r
15353                                          xml.responseText = io.contentDocument.document.body?io.contentDocument.document.body.innerHTML:null;\r
15354                         xml.responseXML = io.contentDocument.document.XMLDocument?io.contentDocument.document.XMLDocument:io.contentDocument.document;\r
15355                                 }                                               \r
15356             }catch(e)\r
15357                         {\r
15358                                 jQuery.handleError(s, xml, null, e);\r
15359                         }\r
15360 \r
15361             var data = $(xml.responseText).html();\r
15362             if ( xml || isTimeout == "timeout") \r
15363                         {                               \r
15364                 requestDone = true;\r
15365                 var status;\r
15366                 try {\r
15367                     data = JSON.parse(data);\r
15368                     //check for error in return JSON\r
15369                     if(data.error){\r
15370                         status = "error";\r
15371                     }else{\r
15372                         status = "success";\r
15373                     }\r
15374                     \r
15375                     // Fire the global callback\r
15376                     if( s.global )\r
15377                         jQuery.event.trigger( "ajaxSuccess", [xml, s] );\r
15378                 } catch(e) {\r
15379                     status = "error";\r
15380                     jQuery.handleError(s, xml, status, e);\r
15381                 }\r
15382 \r
15383                 // The request was completed\r
15384                 if( s.global )\r
15385                     jQuery.event.trigger( "ajaxComplete", [xml, s] );\r
15386 \r
15387                 // Handle the global AJAX counter\r
15388                 if ( s.global && ! --jQuery.active )\r
15389                     jQuery.event.trigger( "ajaxStop" );\r
15390 \r
15391                 // Process result\r
15392                 if ( s.complete )\r
15393                     s.complete(data, status);\r
15394 \r
15395                 jQuery(io).unbind()\r
15396 \r
15397                 setTimeout(function()\r
15398                                                                         {       try \r
15399                                                                                 {\r
15400                                                                                         jQuery(io).remove();\r
15401                                                                                         jQuery(form).remove();  \r
15402                                                                                         \r
15403                                                                                 } catch(e) \r
15404                                                                                 {\r
15405                                                                                         jQuery.handleError(s, xml, null, e);\r
15406                                                                                 }                                                                       \r
15407 \r
15408                                                                         }, 100)\r
15409 \r
15410                 xml = null\r
15411 \r
15412             }\r
15413         }\r
15414         // Timeout checker\r
15415         if ( s.timeout > 0 ) \r
15416                 {\r
15417             setTimeout(function(){\r
15418                 // Check to see if the request is still happening\r
15419                 if( !requestDone ) uploadCallback( "timeout" );\r
15420             }, s.timeout);\r
15421         }\r
15422         try \r
15423                 {\r
15424 \r
15425                         var form = jQuery('#' + formId);\r
15426                         jQuery(form).attr('action', s.url);\r
15427                         jQuery(form).attr('method', 'POST');\r
15428                         jQuery(form).attr('target', frameId);\r
15429             if(form.encoding)\r
15430                         {\r
15431                                 jQuery(form).attr('encoding', 'multipart/form-data');                           \r
15432             }\r
15433             else\r
15434                         {       \r
15435                                 jQuery(form).attr('enctype', 'multipart/form-data');                    \r
15436             }                   \r
15437             jQuery(form).submit();\r
15438 \r
15439         } catch(e) \r
15440                 {                       \r
15441             jQuery.handleError(s, xml, null, e);\r
15442         }\r
15443                 \r
15444                 jQuery('#' + frameId).load(uploadCallback       );\r
15445         return {abort: function () {}}; \r
15446 \r
15447     },\r
15448 })\r
15449 \r
15450
15451 /*jslint browser: true */ /*global jQuery: true */
15452
15453 /**
15454  * jQuery Cookie plugin
15455  *
15456  * Copyright (c) 2010 Klaus Hartl (stilbuero.de)
15457  * Dual licensed under the MIT and GPL licenses:
15458  * http://www.opensource.org/licenses/mit-license.php
15459  * http://www.gnu.org/licenses/gpl.html
15460  *
15461  */
15462
15463 // TODO JsDoc
15464
15465 /**
15466  * Create a cookie with the given key and value and other optional parameters.
15467  *
15468  * @example $.cookie('the_cookie', 'the_value');
15469  * @desc Set the value of a cookie.
15470  * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
15471  * @desc Create a cookie with all available options.
15472  * @example $.cookie('the_cookie', 'the_value');
15473  * @desc Create a session cookie.
15474  * @example $.cookie('the_cookie', null);
15475  * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
15476  *       used when the cookie was set.
15477  *
15478  * @param String key The key of the cookie.
15479  * @param String value The value of the cookie.
15480  * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
15481  * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
15482  *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
15483  *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
15484  *                             when the the browser exits.
15485  * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
15486  * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
15487  * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
15488  *                        require a secure protocol (like HTTPS).
15489  * @type undefined
15490  *
15491  * @name $.cookie
15492  * @cat Plugins/Cookie
15493  * @author Klaus Hartl/klaus.hartl@stilbuero.de
15494  */
15495
15496 /**
15497  * Get the value of a cookie with the given key.
15498  *
15499  * @example $.cookie('the_cookie');
15500  * @desc Get the value of a cookie.
15501  *
15502  * @param String key The key of the cookie.
15503  * @return The value of the cookie.
15504  * @type String
15505  *
15506  * @name $.cookie
15507  * @cat Plugins/Cookie
15508  * @author Klaus Hartl/klaus.hartl@stilbuero.de
15509  */
15510 jQuery.cookie = function (key, value, options) {
15511     
15512     // key and at least value given, set cookie...
15513     if (arguments.length > 1 && String(value) !== "[object Object]") {
15514         options = jQuery.extend({}, options);
15515
15516         if (value === null || value === undefined) {
15517             options.expires = -1;
15518         }
15519
15520         if (typeof options.expires === 'number') {
15521             var days = options.expires, t = options.expires = new Date();
15522             t.setDate(t.getDate() + days);
15523         }
15524         
15525         value = String(value);
15526         
15527         return (document.cookie = [
15528             encodeURIComponent(key), '=',
15529             options.raw ? value : encodeURIComponent(value),
15530             options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
15531             options.path ? '; path=' + options.path : '',
15532             options.domain ? '; domain=' + options.domain : '',
15533             options.secure ? '; secure' : ''
15534         ].join(''));
15535     }
15536
15537     // key and possibly options given, get cookie...
15538     options = value || {};
15539     var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
15540     return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
15541 };
15542
15543 (function(/*! Stitch !*/) {
15544   if (!this.require) {
15545     var modules = {}, cache = {}, require = function(name, root) {
15546       var module = cache[name], path = expand(root, name), fn;
15547       if (module) {
15548         return module;
15549       } else if (fn = modules[path] || modules[path = expand(path, './index')]) {
15550         module = {id: name, exports: {}};
15551         try {
15552           cache[name] = module.exports;
15553           fn(module.exports, function(name) {
15554             return require(name, dirname(path));
15555           }, module);
15556           return cache[name] = module.exports;
15557         } catch (err) {
15558           delete cache[name];
15559           throw err;
15560         }
15561       } else {
15562         throw 'module \'' + name + '\' not found';
15563       }
15564     }, expand = function(root, name) {
15565       var results = [], parts, part;
15566       if (/^\.\.?(\/|$)/.test(name)) {
15567         parts = [root, name].join('/').split('/');
15568       } else {
15569         parts = name.split('/');
15570       }
15571       for (var i = 0, length = parts.length; i < length; i++) {
15572         part = parts[i];
15573         if (part == '..') {
15574           results.pop();
15575         } else if (part != '.' && part != '') {
15576           results.push(part);
15577         }
15578       }
15579       return results.join('/');
15580     }, dirname = function(path) {
15581       return path.split('/').slice(0, -1).join('/');
15582     };
15583     this.require = function(name) {
15584       return require(name, '');
15585     }
15586     this.require.define = function(bundle) {
15587       for (var key in bundle)
15588         modules[key] = bundle[key];
15589     };
15590   }
15591   return this.require.define;
15592 }).call(this)({"collections/locations": function(exports, require, module) {(function() {
15593   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
15594     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
15595     function ctor() { this.constructor = child; }
15596     ctor.prototype = parent.prototype;
15597     child.prototype = new ctor;
15598     child.__super__ = parent.prototype;
15599     return child;
15600   };
15601   exports.LocationsCollection = (function() {
15602     __extends(LocationsCollection, UberCollection);
15603     function LocationsCollection() {
15604       LocationsCollection.__super__.constructor.apply(this, arguments);
15605     }
15606     LocationsCollection.prototype.model = app.models.location;
15607     return LocationsCollection;
15608   })();
15609 }).call(this);
15610 }, "collections/payment_profiles": function(exports, require, module) {(function() {
15611   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
15612     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
15613     function ctor() { this.constructor = child; }
15614     ctor.prototype = parent.prototype;
15615     child.prototype = new ctor;
15616     child.__super__ = parent.prototype;
15617     return child;
15618   };
15619   exports.PaymentProfilesCollection = (function() {
15620     __extends(PaymentProfilesCollection, UberCollection);
15621     function PaymentProfilesCollection() {
15622       PaymentProfilesCollection.__super__.constructor.apply(this, arguments);
15623     }
15624     PaymentProfilesCollection.prototype.model = app.models.paymentprofile;
15625     return PaymentProfilesCollection;
15626   })();
15627 }).call(this);
15628 }, "collections/trips": function(exports, require, module) {(function() {
15629   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
15630     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
15631     function ctor() { this.constructor = child; }
15632     ctor.prototype = parent.prototype;
15633     child.prototype = new ctor;
15634     child.__super__ = parent.prototype;
15635     return child;
15636   };
15637   exports.TripsCollection = (function() {
15638     __extends(TripsCollection, UberCollection);
15639     function TripsCollection() {
15640       TripsCollection.__super__.constructor.apply(this, arguments);
15641     }
15642     TripsCollection.prototype.model = app.models.trip;
15643     TripsCollection.prototype.url = '/trips';
15644     TripsCollection.prototype.relationships = 'client,driver,city';
15645     return TripsCollection;
15646   })();
15647 }).call(this);
15648 }, "lib/config": function(exports, require, module) {(function() {
15649   var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
15650   exports.config = (function() {
15651     function config() {
15652       this.get = __bind(this.get, this);
15653     }
15654     config.prototype.type = 'production';
15655     config.prototype.configurations = {
15656       'development': {
15657         'api': '/api',
15658         'dispatch': '/cn',
15659         'url': 'http://dev.www.uber.com:8080',
15660         'googleJsApiKey': 'ABQIAAAAKSiLiNwCxOW479xGFqHoTBTsMh9mumH-zfDa0AhzI7RTmmqoCRTv2C11J43hXCK7vZguPC7CgGDcNQ',
15661         'debug': 'true',
15662         'cache': '1'
15663       },
15664       'production': {
15665         'api': '/api',
15666         'dispatch': '/cn',
15667         'url': 'http://www.uber.com',
15668         'googleJsApiKey': 'ABQIAAAAKSiLiNwCxOW479xGFqHoTBTsMh9mumH-zfDa0AhzI7RTmmqoCRTv2C11J43hXCK7vZguPC7CgGDcNQ',
15669         'debug': 'false',
15670         'cache': '60'
15671       },
15672       'development-vm': {
15673         'api': 'http://192.168.106.1:6543/api',
15674         'url': 'http://192.168.106.1:8080',
15675         'dispatch': '',
15676         'googleJsApiKey': 'ABQIAAAAKSiLiNwCxOW479xGFqHoTBTsMh9mumH-zfDa0AhzI7RTmmqoCRTv2C11J43hXCK7vZguPC7CgGDcNQ',
15677         'debug': 'true',
15678         'cache': '1'
15679       }
15680     };
15681     config.prototype.get = function(param) {
15682       if (this.configurations[this.type][param] === void 0) {
15683         return '';
15684       }
15685       return this.configurations[this.type][param];
15686     };
15687     return config;
15688   })();
15689 }).call(this);
15690 }, "lib/uber_collection": function(exports, require, module) {(function() {
15691   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
15692     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
15693     function ctor() { this.constructor = child; }
15694     ctor.prototype = parent.prototype;
15695     child.prototype = new ctor;
15696     child.__super__ = parent.prototype;
15697     return child;
15698   };
15699   exports.UberCollection = (function() {
15700     __extends(UberCollection, Backbone.Collection);
15701     function UberCollection() {
15702       UberCollection.__super__.constructor.apply(this, arguments);
15703     }
15704     UberCollection.prototype.parse = function(data) {
15705       if (data.meta) {
15706         this.meta = data.meta;
15707         return data.resources;
15708       }
15709       return data;
15710     };
15711     return UberCollection;
15712   })();
15713 }).call(this);
15714 }, "lib/uber_controller": function(exports, require, module) {(function() {
15715   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
15716     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
15717     function ctor() { this.constructor = child; }
15718     ctor.prototype = parent.prototype;
15719     child.prototype = new ctor;
15720     child.__super__ = parent.prototype;
15721     return child;
15722   };
15723   exports.UberController = (function() {
15724     __extends(UberController, Backbone.Router);
15725     function UberController() {
15726       UberController.__super__.constructor.apply(this, arguments);
15727     }
15728     UberController.prototype.LoggedInRedirect = function(callback) {
15729       if ($.cookie('token') !== null) {
15730         return app.routers.clients.navigate('!/dashboard', true);
15731       } else {
15732         if (typeof callback === 'function') {
15733           return callback.call();
15734         }
15735       }
15736     };
15737     UberController.prototype.LoggedOutRedirect = function(callback) {
15738       if ($.cookie('token') === null) {
15739         return app.routers.clients.navigate('!/sign-in', true);
15740       } else {
15741         if (typeof callback === 'function') {
15742           return callback.call();
15743         }
15744       }
15745     };
15746     return UberController;
15747   })();
15748 }).call(this);
15749 }, "lib/uber_sync": function(exports, require, module) {(function() {
15750   exports.UberSync = function(method, model, options) {
15751     var methodMap, params, type;
15752     methodMap = {
15753       'create': 'POST',
15754       'update': 'PUT',
15755       'delete': 'DELETE',
15756       'read': 'GET'
15757     };
15758     type = methodMap[method];
15759     params = _.extend({
15760       type: type
15761     }, options);
15762     params.url = _.isString(this.url) ? API + this.url : API + this.url(type);
15763     if (type === "DELETE") {
15764       params.url = "" + params.url + "?token=" + USER.token;
15765     }
15766     if (!params.data && model && (method === 'create' || method === 'update')) {
15767       params.data = JSON.parse(JSON.stringify(model.toJSON()));
15768     }
15769     if (Backbone.emulateJSON) {
15770       params.contentType = 'application/x-www-form-urlencoded';
15771       params.processData = true;
15772       params.data = params.data ? {
15773         model: params.data
15774       } : {};
15775     }
15776     if (Backbone.emulateHTTP) {
15777       if (type === 'PUT' || type === 'DELETE') {
15778         if (Backbone.emulateJSON) {
15779           params.data._method = type;
15780         }
15781         params.type = 'POST';
15782         params.beforeSend = function(xhr) {
15783           return xhr.setRequestHeader('X-HTTP-Method-Override', type);
15784         };
15785       }
15786     }
15787     if (!params.data) {
15788       params.data = {};
15789     }
15790     if (!params.data.token && $.cookie('token')) {
15791       params.data.token = $.cookie('token');
15792     }
15793     params.dataType = 'json';
15794     params.cache = false;
15795     return $.ajax(params);
15796   };
15797 }).call(this);
15798 }, "lib/uber_view": function(exports, require, module) {(function() {
15799   var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
15800     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
15801     function ctor() { this.constructor = child; }
15802     ctor.prototype = parent.prototype;
15803     child.prototype = new ctor;
15804     child.__super__ = parent.prototype;
15805     return child;
15806   };
15807   exports.UberView = (function() {
15808     __extends(UberView, Backbone.View);
15809     function UberView() {
15810       this.DownloadUserTrips = __bind(this.DownloadUserTrips, this);
15811       UberView.__super__.constructor.apply(this, arguments);
15812     }
15813     UberView.prototype.place = function(content) {
15814       var $target;
15815       $target = this.options.scope ? this.options.scope.find(this.options.selector) : $(this.options.selector);
15816       $target[this.options.method || 'html'](content || this.el);
15817       this.delegateEvents();
15818       return this;
15819     };
15820     UberView.prototype.mixin = function(m, args) {
15821       var events, self;
15822       if (args == null) {
15823         args = {};
15824       }
15825       self = this;
15826       events = m._events;
15827       _.extend(this, m);
15828       if (m.initialize) {
15829         m.initialize(self, args);
15830       }
15831       return _.each(_.keys(events), function(key) {
15832         var event, func, selector, split;
15833         split = key.split(' ');
15834         event = split[0];
15835         selector = split[1];
15836         func = events[key];
15837         return $(self.el).find(selector).live(event, function(e) {
15838           return self[func](e);
15839         });
15840       });
15841     };
15842     UberView.prototype.RefreshUserInfo = function(callback, silent) {
15843       if (silent == null) {
15844         silent = false;
15845       }
15846       try {
15847         this.model = new app.models.client({
15848           id: amplify.store('USERjson').id
15849         });
15850       } catch (e) {
15851         if (e.name.toString() === "TypeError") {
15852           app.routers.clients.navigate('!/sign-out', true);
15853         } else {
15854           throw e;
15855         }
15856       }
15857       if (!silent) {
15858         this.ShowSpinner("load");
15859       }
15860       return this.model.fetch({
15861         success: __bind(function() {
15862           this.HideSpinner();
15863           $.cookie('token', this.model.get('token'));
15864           amplify.store('USERjson', this.model);
15865           this.ReadUserInfo(true);
15866           if (typeof callback === 'function') {
15867             return callback.call();
15868           }
15869         }, this),
15870         data: {
15871           relationships: 'unexpired_client_promotions,locations,credit_balance,payment_gateway.payment_profiles,client_bills_in_arrears.client_transaction,country'
15872         },
15873         dataType: 'json'
15874       });
15875     };
15876     UberView.prototype.ReadUserInfo = function(forced) {
15877       if (forced == null) {
15878         forced = false;
15879       }
15880       if (!window.USER.id) {
15881         window.USER = amplify.store('USERjson');
15882       }
15883       if (forced) {
15884         return window.USER = amplify.store('USERjson');
15885       }
15886     };
15887     UberView.prototype.DownloadUserPromotions = function(callback, forced) {
15888       var downloadData, stored;
15889       if (forced == null) {
15890         forced = false;
15891       }
15892       downloadData = __bind(function() {
15893         this.ShowSpinner("load");
15894         this.model = new app.models.client({
15895           id: amplify.store('USERjson').id
15896         });
15897         return this.model.fetch({
15898           success: __bind(function() {
15899             window.USER.client_promotions = this.model.get('valid_client_promotions');
15900             this.CacheData('USERPromos', this.model.get('valid_client_promotions'));
15901             if (typeof callback === 'function') {
15902               return callback.call();
15903             }
15904           }, this),
15905           data: {
15906             relationships: 'valid_client_promotions.trips_remaining'
15907           },
15908           dataType: 'json'
15909         });
15910       }, this);
15911       stored = this.GetCache('USERPromos');
15912       if (stored && !forced) {
15913         window.USER.client_promotions = stored;
15914         if (typeof callback === 'function') {
15915           callback.call();
15916         }
15917       } else {
15918         downloadData();
15919       }
15920     };
15921     UberView.prototype.DownloadUserTrips = function(callback, forced, limit) {
15922       var downloadData, stored;
15923       if (forced == null) {
15924         forced = false;
15925       }
15926       if (limit == null) {
15927         limit = 1000;
15928       }
15929       downloadData = __bind(function() {
15930         this.ShowSpinner("load");
15931         return app.collections.trips.fetch({
15932           data: {
15933             status: 'completed,canceled',
15934             relationships: 'driver,city',
15935             client_id: USER.id,
15936             limit: limit
15937           },
15938           success: __bind(function() {
15939             window.USER.trips = app.collections.trips;
15940             this.CacheData('USERtrips', window.USER.trips);
15941             if (typeof callback === 'function') {
15942               callback.call();
15943             }
15944             return this.HideSpinner();
15945           }, this),
15946           dataType: 'json'
15947         });
15948       }, this);
15949       stored = this.GetCache("USERtrips");
15950       if (stored && !forced) {
15951         if (app.collections.trips.length !== stored.length) {
15952           app.collections.trips.reset(stored);
15953         }
15954         window.USER.trips = app.collections.trips;
15955         if (typeof callback === 'function') {
15956           return callback.call();
15957         }
15958       } else {
15959         return downloadData();
15960       }
15961     };
15962     UberView.prototype.ShowSpinner = function(type) {
15963       if (type == null) {
15964         type = 'load';
15965       }
15966       return $('.spinner#' + type).show();
15967     };
15968     UberView.prototype.HideSpinner = function() {
15969       return $('.spinner').hide();
15970     };
15971     UberView.prototype.RequireMaps = function(callback) {
15972       if (typeof google !== 'undefined' && google.maps) {
15973         return callback();
15974       } else {
15975         return $.getScript("https://www.google.com/jsapi?key=" + (app.config.get('googleJsApiKey')), function() {
15976           return google.load('maps', 3, {
15977             callback: callback,
15978             other_params: 'sensor=false&language=en&libraries=places'
15979           });
15980         });
15981       }
15982     };
15983     UberView.prototype.CacheData = function(storeName, data) {
15984       var currentTime;
15985       amplify.store(storeName, data);
15986       currentTime = new Date();
15987       amplify.store("" + storeName + "TS", currentTime.getTime());
15988     };
15989     UberView.prototype.GetCache = function(storeName) {
15990       var cacheTime, currentTime, storedTime;
15991       cacheTime = parseInt(app.config.get('cache')) * 60 * 1000;
15992       currentTime = new Date();
15993       currentTime = currentTime.getTime();
15994       storedTime = amplify.store("" + storeName + "TS");
15995       if (storedTime) {
15996         if (currentTime - storedTime < cacheTime) {
15997           return amplify.store(storeName);
15998         }
15999       }
16000       amplify.store("" + storeName + "TS", null);
16001       amplify.store(storeName, null);
16002       return false;
16003     };
16004     UberView.prototype.ClearGlobalStatus = function() {
16005       $('#global_status').find(".success_message").html("").hide();
16006       return $('#global_status').find(".error_message").html("").hide();
16007     };
16008     UberView.prototype.ShowError = function(message) {
16009       if (message == null) {
16010         message = "Error";
16011       }
16012       this.ClearGlobalStatus();
16013       return $('#global_status').find(".error_message").html(message).fadeIn();
16014     };
16015     UberView.prototype.ShowSuccess = function(message) {
16016       if (message == null) {
16017         message = "Success";
16018       }
16019       this.ClearGlobalStatus();
16020       return $('#global_status').find(".success_message").html(message).fadeIn('slow');
16021     };
16022     return UberView;
16023   })();
16024 }).call(this);
16025 }, "main": function(exports, require, module) {(function() {
16026   var ClientsBillingView, ClientsDashboardView, ClientsForgotPasswordView, ClientsInviteView, ClientsLoginView, ClientsPromotionsView, ClientsRequestsView, ClientsRouter, ClientsSettingsView, ClientsSignUpView, Config, ConfirmEmailView, CountriesCollection, CreditCardView, LocationsCollection, PaymentProfilesCollection, SharedFooterView, SharedMenuView, TripDetailView, TripsCollection;
16027   Config = require('lib/config').config;
16028   window.i18n = require('web-lib/i18n').i18n;
16029   i18n.init();
16030   Backbone.sync = require('lib/uber_sync').UberSync;
16031   window.USER = {};
16032   window.UberView = require('lib/uber_view').UberView;
16033   window.UberCollection = require('lib/uber_collection').UberCollection;
16034   window.UberController = require('lib/uber_controller').UberController;
16035   window.app = {};
16036   app.routers = {};
16037   app.models = {};
16038   app.collections = {};
16039   app.views = {};
16040   app.views.pages = {};
16041   app.views.clients = {};
16042   app.views.clients.modules = {};
16043   app.views.shared = {};
16044   app.views.pages.modules = {};
16045   app.helpers = require('web-lib/helpers').helpers;
16046   app.weblib_helpers = app.helpers;
16047   app.models.client = require('models/client').Client;
16048   app.models.trip = require('models/trip').Trip;
16049   app.models.paymentprofile = require('models/paymentprofile').PaymentProfile;
16050   app.models.clientbills = require('models/clientbills').ClientBills;
16051   app.models.promotions = require('models/promotions').Promotions;
16052   app.models.location = require('models/location').Location;
16053   app.models.country = require('web-lib/models/country').Country;
16054   TripsCollection = require('collections/trips').TripsCollection;
16055   PaymentProfilesCollection = require('collections/payment_profiles').PaymentProfilesCollection;
16056   LocationsCollection = require('collections/locations').LocationsCollection;
16057   CountriesCollection = require('web-lib/collections/countries').CountriesCollection;
16058   ClientsRouter = require('routers/clients_controller').ClientsRouter;
16059   SharedMenuView = require('views/shared/menu').SharedMenuView;
16060   SharedFooterView = require('web-lib/views/footer').SharedFooterView;
16061   ClientsSignUpView = require('views/clients/sign_up').ClientsSignUpView;
16062   ClientsLoginView = require('views/clients/login').ClientsLoginView;
16063   ClientsForgotPasswordView = require('views/clients/forgot_password').ClientsForgotPasswordView;
16064   ClientsDashboardView = require('views/clients/dashboard').ClientsDashboardView;
16065   ClientsInviteView = require('views/clients/invite').ClientsInviteView;
16066   ConfirmEmailView = require('views/clients/confirm_email').ClientsConfirmEmailView;
16067   ClientsPromotionsView = require('views/clients/promotions').ClientsPromotionsView;
16068   ClientsBillingView = require('views/clients/billing').ClientsBillingView;
16069   ClientsSettingsView = require('views/clients/settings').ClientsSettingsView;
16070   ClientsRequestsView = require('views/clients/request').ClientsRequestView;
16071   TripDetailView = require('views/clients/trip_detail').TripDetailView;
16072   CreditCardView = require('views/clients/modules/credit_card').CreditCardView;
16073   $(document).ready(function() {
16074     app.initialize = function() {
16075       var key, _i, _len, _ref;
16076       window.USER = new app.models.client;
16077       if ($.cookie('redirected_user')) {
16078         _ref = _.keys(amplify.store());
16079         for (_i = 0, _len = _ref.length; _i < _len; _i++) {
16080           key = _ref[_i];
16081           amplify.store(key, null);
16082         }
16083         $.cookie('user', $.cookie('redirected_user'));
16084         $.cookie('token', JSON.parse($.cookie('user')).token);
16085         amplify.store('USERjson', JSON.parse($.cookie('user')));
16086         $.cookie('redirected_user', null, {
16087           domain: '.uber.com'
16088         });
16089       }
16090       if ($.cookie('user')) {
16091         USER.set(JSON.parse($.cookie('user')));
16092       }
16093       app.config = new Config();
16094       window.API = app.config.get('api');
16095       window.DISPATCH = app.config.get('dispatch');
16096       app.routers.clients = new ClientsRouter();
16097       app.collections.trips = new TripsCollection();
16098       app.collections.paymentprofiles = new PaymentProfilesCollection();
16099       app.collections.locations = LocationsCollection;
16100       app.collections.countries = CountriesCollection;
16101       app.views.clients.create = new ClientsSignUpView();
16102       app.views.clients.read = new ClientsLoginView();
16103       app.views.clients.forgotpassword = new ClientsForgotPasswordView();
16104       app.views.clients.dashboard = new ClientsDashboardView();
16105       app.views.clients.invite = new ClientsInviteView();
16106       app.views.clients.promotions = new ClientsPromotionsView();
16107       app.views.clients.settings = new ClientsSettingsView();
16108       app.views.clients.tripdetail = new TripDetailView();
16109       app.views.clients.billing = new ClientsBillingView();
16110       app.views.clients.confirmemail = new ConfirmEmailView();
16111       app.views.clients.request = new ClientsRequestsView();
16112       app.views.shared.menu = new SharedMenuView();
16113       app.views.shared.footer = new SharedFooterView();
16114       app.views.clients.modules.creditcard = CreditCardView;
16115       if (Backbone.history.getFragment() === '') {
16116         return app.routers.clients.navigate('!/sign-in', true);
16117       }
16118     };
16119     app.refreshMenu = function() {
16120       $('header').html(app.views.shared.menu.render().el);
16121       return $('footer').html(app.views.shared.footer.render().el);
16122     };
16123     app.initialize();
16124     app.refreshMenu();
16125     return Backbone.history.start();
16126   });
16127 }).call(this);
16128 }, "models/client": function(exports, require, module) {(function() {
16129   var UberModel;
16130   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
16131     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
16132     function ctor() { this.constructor = child; }
16133     ctor.prototype = parent.prototype;
16134     child.prototype = new ctor;
16135     child.__super__ = parent.prototype;
16136     return child;
16137   };
16138   UberModel = require('web-lib/uber_model').UberModel;
16139   exports.Client = (function() {
16140     __extends(Client, UberModel);
16141     function Client() {
16142       Client.__super__.constructor.apply(this, arguments);
16143     }
16144     Client.prototype.url = function() {
16145       if (this.id) {
16146         return "/clients/" + this.id;
16147       } else {
16148         return "/clients";
16149       }
16150     };
16151     return Client;
16152   })();
16153 }).call(this);
16154 }, "models/clientbills": function(exports, require, module) {(function() {
16155   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
16156     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
16157     function ctor() { this.constructor = child; }
16158     ctor.prototype = parent.prototype;
16159     child.prototype = new ctor;
16160     child.__super__ = parent.prototype;
16161     return child;
16162   };
16163   exports.ClientBills = (function() {
16164     __extends(ClientBills, Backbone.Model);
16165     function ClientBills() {
16166       ClientBills.__super__.constructor.apply(this, arguments);
16167     }
16168     ClientBills.prototype.url = function() {
16169       return "/client_bills/" + this.id;
16170     };
16171     return ClientBills;
16172   })();
16173 }).call(this);
16174 }, "models/location": function(exports, require, module) {(function() {
16175   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
16176     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
16177     function ctor() { this.constructor = child; }
16178     ctor.prototype = parent.prototype;
16179     child.prototype = new ctor;
16180     child.__super__ = parent.prototype;
16181     return child;
16182   };
16183   exports.Location = (function() {
16184     __extends(Location, Backbone.Model);
16185     function Location() {
16186       Location.__super__.constructor.apply(this, arguments);
16187     }
16188     Location.prototype.url = function() {
16189       if (this.id) {
16190         return "/locations/" + this.id;
16191       } else {
16192         return "/locations";
16193       }
16194     };
16195     return Location;
16196   })();
16197 }).call(this);
16198 }, "models/paymentprofile": function(exports, require, module) {(function() {
16199   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
16200     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
16201     function ctor() { this.constructor = child; }
16202     ctor.prototype = parent.prototype;
16203     child.prototype = new ctor;
16204     child.__super__ = parent.prototype;
16205     return child;
16206   };
16207   exports.PaymentProfile = (function() {
16208     __extends(PaymentProfile, Backbone.Model);
16209     function PaymentProfile() {
16210       PaymentProfile.__super__.constructor.apply(this, arguments);
16211     }
16212     PaymentProfile.prototype.url = function() {
16213       if (this.id) {
16214         return "/payment_profiles/" + this.id;
16215       } else {
16216         return "/payment_profiles";
16217       }
16218     };
16219     return PaymentProfile;
16220   })();
16221 }).call(this);
16222 }, "models/promotions": function(exports, require, module) {(function() {
16223   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
16224     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
16225     function ctor() { this.constructor = child; }
16226     ctor.prototype = parent.prototype;
16227     child.prototype = new ctor;
16228     child.__super__ = parent.prototype;
16229     return child;
16230   };
16231   exports.Promotions = (function() {
16232     __extends(Promotions, Backbone.Model);
16233     function Promotions() {
16234       Promotions.__super__.constructor.apply(this, arguments);
16235     }
16236     Promotions.prototype.url = function() {
16237       return "/clients_promotions";
16238     };
16239     return Promotions;
16240   })();
16241 }).call(this);
16242 }, "models/trip": function(exports, require, module) {(function() {
16243   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
16244     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
16245     function ctor() { this.constructor = child; }
16246     ctor.prototype = parent.prototype;
16247     child.prototype = new ctor;
16248     child.__super__ = parent.prototype;
16249     return child;
16250   };
16251   exports.Trip = (function() {
16252     __extends(Trip, Backbone.Model);
16253     function Trip() {
16254       Trip.__super__.constructor.apply(this, arguments);
16255     }
16256     Trip.prototype.url = function() {
16257       return "/trips/" + (this.get('id'));
16258     };
16259     return Trip;
16260   })();
16261 }).call(this);
16262 }, "routers/clients_controller": function(exports, require, module) {(function() {
16263   var ClientsLoginView;
16264   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
16265     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
16266     function ctor() { this.constructor = child; }
16267     ctor.prototype = parent.prototype;
16268     child.prototype = new ctor;
16269     child.__super__ = parent.prototype;
16270     return child;
16271   };
16272   ClientsLoginView = require('views/clients/login').ClientsLoginView;
16273   exports.ClientsRouter = (function() {
16274     __extends(ClientsRouter, UberController);
16275     function ClientsRouter() {
16276       ClientsRouter.__super__.constructor.apply(this, arguments);
16277     }
16278     ClientsRouter.prototype.routes = {
16279       "!/sign-up": "signup",
16280       "!/sign-in": "signin",
16281       "!/sign-out": "signout",
16282       "!/forgot-password": "forgotpassword",
16283       "!/forgot-password?email_token=:token": "passwordReset",
16284       "!/dashboard": "dashboard",
16285       "!/invite": "invite",
16286       "!/promotions": "promotions",
16287       "!/settings/information": "settingsInfo",
16288       "!/settings/picture": "settingsPic",
16289       "!/settings/locations": "settingsLoc",
16290       "!/trip/:id": "tripDetail",
16291       "!/billing": "billing",
16292       "!/confirm-email?token=:token": "confirmEmail",
16293       "!/invite/:invite": "signupInvite",
16294       "!/request": "request"
16295     };
16296     ClientsRouter.prototype.signup = function(invite) {
16297       var renderContent;
16298       if (invite == null) {
16299         invite = "";
16300       }
16301       renderContent = function() {
16302         $('section').html(app.views.clients.create.render(invite).el);
16303         document.title = t('Sign Up') + ' | ' + t('Uber');
16304         $('a').removeClass('active');
16305         return $('a[href="/#!/sign-up"]').addClass('active');
16306       };
16307       return this.LoggedInRedirect(renderContent);
16308     };
16309     ClientsRouter.prototype.signupInvite = function(invite) {
16310       return this.signup(invite);
16311     };
16312     ClientsRouter.prototype.forgotpassword = function() {
16313       var renderContent;
16314       renderContent = function() {
16315         $('section').html(app.views.clients.forgotpassword.render().el);
16316         return document.title = t('Password Recovery') + ' | ' + t('Uber');
16317       };
16318       return this.LoggedInRedirect(renderContent);
16319     };
16320     ClientsRouter.prototype.signin = function() {
16321       var renderContent;
16322       renderContent = function() {
16323         var view;
16324         document.title = t('Login') + ' | ' + t('Uber');
16325         view = new ClientsLoginView({
16326           selector: 'section'
16327         });
16328         $('a').removeClass('active');
16329         return $('a[href="/#!/sign-in"]').addClass('active');
16330       };
16331       return this.LoggedInRedirect(renderContent);
16332     };
16333     ClientsRouter.prototype.signout = function() {
16334       $.cookie('token', null);
16335       $.cookie('user', null);
16336       amplify.store('USERjson', null);
16337       amplify.store('USERtrips', null);
16338       amplify.store('USERPromos', null);
16339       app.refreshMenu();
16340       return app.routers.clients.navigate('!/sign-in', true);
16341     };
16342     ClientsRouter.prototype.dashboard = function() {
16343       var renderContent;
16344       renderContent = function() {
16345         $('section').html(app.views.clients.dashboard.render().el);
16346         document.title = t('Dashboard') + ' | ' + t('Uber');
16347         $('a').removeClass('active');
16348         return $('a[href="/#!/dashboard"]').addClass('active');
16349       };
16350       return this.LoggedOutRedirect(renderContent);
16351     };
16352     ClientsRouter.prototype.invite = function() {
16353       var renderContent;
16354       renderContent = function() {
16355         $('section').html(app.views.clients.invite.render().el);
16356         document.title = t('Invite Friends') + ' | ' + t('Uber');
16357         $('a').removeClass('active');
16358         return $('a[href="/#!/invite"]').addClass('active');
16359       };
16360       return this.LoggedOutRedirect(renderContent);
16361     };
16362     ClientsRouter.prototype.tripDetail = function(id) {
16363       var renderContent;
16364       renderContent = function() {
16365         $('a').removeClass('active');
16366         $('section').html(app.views.clients.tripdetail.render(id).el);
16367         return document.title = t('Trip Detail') + ' | ' + t('Uber');
16368       };
16369       return this.LoggedOutRedirect(renderContent);
16370     };
16371     ClientsRouter.prototype.promotions = function() {
16372       var renderContent;
16373       renderContent = function() {
16374         $('section').html(app.views.clients.promotions.render().el);
16375         document.title = t('Promotions') + ' | ' + t('Uber');
16376         $('a').removeClass('active');
16377         return $('a[href="/#!/promotions"]').addClass('active');
16378       };
16379       return this.LoggedOutRedirect(renderContent);
16380     };
16381     ClientsRouter.prototype.settingsInfo = function() {
16382       var renderContent;
16383       renderContent = function() {
16384         $('section').html(app.views.clients.settings.render('info').el);
16385         $('a').removeClass('active');
16386         return $('a[href="/#!/settings/information"]').addClass('active');
16387       };
16388       return this.LoggedOutRedirect(renderContent);
16389     };
16390     ClientsRouter.prototype.settingsLoc = function() {
16391       var renderContent;
16392       renderContent = function() {
16393         $('section').html(app.views.clients.settings.render('loc').el);
16394         $('a').removeClass('active');
16395         return $('a[href="/#!/settings/information"]').addClass('active');
16396       };
16397       return this.LoggedOutRedirect(renderContent);
16398     };
16399     ClientsRouter.prototype.settingsPic = function() {
16400       var renderContent;
16401       renderContent = function() {
16402         $('section').html(app.views.clients.settings.render('pic').el);
16403         $('a').removeClass('active');
16404         return $('a[href="/#!/settings/information"]').addClass('active');
16405       };
16406       return this.LoggedOutRedirect(renderContent);
16407     };
16408     ClientsRouter.prototype.passwordReset = function(token) {
16409       var renderContent;
16410       if (token == null) {
16411         token = '';
16412       }
16413       renderContent = function() {
16414         $('section').html(app.views.clients.forgotpassword.render(token).el);
16415         document.title = t('Password Reset') + ' | ' + t('Uber');
16416         return $('a').removeClass('active');
16417       };
16418       return this.LoggedInRedirect(renderContent);
16419     };
16420     ClientsRouter.prototype.billing = function() {
16421       var renderContent;
16422       renderContent = function() {
16423         $('section').html(app.views.clients.billing.render().el);
16424         document.title = t('Billing') + ' | ' + t('Uber');
16425         $('a').removeClass('active');
16426         return $('a[href="/#!/billing"]').addClass('active');
16427       };
16428       return this.LoggedOutRedirect(renderContent);
16429     };
16430     ClientsRouter.prototype.confirmEmail = function(token) {
16431       $('section').html(app.views.clients.confirmemail.render(token).el);
16432       document.title = t('Confirm Email') + ' | ' + t('Uber');
16433       return $('a').removeClass('active');
16434     };
16435     ClientsRouter.prototype.request = function() {
16436       var renderContent;
16437       renderContent = function() {
16438         $('section').html(app.views.clients.request.render().el);
16439         document.title = t('Request Ride') + ' | ' + t('Uber');
16440         $('a').removeClass('active');
16441         return $('a[href="/#!/request"]').addClass('active');
16442       };
16443       return this.LoggedOutRedirect(renderContent);
16444     };
16445     ClientsRouter.prototype.errorPage = function(path) {
16446       if (path == null) {
16447         path = '';
16448       }
16449       return app.helpers.debug(path, "path");
16450     };
16451     return ClientsRouter;
16452   })();
16453 }).call(this);
16454 }, "templates/clients/billing": function(exports, require, module) {module.exports = function(__obj) {
16455   if (!__obj) __obj = {};
16456   var __out = [], __capture = function(callback) {
16457     var out = __out, result;
16458     __out = [];
16459     callback.call(this);
16460     result = __out.join('');
16461     __out = out;
16462     return __safe(result);
16463   }, __sanitize = function(value) {
16464     if (value && value.ecoSafe) {
16465       return value;
16466     } else if (typeof value !== 'undefined' && value != null) {
16467       return __escape(value);
16468     } else {
16469       return '';
16470     }
16471   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
16472   __safe = __obj.safe = function(value) {
16473     if (value && value.ecoSafe) {
16474       return value;
16475     } else {
16476       if (!(typeof value !== 'undefined' && value != null)) value = '';
16477       var result = new String(value);
16478       result.ecoSafe = true;
16479       return result;
16480     }
16481   };
16482   if (!__escape) {
16483     __escape = __obj.escape = function(value) {
16484       return ('' + value)
16485         .replace(/&/g, '&amp;')
16486         .replace(/</g, '&lt;')
16487         .replace(/>/g, '&gt;')
16488         .replace(/"/g, '&quot;');
16489     };
16490   }
16491   (function() {
16492     (function() {
16493       var arrears, numCards, printArrear, printCardOption;
16494       numCards = parseInt(USER.payment_gateway.payment_profiles.length);
16495       __out.push('\n');
16496       arrears = USER.client_bills_in_arrears;
16497       __out.push('\n\n');
16498       printCardOption = function(card) {
16499         __out.push('\n  <option value="');
16500         __out.push(__sanitize(card.id));
16501         __out.push('"> ');
16502         __out.push(__sanitize(t('Card Ending in')));
16503         __out.push(' ');
16504         __out.push(__sanitize(card.card_number));
16505         return __out.push(' </option>\n');
16506       };
16507       __out.push('\n\n');
16508       printArrear = function(arrear) {
16509         __out.push('\n<tr>\n  <td>\n    <a href="#!/trip/');
16510         __out.push(__sanitize(arrear.client_transaction.trip_id));
16511         __out.push('"> <img src="https://uber-static.s3.amazonaws.com/map_icon.png" alt="');
16512         __out.push(__sanitize(t('Trip Map')));
16513         __out.push('" /></a>\n    <div class="arrear_info">\n      <span id="amount"> ');
16514         __out.push(__sanitize(t('Amount', {
16515           amount: app.helpers.formatCurrency(Math.abs(arrear.client_transaction.amount))
16516         })));
16517         __out.push(' </span>\n      <span id="date"> ');
16518         __out.push(__sanitize(t('Last Attempt to Bill', {
16519           date: app.helpers.parseDate(arrear.updated_at)
16520         })));
16521         __out.push(' </span>\n    </div>\n  </td>\n  ');
16522         if (numCards !== 0) {
16523           __out.push('\n    <td>\n      <p class="error_message"></p>\n      <p class="success_message"></p>\n      <select id="card_to_charge">\n        ');
16524           _.each(USER.payment_gateway.payment_profiles, printCardOption);
16525           __out.push('\n      </select>\n      <button class="button charge_arrear" id="');
16526           __out.push(__sanitize(arrear.id));
16527           __out.push('" data-theme="a"><span>');
16528           __out.push(__sanitize(t('Charge')));
16529           __out.push('</span></button>\n    </td>\n  ');
16530         }
16531         return __out.push('\n</tr>\n');
16532       };
16533       __out.push('\n\n\n\n');
16534       __out.push(require('templates/clients/modules/sub_header').call(this, {
16535         heading: t("Billing")
16536       }));
16537       __out.push('\n\n<div id="main_content">\n  <div>\n    <div id="credit_card_wrapper">\n      <div id="global_status">\n        <span class="success_message"></span>\n        <span class="error_message"></span>\n      </div>\n\n      ');
16538       if (USER.payment_gateway.payment_profiles.length > 0) {
16539         __out.push('\n        <h2>');
16540         __out.push(__sanitize(t('Credit Cards')));
16541         __out.push('</h2>\n        <div id="cards"></div>\n        <p><a id="add_card" href="">');
16542         __out.push(__sanitize(t('add a new credit card')));
16543         __out.push('</a></p>\n      ');
16544       } else {
16545         __out.push('\n        <div id="add_card_wrapper"> </div>\n      ');
16546       }
16547       __out.push('\n    </div>\n    ');
16548       if (USER.credit_balance > 0) {
16549         __out.push('\n      <div id="account_balance_wrapper">\n        <h2>');
16550         __out.push(__sanitize(t('Account Balance')));
16551         __out.push('</h2>\n        <p>\n          ');
16552         __out.push(__sanitize(t("Uber Credit Balance Note", {
16553           amount: app.helpers.formatCurrency(USER.credit_balance)
16554         })));
16555         __out.push('\n        </p>\n      </div>\n    ');
16556       }
16557       __out.push('\n    ');
16558       if (arrears.length > 0) {
16559         __out.push('\n      <div id="arrears_wrapper">\n        <h2>');
16560         __out.push(__sanitize(t('Arrears')));
16561         __out.push('</h2>\n        ');
16562         if (numCards === 0) {
16563           __out.push('\n          <strong> ');
16564           __out.push(__sanitize(t('Please Add Credit Card')));
16565           __out.push(' </strong>\n        ');
16566         }
16567         __out.push('\n        <table>\n          <tbody>\n            ');
16568         _.each(arrears, printArrear);
16569         __out.push('\n          </tbody>\n        </table>\n      </div>\n    ');
16570       }
16571       __out.push('\n  </div>\n</div>\n<div id="main_shadow"></div>\n\n');
16572     }).call(this);
16573     
16574   }).call(__obj);
16575   __obj.safe = __objSafe, __obj.escape = __escape;
16576   return __out.join('');
16577 }}, "templates/clients/confirm_email": function(exports, require, module) {module.exports = function(__obj) {
16578   if (!__obj) __obj = {};
16579   var __out = [], __capture = function(callback) {
16580     var out = __out, result;
16581     __out = [];
16582     callback.call(this);
16583     result = __out.join('');
16584     __out = out;
16585     return __safe(result);
16586   }, __sanitize = function(value) {
16587     if (value && value.ecoSafe) {
16588       return value;
16589     } else if (typeof value !== 'undefined' && value != null) {
16590       return __escape(value);
16591     } else {
16592       return '';
16593     }
16594   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
16595   __safe = __obj.safe = function(value) {
16596     if (value && value.ecoSafe) {
16597       return value;
16598     } else {
16599       if (!(typeof value !== 'undefined' && value != null)) value = '';
16600       var result = new String(value);
16601       result.ecoSafe = true;
16602       return result;
16603     }
16604   };
16605   if (!__escape) {
16606     __escape = __obj.escape = function(value) {
16607       return ('' + value)
16608         .replace(/&/g, '&amp;')
16609         .replace(/</g, '&lt;')
16610         .replace(/>/g, '&gt;')
16611         .replace(/"/g, '&quot;');
16612     };
16613   }
16614   (function() {
16615     (function() {
16616       __out.push('<div id="sub_header">\n  <h1>');
16617       __out.push(__sanitize(t('Confirm Email')));
16618       __out.push('</h1>\n</div>\n\n<div id="main_content">\n  <div>\n    <h3 id="attempt_text">');
16619       __out.push(__sanitize(t('Confirm Email Message')));
16620       __out.push('</h3>\n    <h3 class="success_message" style="display:none">');
16621       __out.push(__sanitize(t('Confirm Email Succeeded')));
16622       __out.push('</h3>\n    <h3 class="already_confirmed_message" style="display:none">');
16623       __out.push(__sanitize(t('Email Already Confirmed')));
16624       __out.push('</h3>\n    <h3 class="error_message" style="display:none">');
16625       __out.push(__sanitize(t('Confirm Email Failed')));
16626       __out.push('</h3>\n  </div>\n</div>\n<div id="main_shadow"></div>\n\n');
16627     }).call(this);
16628     
16629   }).call(__obj);
16630   __obj.safe = __objSafe, __obj.escape = __escape;
16631   return __out.join('');
16632 }}, "templates/clients/dashboard": function(exports, require, module) {module.exports = function(__obj) {
16633   if (!__obj) __obj = {};
16634   var __out = [], __capture = function(callback) {
16635     var out = __out, result;
16636     __out = [];
16637     callback.call(this);
16638     result = __out.join('');
16639     __out = out;
16640     return __safe(result);
16641   }, __sanitize = function(value) {
16642     if (value && value.ecoSafe) {
16643       return value;
16644     } else if (typeof value !== 'undefined' && value != null) {
16645       return __escape(value);
16646     } else {
16647       return '';
16648     }
16649   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
16650   __safe = __obj.safe = function(value) {
16651     if (value && value.ecoSafe) {
16652       return value;
16653     } else {
16654       if (!(typeof value !== 'undefined' && value != null)) value = '';
16655       var result = new String(value);
16656       result.ecoSafe = true;
16657       return result;
16658     }
16659   };
16660   if (!__escape) {
16661     __escape = __obj.escape = function(value) {
16662       return ('' + value)
16663         .replace(/&/g, '&amp;')
16664         .replace(/</g, '&lt;')
16665         .replace(/>/g, '&gt;')
16666         .replace(/"/g, '&quot;');
16667     };
16668   }
16669   (function() {
16670     (function() {
16671       var printStar, trip, _i, _len, _ref, _ref2, _ref3, _ref4;
16672       printStar = function() {
16673         return __out.push('\n  <img alt="Star" src="/web/img/star.png"/>\n');
16674       };
16675       __out.push('\n\n');
16676       __out.push(require('templates/clients/modules/sub_header').call(this, {
16677         heading: t("Dashboard")
16678       }));
16679       __out.push('\n\n\n<div id="main_content">\n  <div>\n    <div id="confirmation">\n      ');
16680       if (((_ref = USER.payment_gateway) != null ? (_ref2 = _ref.payment_profiles) != null ? _ref2.length : void 0 : void 0) > 0) {
16681         __out.push('\n        <div id="confirmed_credit_card" class="true left">');
16682         __out.push(__sanitize(t('Credit Card Added')));
16683         __out.push('</div>\n      ');
16684       } else {
16685         __out.push('\n        <div id="confirmed_credit_card" class="false left"><a id="card" class="confirmation" href="">');
16686         __out.push(__sanitize(t('No Credit Card')));
16687         __out.push('</a></div>\n      ');
16688       }
16689       __out.push('\n\n      ');
16690       if (USER.confirm_mobile === true) {
16691         __out.push('\n        <div id="confirmed_mobile" class="true">');
16692         __out.push(__sanitize(t('Mobile Number Confirmed')));
16693         __out.push('</div>\n      ');
16694       } else {
16695         __out.push('\n        <div id="confirmed_mobile" class="false"><a id="mobile" class="confirmation" href="">');
16696         __out.push(__sanitize(t('No Confirmed Mobile')));
16697         __out.push('</a></div>\n      ');
16698       }
16699       __out.push('\n\n      ');
16700       if (USER.confirm_email === true) {
16701         __out.push('\n        <div id="confirmed_email" class="true right">');
16702         __out.push(__sanitize(t('E-mail Address Confirmed')));
16703         __out.push('</div>\n      ');
16704       } else {
16705         __out.push('\n        <div id="confirmed_email" class="false right"><a id="email" class="confirmation" href="">');
16706         __out.push(__sanitize(t('No Confirmed E-mail')));
16707         __out.push('</a></div>\n      ');
16708       }
16709       __out.push('\n\n      <div id="more_info" style="display:none;">\n        <div id="mobile" class="info">\n          <span>');
16710       __out.push(__sanitize(t('Reply to sign up text')));
16711       __out.push('</span>\n          <a id="resend_mobile" class="resend" href="">');
16712       __out.push(__sanitize(t('Resend text message')));
16713       __out.push('</a>\n        </div>\n        <div id="email" class="info">\n          <span>');
16714       __out.push(__sanitize(t('Click sign up link')));
16715       __out.push('</span>\n          <a id="resend_email" class="resend" href="">');
16716       __out.push(__sanitize(t('Resend email')));
16717       __out.push('</a>\n        </div>\n        <div id="card" class="info">\n          <span>');
16718       __out.push(__sanitize(t("Add a credit card to ride")));
16719       __out.push('</span>\n        </div>\n      </div>\n    </div>\n\n    <div id="dashboard_trips">\n      ');
16720       if (USER.trips.length > 0) {
16721         __out.push('\n      <div id="trip_details_map"></div>\n      <div id="trip_details_info">\n        <h2>');
16722         __out.push(__sanitize(t('Your Most Recent Trip')));
16723         __out.push('</h2>\n        <span><a href="#!/trip/');
16724         __out.push(__sanitize(_.first(USER.trips.models).get('random_id')));
16725         __out.push('">');
16726         __out.push(__sanitize(t('details')));
16727         __out.push('</a></span>\n\n        <div id="avatars">\n          <img alt="Driver image" height="45" src="');
16728         __out.push(__sanitize(_.first(USER.trips.models).get('driver').picture_url));
16729         __out.push('" width="45"/>\n          <span>');
16730         __out.push(__sanitize("" + (_.first(USER.trips.models).get('driver').first_name)));
16731         __out.push('</span>\n          <div class="clear">\n          </div>\n        </div>\n        <h3>');
16732         __out.push(__sanitize(t('Rating')));
16733         __out.push('</h3>\n        ');
16734         _(_.first(USER.trips.models).get('driver_rating')).times(printStar);
16735         __out.push('\n      </div>\n      <div class="clear">\n      </div>\n      <div class="table_wrapper">\n        <h2>');
16736         __out.push(__sanitize(t('Your Trip History ')));
16737         __out.push('</h2>\n        <table class="zebra">\n        <colgroup>\n          <col width="*" />\n          <col width="200" />\n          <col width="120" />\n          <col width="100" />\n        </colgroup>\n        <thead>\n        <tr>\n          <td class="text">\n            ');
16738         __out.push(__sanitize(t('Pickup Time')));
16739         __out.push('\n          </td>\n          <td class="text">\n            ');
16740         __out.push(__sanitize(t('Status')));
16741         __out.push('\n          </td>\n          <td class="text">\n            ');
16742         __out.push(__sanitize(t('Driver')));
16743         __out.push('\n          </td>\n          <td class="graphic">\n            ');
16744         __out.push(__sanitize(t('Rating')));
16745         __out.push('\n          </td>\n          <td class="num">\n            ');
16746         __out.push(__sanitize(t('Fare')));
16747         __out.push('\n          </td>\n        </tr>\n        </thead>\n        <tbody>\n        ');
16748         _ref3 = USER.trips.models;
16749         for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
16750           trip = _ref3[_i];
16751           __out.push('\n          <tr>\n            <td class="text"><a href="#!/trip/');
16752           __out.push(__sanitize(trip.get('random_id')));
16753           __out.push('">');
16754           __out.push(__sanitize(app.helpers.formatDate(trip.get('request_at'), true, trip.get('city').timezone)));
16755           __out.push('</a></td>\n            <td class="text">');
16756           __out.push(__sanitize(trip.get('status')));
16757           __out.push('</td>\n            <td class="text">');
16758           __out.push(__sanitize((_ref4 = trip.get('driver')) != null ? _ref4.first_name : void 0));
16759           __out.push('</td>\n            <td class="graphic">');
16760           _(trip.get('driver_rating')).times(printStar);
16761           __out.push('</td>\n            <td class="num">');
16762           __out.push(__sanitize(app.helpers.formatTripFare(trip)));
16763           __out.push('</td>\n          </tr>\n        ');
16764         }
16765         __out.push('\n        </tbody>\n        </table>\n        <a id="show_all_trips" href="">');
16766         __out.push(__sanitize(t('Show all trips')));
16767         __out.push('</a>\n      </div>\n      ');
16768       } else {
16769         __out.push('\n        <p><strong>');
16770         __out.push(__sanitize(t("Here's how it works:")));
16771         __out.push('</strong></p>\n        <ol class="spaced">\n          <li>\n            ');
16772         __out.push(__sanitize(t('Set your location:')));
16773         __out.push('\n            <ul>\n              <li>');
16774         __out.push(__sanitize(t('App search for address')));
16775         __out.push('</li>\n              <li>');
16776         __out.push(__sanitize(t('SMS text address')));
16777         __out.push('</li>\n            </ul>\n          </li>\n          <li>');
16778         __out.push(__sanitize(t('Confirm pickup request')));
16779         __out.push('</li>\n          <li>');
16780         __out.push(__sanitize(t('Uber sends ETA')));
16781         __out.push('</li>\n          <li>');
16782         __out.push(__sanitize(t('Car arrives')));
16783         __out.push('</li>\n          <li>');
16784         __out.push(__sanitize(t('Ride to destination')));
16785         __out.push('</li>\n        </ol>\n        <p>');
16786         __out.push(__sanitize(t('Thank your driver')));
16787         __out.push('</p>\n      ');
16788       }
16789       __out.push('\n    </div>\n\n  </div>\n</div>\n<div id="main_shadow"></div>\n');
16790     }).call(this);
16791     
16792   }).call(__obj);
16793   __obj.safe = __objSafe, __obj.escape = __escape;
16794   return __out.join('');
16795 }}, "templates/clients/forgot_password": function(exports, require, module) {module.exports = function(__obj) {
16796   if (!__obj) __obj = {};
16797   var __out = [], __capture = function(callback) {
16798     var out = __out, result;
16799     __out = [];
16800     callback.call(this);
16801     result = __out.join('');
16802     __out = out;
16803     return __safe(result);
16804   }, __sanitize = function(value) {
16805     if (value && value.ecoSafe) {
16806       return value;
16807     } else if (typeof value !== 'undefined' && value != null) {
16808       return __escape(value);
16809     } else {
16810       return '';
16811     }
16812   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
16813   __safe = __obj.safe = function(value) {
16814     if (value && value.ecoSafe) {
16815       return value;
16816     } else {
16817       if (!(typeof value !== 'undefined' && value != null)) value = '';
16818       var result = new String(value);
16819       result.ecoSafe = true;
16820       return result;
16821     }
16822   };
16823   if (!__escape) {
16824     __escape = __obj.escape = function(value) {
16825       return ('' + value)
16826         .replace(/&/g, '&amp;')
16827         .replace(/</g, '&lt;')
16828         .replace(/>/g, '&gt;')
16829         .replace(/"/g, '&quot;');
16830     };
16831   }
16832   (function() {
16833     (function() {
16834       __out.push('<div id="form_container">\n  ');
16835       if (this.token) {
16836         __out.push('\n    <h1>');
16837         __out.push(__sanitize(t('Password Reset')));
16838         __out.push('</h1>\n    <div id="standard_form">\n\n      <p>');
16839         __out.push(__sanitize(t('Please choose a new password.')));
16840         __out.push('</p>\n\n      <p class="error_message" style="display:none;">');
16841         __out.push(__sanitize(t('Password Reset Error')));
16842         __out.push('</p>\n\n      <form id="password_reset" action="" method="">\n\n        <input id="token" type="hidden" name="token" value="');
16843         __out.push(__sanitize(this.token));
16844         __out.push('">\n\n        <div class="form_label">\n          <label for="password">');
16845         __out.push(__sanitize(t('New Password')));
16846         __out.push('</label>\n        </div>\n\n        <div class="form_input">\n          <input id="password" name="password" type="password" value=""/>\n        </div>\n\n        <div class="form_clear"></div>\n\n        <div class="formSubmitButton"><button id="password_reset_submit" type="submit" class="button" data-theme="a"><span>Reset Password</span></button></div>\n\n      </form>\n    </div>\n\n  ');
16847       } else {
16848         __out.push('\n    <h1>');
16849         __out.push(__sanitize(t('Forgot Password')));
16850         __out.push('</h1>\n    <div id="standard_form">\n\n      <p>');
16851         __out.push(t('Forgot Password Enter Email'));
16852         __out.push('\n\n      <p class="error_message" style="display:none;">');
16853         __out.push(__sanitize(t('Forgot Password Error')));
16854         __out.push('</p>\n\n      <p class="success_message" style="display:none;">');
16855         __out.push(__sanitize(t('Forgot Password Success')));
16856         __out.push('</p>\n\n      <form id="forgot_password" action="" method="">\n\n        <div class="form_label">\n          <label for="login">');
16857         __out.push(__sanitize(t('Email Address')));
16858         __out.push('</label>\n        </div>\n\n        <div class="form_input">\n          <input id="login" name="login" type="text" value=""/>\n        </div>\n\n        <div class="form_clear"></div>\n\n        <div class="formSubmitButton"><button type="submit" class="button" data-theme="a"><span>');
16859         __out.push(__sanitize(t('Reset Password')));
16860         __out.push('</span></button></div>\n      </form>\n\n    </div>\n  ');
16861       }
16862       __out.push('\n\n</div>\n\n<div id="small_container_shadow"><div class="left"></div><div class="right"></div></div>\n');
16863     }).call(this);
16864     
16865   }).call(__obj);
16866   __obj.safe = __objSafe, __obj.escape = __escape;
16867   return __out.join('');
16868 }}, "templates/clients/invite": function(exports, require, module) {module.exports = function(__obj) {
16869   if (!__obj) __obj = {};
16870   var __out = [], __capture = function(callback) {
16871     var out = __out, result;
16872     __out = [];
16873     callback.call(this);
16874     result = __out.join('');
16875     __out = out;
16876     return __safe(result);
16877   }, __sanitize = function(value) {
16878     if (value && value.ecoSafe) {
16879       return value;
16880     } else if (typeof value !== 'undefined' && value != null) {
16881       return __escape(value);
16882     } else {
16883       return '';
16884     }
16885   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
16886   __safe = __obj.safe = function(value) {
16887     if (value && value.ecoSafe) {
16888       return value;
16889     } else {
16890       if (!(typeof value !== 'undefined' && value != null)) value = '';
16891       var result = new String(value);
16892       result.ecoSafe = true;
16893       return result;
16894     }
16895   };
16896   if (!__escape) {
16897     __escape = __obj.escape = function(value) {
16898       return ('' + value)
16899         .replace(/&/g, '&amp;')
16900         .replace(/</g, '&lt;')
16901         .replace(/>/g, '&gt;')
16902         .replace(/"/g, '&quot;');
16903     };
16904   }
16905   (function() {
16906     (function() {
16907       __out.push(require('templates/clients/modules/sub_header').call(this, {
16908         heading: t("Invite friends")
16909       }));
16910       __out.push('\n\n<div id="main_content">\n  <div>\n    <h2>');
16911       __out.push(__sanitize(t('Give $ Get $')));
16912       __out.push('</h2>\n\n    <p>\n      ');
16913       __out.push(__sanitize(t('Give $ Get $ Description')));
16914       __out.push('\n    </p>\n\n    <p>');
16915       __out.push(__sanitize(t('What are you waiting for?')));
16916       __out.push('</p>\n    <div id="social_icons">\n      <div>\n        <a style="float:left" href="https://twitter.com/share" class="twitter-share-button" data-url="');
16917       __out.push(__sanitize(USER.referral_url));
16918       __out.push('" data-text="Sign up for @uber with my link and get $10 off your first ride! " data-count="none">');
16919       __out.push(__sanitize(t('Tweet')));
16920       __out.push('</a><script type="text/javascript" src="//platform.twitter.com/widgets.js"></script>\n      </div>\n      <div>\n        <div id="fb-root"></div>\n        <script>(function(d, s, id) {\n          var js, fjs = d.getElementsByTagName(s)[0];\n          js = d.createElement(s); js.id = id;\n          js.src = "//connect.facebook.net/" + window.i18n.getLocale() + "/all.js#appId=124678754298965&xfbml=1";\n          fjs.parentNode.insertBefore(js, fjs);\n        }(document, \'script\', \'facebook-jssdk\'));</script>\n\n        <div class="fb-like" data-href="');
16921       __out.push(__sanitize(USER.referral_url));
16922       __out.push('" data-send="true" data-layout="button_count" data-width="180" data-show-faces="false" data-action="recommend" data-font="lucida grande"></div>\n      </div>\n    </div>\n    <br>\n    <p>');
16923       __out.push(__sanitize(t('Invite Link')));
16924       __out.push(' <a href="');
16925       __out.push(__sanitize(USER.referral_url));
16926       __out.push('">');
16927       __out.push(__sanitize(USER.referral_url));
16928       __out.push('</a> </p>\n\n  </div>\n</div>\n<div id="main_shadow"></div>\n\n');
16929     }).call(this);
16930     
16931   }).call(__obj);
16932   __obj.safe = __objSafe, __obj.escape = __escape;
16933   return __out.join('');
16934 }}, "templates/clients/login": function(exports, require, module) {module.exports = function(__obj) {
16935   if (!__obj) __obj = {};
16936   var __out = [], __capture = function(callback) {
16937     var out = __out, result;
16938     __out = [];
16939     callback.call(this);
16940     result = __out.join('');
16941     __out = out;
16942     return __safe(result);
16943   }, __sanitize = function(value) {
16944     if (value && value.ecoSafe) {
16945       return value;
16946     } else if (typeof value !== 'undefined' && value != null) {
16947       return __escape(value);
16948     } else {
16949       return '';
16950     }
16951   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
16952   __safe = __obj.safe = function(value) {
16953     if (value && value.ecoSafe) {
16954       return value;
16955     } else {
16956       if (!(typeof value !== 'undefined' && value != null)) value = '';
16957       var result = new String(value);
16958       result.ecoSafe = true;
16959       return result;
16960     }
16961   };
16962   if (!__escape) {
16963     __escape = __obj.escape = function(value) {
16964       return ('' + value)
16965         .replace(/&/g, '&amp;')
16966         .replace(/</g, '&lt;')
16967         .replace(/>/g, '&gt;')
16968         .replace(/"/g, '&quot;');
16969     };
16970   }
16971   (function() {
16972     (function() {
16973       __out.push('<div id="form_container">\n\t<h1>');
16974       __out.push(__sanitize(t('Sign In')));
16975       __out.push('</h1>\n\t<div id="standard_form">\n\t\t<form method="post">\n\n\t\t\t<p class="error_message" style="display:none;"></span>\n\n\t\t\t<div class="form_label">\n\t\t\t\t<label for="login">');
16976       __out.push(__sanitize(t('Email Address')));
16977       __out.push('</label>\n\t\t\t</div>\n\t\t\t<div class="form_input">\n\t\t\t\t<input id="login" name="login" type="text" value=""/>\n\t\t\t</div>\n\n\t\t\t<div class="form_clear"></div>\n\n\t\t\t<div class="form_label">\n\t\t\t\t<label for="password">');
16978       __out.push(__sanitize(t('Password')));
16979       __out.push('</label>\n\t\t\t</div>\n\t\t\t<div class="form_input">\n\t\t\t\t<input id="password" name="password" type="password" value=""/>\n\t\t\t</div>\n\n\t\t\t<div class="form_clear"></div>\n\n      <div class="formSubmitButton"><button type="submit" class="button" data-theme="a"><span>');
16980       __out.push(__sanitize(t('Sign In')));
16981       __out.push('</span></button></div>\n\n      <h2><a href=\'/#!/forgot-password\'>');
16982       __out.push(__sanitize(t('Forgot Password?')));
16983       __out.push('</a></h2>\n\n\t\t</form>\n\t</div>\n</div>\n\n<div class="clear"></div>\n<div id="small_container_shadow"><div class="left"></div><div class="right"></div></div>\n');
16984     }).call(this);
16985     
16986   }).call(__obj);
16987   __obj.safe = __objSafe, __obj.escape = __escape;
16988   return __out.join('');
16989 }}, "templates/clients/modules/credit_card": function(exports, require, module) {module.exports = function(__obj) {
16990   if (!__obj) __obj = {};
16991   var __out = [], __capture = function(callback) {
16992     var out = __out, result;
16993     __out = [];
16994     callback.call(this);
16995     result = __out.join('');
16996     __out = out;
16997     return __safe(result);
16998   }, __sanitize = function(value) {
16999     if (value && value.ecoSafe) {
17000       return value;
17001     } else if (typeof value !== 'undefined' && value != null) {
17002       return __escape(value);
17003     } else {
17004       return '';
17005     }
17006   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
17007   __safe = __obj.safe = function(value) {
17008     if (value && value.ecoSafe) {
17009       return value;
17010     } else {
17011       if (!(typeof value !== 'undefined' && value != null)) value = '';
17012       var result = new String(value);
17013       result.ecoSafe = true;
17014       return result;
17015     }
17016   };
17017   if (!__escape) {
17018     __escape = __obj.escape = function(value) {
17019       return ('' + value)
17020         .replace(/&/g, '&amp;')
17021         .replace(/</g, '&lt;')
17022         .replace(/>/g, '&gt;')
17023         .replace(/"/g, '&quot;');
17024     };
17025   }
17026   (function() {
17027     (function() {
17028       var printCard;
17029       var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
17030       if (this.cards === "new") {
17031         __out.push('\n  <div id="cc_form_wrapper" class="inline_label_form wider_inline_label_form">\n    <form action="" id="credit_card_form" method="">\n      <div id="top_of_form" class="error_message"></div>\n      <div id="card_logos"></div>\n      <div id="credit_card_number_wrapper" data-role="fieldcontain">\n        <div class="error_message"></div>\n        <label>');
17032         __out.push(__sanitize(t('Credit Card Number')));
17033         __out.push('</label>\n        <input id="card_number" name="card_number" type="text"/>\n      </div>\n      <div class="clear"></div>\n      <div id="expiration_wrapper" data-role="fieldcontain">\n        <div class="error_message"></div>\n        <label for="expiration_month">');
17034         __out.push(__sanitize(t('Expiration')));
17035         __out.push('</label>\n        <select id="card_expiration_month" name="expiration_month">\n          <option value="">');
17036         __out.push(__sanitize(t('month')));
17037         __out.push('</option>\n          <option value="01">');
17038         __out.push(__sanitize(t('01-Jan')));
17039         __out.push('</option>\n          <option value="02">');
17040         __out.push(__sanitize(t('02-Feb')));
17041         __out.push('</option>\n          <option value="03">');
17042         __out.push(__sanitize(t('03-Mar')));
17043         __out.push('</option>\n          <option value="04">');
17044         __out.push(__sanitize(t('04-Apr')));
17045         __out.push('</option>\n          <option value="05">');
17046         __out.push(__sanitize(t('05-May')));
17047         __out.push('</option>\n          <option value="06">');
17048         __out.push(__sanitize(t('06-Jun')));
17049         __out.push('</option>\n          <option value="07">');
17050         __out.push(__sanitize(t('07-Jul')));
17051         __out.push('</option>\n          <option value="08">');
17052         __out.push(__sanitize(t('08-Aug')));
17053         __out.push('</option>\n          <option value="09">');
17054         __out.push(__sanitize(t('09-Sep')));
17055         __out.push('</option>\n          <option value="10">');
17056         __out.push(__sanitize(t('10-Oct')));
17057         __out.push('</option>\n          <option value="11">');
17058         __out.push(__sanitize(t('11-Nov')));
17059         __out.push('</option>\n          <option value="12">');
17060         __out.push(__sanitize(t('12-Dec')));
17061         __out.push('</option>\n        </select>\n      </div>\n      <div>\n        <span style="display:inline" class="error_message"></span>\n        <select id="card_expiration_year" name="expiration_year">\n          <option selected="selected" value="">');
17062         __out.push(__sanitize(t('year')));
17063         __out.push('</option>\n          <option value="2011">');
17064         __out.push(__sanitize(t('2011')));
17065         __out.push('</option>\n          <option value="2012">');
17066         __out.push(__sanitize(t('2012')));
17067         __out.push('</option>\n          <option value="2013">');
17068         __out.push(__sanitize(t('2013')));
17069         __out.push('</option>\n          <option value="2014">');
17070         __out.push(__sanitize(t('2014')));
17071         __out.push('</option>\n          <option value="2015">');
17072         __out.push(__sanitize(t('2015')));
17073         __out.push('</option>\n          <option value="2016">');
17074         __out.push(__sanitize(t('2016')));
17075         __out.push('</option>\n          <option value="2017">');
17076         __out.push(__sanitize(t('2017')));
17077         __out.push('</option>\n          <option value="2018">');
17078         __out.push(__sanitize(t('2018')));
17079         __out.push('</option>\n          <option value="2019">');
17080         __out.push(__sanitize(t('2019')));
17081         __out.push('</option>\n          <option value="2020">');
17082         __out.push(__sanitize(t('2020')));
17083         __out.push('</option>\n        </select>\n      </div>\n      <div class="clear"></div>\n      <div id="cvv_wrapper" data-role="fieldcontain">\n        <div class="error_message"></div>\n        <label for="card_code">');
17084         __out.push(__sanitize(t('CVV')));
17085         __out.push('</label>\n        <input id="card_code" name="card_code" type="text"/>\n      </div>\n      <div class="clear"></div>\n      <div>\n        <label for="use_case">');
17086         __out.push(__sanitize(t('Category')));
17087         __out.push('</label>\n        <select id="use_case">\n                <option value="personal" selected="true">');
17088         __out.push(__sanitize(t('personal')));
17089         __out.push('</option>\n                <option value="business">');
17090         __out.push(__sanitize(t('business')));
17091         __out.push('</option>\n        </select>\n      </div>\n      <div class="clear"></div>\n      <div id="default_wrapper" data-role="fieldcontain">\n        <label for="default">');
17092         __out.push(__sanitize(t('Default Credit Card')));
17093         __out.push('</label>\n        <input id="default_check" type="checkbox" name="default" value="true"/>\n        </div>\n      <div class="clear"></div>\n      <div>\n        <button id="new_card" type="submit" class="button" data-theme="a"><span>');
17094         __out.push(__sanitize(t('Add Credit Card')));
17095         __out.push('</span></button>\n      </div>\n    </form>\n  </div>\n');
17096       } else {
17097         __out.push('\n  ');
17098         printCard = __bind(function(card, index) {
17099           var exp, style;
17100           __out.push('\n    <tr id="');
17101           __out.push(__sanitize("d" + index));
17102           __out.push('">\n      <td>\n        ');
17103           style = "background-position:-173px";
17104           __out.push('\n        ');
17105           if (card.get("card_type") === "Visa") {
17106             style = "background-position:0px";
17107           }
17108           __out.push('\n        ');
17109           if (card.get("card_type") === "MasterCard") {
17110             style = "background-position:-42px";
17111           }
17112           __out.push('\n        ');
17113           if (card.get("card_type") === "American Express") {
17114             style = "background-position:-130px";
17115           }
17116           __out.push('\n        ');
17117           if (card.get("card_type") === "Discover Card") {
17118             style = "background-position:-85px";
17119           }
17120           __out.push('\n        <div class="card_type" style="');
17121           __out.push(__sanitize(style));
17122           __out.push('"></div>\n      </td>\n      <td>\n        ****');
17123           __out.push(__sanitize(card.get("card_number")));
17124           __out.push('\n      </td>\n      <td>\n        ');
17125           if (card.get("card_expiration")) {
17126             __out.push('\n          ');
17127             __out.push(__sanitize(t('Expiry')));
17128             __out.push('\n          ');
17129             exp = card.get('card_expiration').split('-');
17130             __out.push('\n          ');
17131             __out.push(__sanitize("" + exp[0] + "-" + exp[1]));
17132             __out.push('\n        ');
17133           }
17134           __out.push('\n      </td>\n      <td>\n        <select class="use_case">\n          <option ');
17135           __out.push(__sanitize(card.get("use_case") === "personal" ? "selected" : void 0));
17136           __out.push(' value="personal">');
17137           __out.push(__sanitize(t('personal')));
17138           __out.push('</option>\n          <option ');
17139           __out.push(__sanitize(card.get("use_case") === "business" ? "selected" : void 0));
17140           __out.push(' value="business">');
17141           __out.push(__sanitize(t('business')));
17142           __out.push('</option>\n        </select>\n      </td>\n      <td>\n        ');
17143           if (card.get("default")) {
17144             __out.push('\n          <strong>(');
17145             __out.push(__sanitize(t('default card')));
17146             __out.push(')</strong>\n        ');
17147           }
17148           __out.push('\n        ');
17149           if (this.cards.length > 1 && !card.get("default")) {
17150             __out.push('\n          <a class="make_default" href="">');
17151             __out.push(__sanitize(t('make default')));
17152             __out.push('</a>\n        ');
17153           }
17154           __out.push('\n      </td>\n      <td>\n        <a class="edit_card_show" href="">');
17155           __out.push(__sanitize(t('Edit')));
17156           __out.push('</a>\n      </td>\n      <td>\n        ');
17157           if (this.cards.length > 1) {
17158             __out.push('\n          <a class="delete_card" href="">');
17159             __out.push(__sanitize(t('Delete')));
17160             __out.push('</a>\n        ');
17161           }
17162           __out.push('\n      </td>\n    </tr>\n    <tr id=\'');
17163           __out.push(__sanitize("e" + index));
17164           __out.push('\' style="display:none;"><td colspan="7">\n      <form action="" method="">\n        <div>\n          <strong><label for="expiration_month">');
17165           __out.push(__sanitize(t('Expiry Month')));
17166           __out.push('</label></strong>\n          <select id="card_expiration_month" name="expiration_month">\n            <option value="">');
17167           __out.push(__sanitize(t('month')));
17168           __out.push('</option>\n            <option value="01">');
17169           __out.push(__sanitize(t('01-Jan')));
17170           __out.push('</option>\n            <option value="02">');
17171           __out.push(__sanitize(t('02-Feb')));
17172           __out.push('</option>\n            <option value="03">');
17173           __out.push(__sanitize(t('03-Mar')));
17174           __out.push('</option>\n            <option value="04">');
17175           __out.push(__sanitize(t('04-Apr')));
17176           __out.push('</option>\n            <option value="05">');
17177           __out.push(__sanitize(t('05-May')));
17178           __out.push('</option>\n            <option value="06">');
17179           __out.push(__sanitize(t('06-Jun')));
17180           __out.push('</option>\n            <option value="07">');
17181           __out.push(__sanitize(t('07-Jul')));
17182           __out.push('</option>\n            <option value="08">');
17183           __out.push(__sanitize(t('08-Aug')));
17184           __out.push('</option>\n            <option value="09">');
17185           __out.push(__sanitize(t('09-Sep')));
17186           __out.push('</option>\n            <option value="10">');
17187           __out.push(__sanitize(t('10-Oct')));
17188           __out.push('</option>\n            <option value="11">');
17189           __out.push(__sanitize(t('11-Nov')));
17190           __out.push('</option>\n            <option value="12">');
17191           __out.push(__sanitize(t('12-Dec')));
17192           __out.push('</option>\n          </select>\n        </div>\n        <div>\n          <strong><label for="expiration_year">');
17193           __out.push(__sanitize(t('Expiry Year')));
17194           __out.push('</label></strong>\n          <select id="card_expiration_year" name="expiration_year">\n            <option selected="selected" value="">');
17195           __out.push(__sanitize(t('year')));
17196           __out.push('</option>\n            <option value="2011">');
17197           __out.push(__sanitize(t('2011')));
17198           __out.push('</option>\n            <option value="2012">');
17199           __out.push(__sanitize(t('2012')));
17200           __out.push('</option>\n            <option value="2013">');
17201           __out.push(__sanitize(t('2013')));
17202           __out.push('</option>\n            <option value="2014">');
17203           __out.push(__sanitize(t('2014')));
17204           __out.push('</option>\n            <option value="2015">');
17205           __out.push(__sanitize(t('2015')));
17206           __out.push('</option>\n            <option value="2016">');
17207           __out.push(__sanitize(t('2016')));
17208           __out.push('</option>\n            <option value="2017">');
17209           __out.push(__sanitize(t('2017')));
17210           __out.push('</option>\n            <option value="2018">');
17211           __out.push(__sanitize(t('2018')));
17212           __out.push('</option>\n            <option value="2019">');
17213           __out.push(__sanitize(t('2019')));
17214           __out.push('</option>\n            <option value="2020">');
17215           __out.push(__sanitize(t('2020')));
17216           __out.push('</option>\n            <option value="2021">');
17217           __out.push(__sanitize(t('2021')));
17218           __out.push('</option>\n            <option value="2022">');
17219           __out.push(__sanitize(t('2022')));
17220           __out.push('</option>\n          </select>\n        </div>\n        <div>\n          <strong><label for="card_code">');
17221           __out.push(__sanitize(t('CVV')));
17222           __out.push('</label></strong>\n          <input id="card_code" name="card_code" type="text"/>\n        </div>\n        <button class="button edit_card" data-theme="a"><span>');
17223           __out.push(__sanitize(t('Save')));
17224           return __out.push('</span></button>\n      </form>\n    </td></tr>\n  ');
17225         }, this);
17226         __out.push('\n\n  <div id="card_edit_form">\n    <table>\n      ');
17227         _.each(this.cards.models, printCard);
17228         __out.push('\n    </table>\n  </div>\n\n');
17229       }
17230       __out.push('\n');
17231     }).call(this);
17232     
17233   }).call(__obj);
17234   __obj.safe = __objSafe, __obj.escape = __escape;
17235   return __out.join('');
17236 }}, "templates/clients/modules/sub_header": function(exports, require, module) {module.exports = function(__obj) {
17237   if (!__obj) __obj = {};
17238   var __out = [], __capture = function(callback) {
17239     var out = __out, result;
17240     __out = [];
17241     callback.call(this);
17242     result = __out.join('');
17243     __out = out;
17244     return __safe(result);
17245   }, __sanitize = function(value) {
17246     if (value && value.ecoSafe) {
17247       return value;
17248     } else if (typeof value !== 'undefined' && value != null) {
17249       return __escape(value);
17250     } else {
17251       return '';
17252     }
17253   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
17254   __safe = __obj.safe = function(value) {
17255     if (value && value.ecoSafe) {
17256       return value;
17257     } else {
17258       if (!(typeof value !== 'undefined' && value != null)) value = '';
17259       var result = new String(value);
17260       result.ecoSafe = true;
17261       return result;
17262     }
17263   };
17264   if (!__escape) {
17265     __escape = __obj.escape = function(value) {
17266       return ('' + value)
17267         .replace(/&/g, '&amp;')
17268         .replace(/</g, '&lt;')
17269         .replace(/>/g, '&gt;')
17270         .replace(/"/g, '&quot;');
17271     };
17272   }
17273   (function() {
17274     (function() {
17275       __out.push('<div id="sub_header">\n  <div id="title">');
17276       __out.push(__sanitize(this.heading));
17277       __out.push('</div>\n  <div id="greeting">\n    ');
17278       if (window.USER.first_name) {
17279         __out.push('\n      ');
17280         __out.push(__sanitize(t('Hello Greeting', {
17281           name: USER.first_name
17282         })));
17283         __out.push('\n    ');
17284       }
17285       __out.push('\n  </div>\n</div>\n<div class="clear"></div>\n');
17286     }).call(this);
17287     
17288   }).call(__obj);
17289   __obj.safe = __objSafe, __obj.escape = __escape;
17290   return __out.join('');
17291 }}, "templates/clients/promotions": function(exports, require, module) {module.exports = function(__obj) {
17292   if (!__obj) __obj = {};
17293   var __out = [], __capture = function(callback) {
17294     var out = __out, result;
17295     __out = [];
17296     callback.call(this);
17297     result = __out.join('');
17298     __out = out;
17299     return __safe(result);
17300   }, __sanitize = function(value) {
17301     if (value && value.ecoSafe) {
17302       return value;
17303     } else if (typeof value !== 'undefined' && value != null) {
17304       return __escape(value);
17305     } else {
17306       return '';
17307     }
17308   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
17309   __safe = __obj.safe = function(value) {
17310     if (value && value.ecoSafe) {
17311       return value;
17312     } else {
17313       if (!(typeof value !== 'undefined' && value != null)) value = '';
17314       var result = new String(value);
17315       result.ecoSafe = true;
17316       return result;
17317     }
17318   };
17319   if (!__escape) {
17320     __escape = __obj.escape = function(value) {
17321       return ('' + value)
17322         .replace(/&/g, '&amp;')
17323         .replace(/</g, '&lt;')
17324         .replace(/>/g, '&gt;')
17325         .replace(/"/g, '&quot;');
17326     };
17327   }
17328   (function() {
17329     (function() {
17330       var promo, _i, _len, _ref;
17331       __out.push(require('templates/clients/modules/sub_header').call(this, {
17332         heading: t("Promotions")
17333       }));
17334       __out.push('\n\n<div id="main_content">\n  <div>\n      <div id="global_status">\n        <span class="success_message"></span>\n        <span class="error_message"></span>\n      </div>\n      <form action="/dashboard/promotions/create" method="post">\n        <label for="code">');
17335       __out.push(__sanitize(t('Enter Promotion Code')));
17336       __out.push('</label>\n        <input id="code" name="code" type="text" />\n\n        <button type="submit" class="button"><span>');
17337       __out.push(__sanitize(t('Submit')));
17338       __out.push('</span></button>\n      </form>\n      ');
17339       if (this.promos.length > 0) {
17340         __out.push('\n      <div class="table_wrapper">\n        <h2>');
17341         __out.push(__sanitize(t('Your Available Promotions')));
17342         __out.push('</h2>\n        <table>\n          <thead>\n\n            <tr>\n              <td>');
17343         __out.push(__sanitize(t('Code')));
17344         __out.push('</td>\n              <td>');
17345         __out.push(__sanitize(t('Details')));
17346         __out.push('</td>\n              <td>');
17347         __out.push(__sanitize(t('Starts')));
17348         __out.push('</td>\n              <td>');
17349         __out.push(__sanitize(t('Expires')));
17350         __out.push('</td>\n            </tr>\n          </thead>\n          <tbody>\n         ');
17351         _ref = this.promos;
17352         for (_i = 0, _len = _ref.length; _i < _len; _i++) {
17353           promo = _ref[_i];
17354           __out.push('\n              <tr>\n                <td>');
17355           __out.push(__sanitize(promo.code));
17356           __out.push('</td>\n                <td>');
17357           __out.push(__sanitize(promo.description));
17358           __out.push('</td>\n                <td>');
17359           __out.push(__sanitize(app.helpers.formatDate(promo.starts_at, true, "America/Los_Angeles")));
17360           __out.push('</td>\n                <td>');
17361           __out.push(__sanitize(app.helpers.formatDate(promo.ends_at, true, "America/Los_Angeles")));
17362           __out.push('</td>\n             </tr>\n          ');
17363         }
17364         __out.push('\n          </tbody>\n        </table>\n        </div>\n        ');
17365       } else {
17366         __out.push('\n\n    <p>');
17367         __out.push(__sanitize(t('No Active Promotions')));
17368         __out.push('</p>\n      ');
17369       }
17370       __out.push('\n\n  </div>\n</div>\n<div id="main_shadow"></div>\n');
17371     }).call(this);
17372     
17373   }).call(__obj);
17374   __obj.safe = __objSafe, __obj.escape = __escape;
17375   return __out.join('');
17376 }}, "templates/clients/request": function(exports, require, module) {module.exports = function(__obj) {
17377   if (!__obj) __obj = {};
17378   var __out = [], __capture = function(callback) {
17379     var out = __out, result;
17380     __out = [];
17381     callback.call(this);
17382     result = __out.join('');
17383     __out = out;
17384     return __safe(result);
17385   }, __sanitize = function(value) {
17386     if (value && value.ecoSafe) {
17387       return value;
17388     } else if (typeof value !== 'undefined' && value != null) {
17389       return __escape(value);
17390     } else {
17391       return '';
17392     }
17393   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
17394   __safe = __obj.safe = function(value) {
17395     if (value && value.ecoSafe) {
17396       return value;
17397     } else {
17398       if (!(typeof value !== 'undefined' && value != null)) value = '';
17399       var result = new String(value);
17400       result.ecoSafe = true;
17401       return result;
17402     }
17403   };
17404   if (!__escape) {
17405     __escape = __obj.escape = function(value) {
17406       return ('' + value)
17407         .replace(/&/g, '&amp;')
17408         .replace(/</g, '&lt;')
17409         .replace(/>/g, '&gt;')
17410         .replace(/"/g, '&quot;');
17411     };
17412   }
17413   (function() {
17414     (function() {
17415       var showFavoriteLocation;
17416       showFavoriteLocation = function(location, index) {
17417         var alphabet;
17418         __out.push('\n   ');
17419         alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
17420         __out.push('\n  <tr id="f');
17421         __out.push(__sanitize(index));
17422         __out.push('" class="location_row">\n    <td class="marker_logo">\n       <img src="https://www.google.com/mapfiles/marker');
17423         __out.push(__sanitize(alphabet[index]));
17424         __out.push('.png" />\n    </td>\n    <td class="location_nickname_wrapper">\n      <span >');
17425         __out.push(__sanitize(location.nickname));
17426         return __out.push('</span>\n    </td>\n  </tr>\n');
17427       };
17428       __out.push('\n\n');
17429       __out.push(require('templates/clients/modules/sub_header').call(this, {
17430         heading: t("Ride Request")
17431       }));
17432       __out.push('\n\n\n<div id="main_content">\n  <div>\n    <div id="top_bar">\n      <form id="search_form" action="" method="post">\n        <label for="address">');
17433       __out.push(__sanitize(t('Where do you want us to pick you up?')));
17434       __out.push('</label>\n        <input id="address" name="address" type="text" placeholder="');
17435       __out.push(__sanitize(t('Address to search')));
17436       __out.push('"/>\n        <button type="submit" id="address" class="button"><span>');
17437       __out.push(__sanitize(t('Search')));
17438       __out.push('</span></button>\n      </form>\n    </div>\n\n    <div id="sidebar">\n      <div id="waiting_riding" class="panel">\n        <table>\n          <tr>\n            <td>\n              <p class="label">');
17439       __out.push(__sanitize(t('Driver Name:')));
17440       __out.push('</p>\n              <p id="rideName"></p>\n            </td>\n          </tr>\n          <tr>\n            <td>\n              <p class="label">');
17441       __out.push(__sanitize(t('Driver #:')));
17442       __out.push('</p>\n              <p id="ridePhone"></p>\n            </td>\n          </tr>\n          <tr id="ride_address_wrapper">\n            <td>\n              <p class="label">');
17443       __out.push(__sanitize(t('Pickup Address:')));
17444       __out.push('</p>\n              <p id="rideAddress"></p>\n            </td>\n            <td id="favShow">\n              <img alt="');
17445       __out.push(__sanitize(t('Add to Favorite Locations')));
17446       __out.push('" id="addToFavButton" src="/web/img/button_plus_gray.png"/>\n            </td>\n          </tr>\n          <tr>\n            <td>\n              <form id="favLoc_form" action="" method="post">\n                <p class="error_message"></p>\n                <span class="label">');
17447       __out.push(__sanitize(t('Nickname:')));
17448       __out.push('</span>\n                <input type="hidden" value="" id="pickupLat" />\n                <input type="hidden" value="" id="pickupLng" />\n                <input id="favLocNickname" name="nickname" type="text"/>\n                <button type="submit" class="button"><span>');
17449       __out.push(__sanitize(t('Add')));
17450       __out.push('</span></button>\n              </form>\n            </td>\n          </tr>\n        </table>\n      </div>\n      <div id="trip_completed_panel" class="panel">\n        <h2>');
17451       __out.push(__sanitize(t('Your last trip')));
17452       __out.push('</h2>\n        <form id="rating_form">\n          <label>');
17453       __out.push(__sanitize(t('Please rate your driver:')));
17454       __out.push('</label>\n          <img alt="');
17455       __out.push(__sanitize(t('Star')));
17456       __out.push('" class="stars" id="1" src="/web/img/star_inactive.png"/>\n          <img alt="');
17457       __out.push(__sanitize(t('Star')));
17458       __out.push('" class="stars" id="2" src="/web/img/star_inactive.png"/>\n          <img alt="');
17459       __out.push(__sanitize(t('Star')));
17460       __out.push('" class="stars" id="3" src="/web/img/star_inactive.png"/>\n          <img alt="');
17461       __out.push(__sanitize(t('Star')));
17462       __out.push('" class="stars" id="4" src="/web/img/star_inactive.png"/>\n          <img alt="');
17463       __out.push(__sanitize(t('Star')));
17464       __out.push('" class="stars" id="5" src="/web/img/star_inactive.png"/>\n          <label>');
17465       __out.push(__sanitize(t('Comments: (optional)')));
17466       __out.push('</label>\n          <textarea id="comments" name="comments" type="text"/>\n          <button type="submit" id="rating" class="button"><span>');
17467       __out.push(__sanitize(t('Rate Trip')));
17468       __out.push('</span></button>\n        </form>\n        <table>\n          <tr>\n            <td class="label">');
17469       __out.push(__sanitize(t('Pickup time:')));
17470       __out.push('</td>\n            <td id="tripTime"></td>\n          </tr>\n          <tr>\n            <td class="label">');
17471       __out.push(__sanitize(t('Miles:')));
17472       __out.push('</td>\n            <td id="tripDist"></td>\n          </tr>\n          <tr>\n            <td class="label">');
17473       __out.push(__sanitize(t('Trip time:')));
17474       __out.push('</td>\n            <td id="tripDur"></td>\n          </tr>\n          <tr>\n            <td class="label">');
17475       __out.push(__sanitize(t('Fare:')));
17476       __out.push('</td>\n            <td id="tripFare"></td>\n          </tr>\n        </table>\n      </div>\n      <div id="location_panel_control" class="panel">\n        <a id="favorite" style="font-weight:bold;" class="locations_link" >');
17477       __out.push(__sanitize(t('Favorite Locations')));
17478       __out.push('</a> |\n        <a href="" id="search" class="locations_link">');
17479       __out.push(__sanitize(t('Search Results')));
17480       __out.push('</a>\n      </div>\n      <div id="location_panel" class="panel">\n        <div id="favorite_results">\n          ');
17481       if (USER.locations) {
17482         __out.push('\n            <table>\n              ');
17483         _.each(USER.locations, showFavoriteLocation);
17484         __out.push('\n            </table>\n          ');
17485       } else {
17486         __out.push('\n            <p>');
17487         __out.push(__sanitize(t('You have no favorite locations saved.')));
17488         __out.push('</p>\n          ');
17489       }
17490       __out.push('\n        </div>\n        <div id="search_results">\n        </div>\n      </div>\n    </div>\n    <span id="status_message" >');
17491       __out.push(__sanitize(t('Loading...')));
17492       __out.push('</span>\n    <div id="map_wrapper_right"></div>\n    <a id="pickupHandle" type="submit" class="button_green"><span>');
17493       __out.push(__sanitize(t('Request Pickup')));
17494       __out.push('</span></a>\n    <div class="clear"></div>\n  </div>\n</div>\n<div id="main_shadow"></div>\n');
17495     }).call(this);
17496     
17497   }).call(__obj);
17498   __obj.safe = __objSafe, __obj.escape = __escape;
17499   return __out.join('');
17500 }}, "templates/clients/settings": function(exports, require, module) {module.exports = function(__obj) {
17501   if (!__obj) __obj = {};
17502   var __out = [], __capture = function(callback) {
17503     var out = __out, result;
17504     __out = [];
17505     callback.call(this);
17506     result = __out.join('');
17507     __out = out;
17508     return __safe(result);
17509   }, __sanitize = function(value) {
17510     if (value && value.ecoSafe) {
17511       return value;
17512     } else if (typeof value !== 'undefined' && value != null) {
17513       return __escape(value);
17514     } else {
17515       return '';
17516     }
17517   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
17518   __safe = __obj.safe = function(value) {
17519     if (value && value.ecoSafe) {
17520       return value;
17521     } else {
17522       if (!(typeof value !== 'undefined' && value != null)) value = '';
17523       var result = new String(value);
17524       result.ecoSafe = true;
17525       return result;
17526     }
17527   };
17528   if (!__escape) {
17529     __escape = __obj.escape = function(value) {
17530       return ('' + value)
17531         .replace(/&/g, '&amp;')
17532         .replace(/</g, '&lt;')
17533         .replace(/>/g, '&gt;')
17534         .replace(/"/g, '&quot;');
17535     };
17536   }
17537   (function() {
17538     (function() {
17539       var args;
17540       __out.push(require('templates/clients/modules/sub_header').call(this, {
17541         heading: t("settings")
17542       }));
17543       __out.push('\n\n<div id="tabs">\n  <ul>\n    <li><a href="info_div" class="setting_change">');
17544       __out.push(__sanitize(t('Information')));
17545       __out.push('</a></li>\n    <li><a href="pic_div" class="setting_change">');
17546       __out.push(__sanitize(t('Picture')));
17547       __out.push('</a></li>\n  </ul>\n</div>\n<div class="clear"></div>\n\n<div id="main_content">\n  <div>\n  <div id="global_status">\n    <span class="error_message"></span>\n    <span class="success_message"></span>\n  </div>\n    <div id="info_div" style="display:none;">\n\n      <div id="form_container">\n        <div id="standard_form">\n\n          <form id="edit_info_form">\n\n            <h2>');
17548       __out.push(__sanitize(t('Account Information')));
17549       __out.push('</h2>\n\n            <div class="form_label">\n              <label for="first_name">');
17550       __out.push(__sanitize(t('First Name')));
17551       __out.push('</label>\n            </div>\n\n            <div class="form_input">\n              <input id="first_name" name="first_name" type="text" value="');
17552       __out.push(__sanitize(USER.first_name));
17553       __out.push('"/>\n              <span class="error_message"></span>\n            </div>\n\n            <div class="form_clear"></div>\n\n            <div class="form_label">\n              <label for="last_name">');
17554       __out.push(__sanitize(t('Last Name')));
17555       __out.push('</label>\n            </div>\n            <div class="form_input">\n              <input id="last_name" name="last_name" type="text" value="');
17556       __out.push(__sanitize(USER.last_name));
17557       __out.push('"/>\n              <span class="error_message"></span>\n            </div>\n\n            <div class="form_clear"></div>\n\n            <div class="form_label">\n              <label for="email">');
17558       __out.push(__sanitize(t('Email Address')));
17559       __out.push('</label>\n            </div>\n            <div class="form_input">\n              <input id="email" name="email" type="text" value="');
17560       __out.push(__sanitize(USER.email));
17561       __out.push('"/>\n              <span class="error_message"></span>\n            </div>\n\n            <div class="form_clear"></div>\n\n            <div class="form_label">\n              <label for="password">');
17562       __out.push(__sanitize(t('Password')));
17563       __out.push('</label>\n            </div>\n            <div class="form_input">\n              <a id="change_password" href="">');
17564       __out.push(__sanitize(t('Change Your Password')));
17565       __out.push('</a>\n              <input style="display:none" id="password" name="password" type="password" value=""/>\n              <span class="error_message"></span>\n            </div>\n\n            <div class="form_clear"></div>\n\n            <div class="form_label">\n              <label for="country">');
17566       __out.push(__sanitize(t('Country')));
17567       __out.push('</label>\n            </div>\n            <div class="form_input">\n              ');
17568       args = {
17569         selected: USER['country_id']
17570       };
17571       __out.push('\n              ');
17572       __out.push(app.helpers.countrySelector("country_id", args));
17573       __out.push('\n              <span class="error_message"></span>\n            </div>\n\n            <div class="form_clear"></div>\n              <div class="form_label">\n              <label for="location">Zip/Postal Code</label>\n            </div>\n            <div class="form_input">\n              <input id="location" name="location" class="half" type="text" value="');
17574       __out.push(__sanitize(USER.location));
17575       __out.push('"/>\n              <span class="error_message"></span>\n            </div>\n\n            <div class="form_clear"></div>\n\n            <div class="form_label">\n            <label for="language_id">');
17576       __out.push(__sanitize(t('Language')));
17577       __out.push('</label>\n            </div>\n            <div class="form_input">\n            <select name="language_id" id="language_id">\n              <option value="1" ');
17578       __out.push(__sanitize(USER.language_id === 1 ? 'selected="selected"' : ""));
17579       __out.push('>English</option>\n              <option value="2" ');
17580       __out.push(__sanitize(USER.language_id === 2 ? 'selected="selected"' : ""));
17581       __out.push('>Francais</option>\n            </select>\n            <span class="erro_message"></span>\n            </div>\n\n            <div class="form_clear"></div>\n\n            <h2>');
17582       __out.push(__sanitize(t('Mobile Phone Information')));
17583       __out.push('</h2>\n\n            <div class="form_clear"></div>\n\n            <div class="form_label">\n              <label for="country">');
17584       __out.push(__sanitize(t('Country')));
17585       __out.push('</label>\n            </div>\n            <div class="form_input">\n              ');
17586       args = {
17587         countryCodePrefix: 'mobile_country_code'
17588       };
17589       __out.push('\n              ');
17590       args['selected'] = USER['mobile_country_code'];
17591       __out.push('\n              ');
17592       __out.push(app.helpers.countrySelector("mobile_country_id", args));
17593       __out.push('\n              <span class="error_message"></span>\n            </div>\n\n            <div class="form_clear"></div>\n\n            <div class="form_label">\n              <label for="mobile">');
17594       __out.push(__sanitize(t('Mobile Number')));
17595       __out.push('</label>\n            </div>\n            <div class="form_input">\n              <div id="mobile_country_code" class="phone_country_code">');
17596       __out.push(__sanitize(USER['mobile_country_code']));
17597       __out.push('</div>\n              <input id="mobile" name="mobile" class="phone" type="text" value="');
17598       __out.push(__sanitize(USER.mobile));
17599       __out.push('"/>\n              <span class="error_message"></span>\n            </div>\n\n            <div class="form_clear"></div>\n\n            <div>\n              <button id="submit_info" type="submit" class="button"><span>');
17600       __out.push(__sanitize(t('Submit')));
17601       __out.push('</span></button>\n            </div>\n          </form>\n        </div>\n      </div>\n    </div>\n\n    <div id="pic_div" style="display:none;">\n      <form id="profile_pic_form" enctype="multipart/form-data" method="POST" target="">\n        <input type="file" name="picture" id="picture">\n        <button id="submit_pic" type="submit" class="button"><span>');
17602       __out.push(__sanitize(t('Upload')));
17603       __out.push('</span></button>\n      </form>\n      <p>');
17604       __out.push(__sanitize(t('Your current Picture')));
17605       __out.push('</p>\n      <img id="settingsProfPic" src="');
17606       __out.push(__sanitize("" + USER.picture_url + "?" + (new Date().getTime())));
17607       __out.push('" />\n      <div id="test"></div>\n    </div>\n\n    <div class="clear"></div>\n  </div>\n</div>\n\n<div class="clear"></div>\n<div id="main_shadow"></div>\n');
17608     }).call(this);
17609     
17610   }).call(__obj);
17611   __obj.safe = __objSafe, __obj.escape = __escape;
17612   return __out.join('');
17613 }}, "templates/clients/sign_up": function(exports, require, module) {module.exports = function(__obj) {
17614   if (!__obj) __obj = {};
17615   var __out = [], __capture = function(callback) {
17616     var out = __out, result;
17617     __out = [];
17618     callback.call(this);
17619     result = __out.join('');
17620     __out = out;
17621     return __safe(result);
17622   }, __sanitize = function(value) {
17623     if (value && value.ecoSafe) {
17624       return value;
17625     } else if (typeof value !== 'undefined' && value != null) {
17626       return __escape(value);
17627     } else {
17628       return '';
17629     }
17630   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
17631   __safe = __obj.safe = function(value) {
17632     if (value && value.ecoSafe) {
17633       return value;
17634     } else {
17635       if (!(typeof value !== 'undefined' && value != null)) value = '';
17636       var result = new String(value);
17637       result.ecoSafe = true;
17638       return result;
17639     }
17640   };
17641   if (!__escape) {
17642     __escape = __obj.escape = function(value) {
17643       return ('' + value)
17644         .replace(/&/g, '&amp;')
17645         .replace(/</g, '&lt;')
17646         .replace(/>/g, '&gt;')
17647         .replace(/"/g, '&quot;');
17648     };
17649   }
17650   (function() {
17651     (function() {
17652       __out.push('<div id="form_container">\n  <h1>');
17653       __out.push(__sanitize(t('Sign Up')));
17654       __out.push('</h1>\n  <div id="standard_form">\n    <form action="/" method="">\n\n      <h2>');
17655       __out.push(__sanitize(t('Personal Information')));
17656       __out.push('</h2>\n\n      <div class="form_label">\n        <label for="first_name">');
17657       __out.push(__sanitize(t('First Name')));
17658       __out.push('</label>\n      </div>\n      <div class="form_input">\n        <input id="first_name" name="first_name" type="text" value=""/>\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <div class="form_label">\n        <label for="last_name">');
17659       __out.push(__sanitize(t('Last Name')));
17660       __out.push('</label>\n      </div>\n      <div class="form_input">\n        <input id="last_name" name="last_name" type="text" value=""/>\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <div class="form_label">\n        <label for="email">');
17661       __out.push(__sanitize(t('Email Address')));
17662       __out.push('</label>\n      </div>\n      <div class="form_input">\n        <input id="email" name="email" type="text" value=""/>\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <div class="form_label">\n        <label for="password">');
17663       __out.push(__sanitize(t('Password')));
17664       __out.push('</label>\n      </div>\n      <div class="form_input">\n        <input id="password" name="password" type="password" value=""/>\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <div class="form_label">\n        <label for="country">');
17665       __out.push(__sanitize(t('Country')));
17666       __out.push('</label>\n      </div>\n      <div class="form_input">\n        ');
17667       __out.push(app.helpers.countrySelector('location_country'));
17668       __out.push('\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n        <div class="form_label">\n        <label for="location">');
17669       __out.push(__sanitize(t('Zip/Postal Code')));
17670       __out.push('</label>\n      </div>\n      <div class="form_input">\n        <input id="location" name="location" class="half" type="text" value=""/>\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <div class="form_clear"></div>\n        <div class="form_label">\n        <label for="language">');
17671       __out.push(__sanitize(t('Language')));
17672       __out.push('</label>\n      </div>\n      <div class="form_input">\n        <select id="language" name="language">\n          <option value="en">English (US)</option>\n          <option value="fr">Français</option>\n        </select>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <h2>');
17673       __out.push(__sanitize(t('Mobile Phone Information')));
17674       __out.push('</h2>\n\n      <div class="form_clear"></div>\n\n      <div class="form_label">\n        <label for="country">');
17675       __out.push(__sanitize(t('Country')));
17676       __out.push('</label>\n      </div>\n      <div class="form_input">\n        ');
17677       __out.push(app.helpers.countrySelector('mobile_country', {
17678         countryCodePrefix: 'mobile_country_code'
17679       }));
17680       __out.push('\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <div class="form_label">\n        <label for="mobile">');
17681       __out.push(__sanitize(t('Mobile Number')));
17682       __out.push('</label>\n      </div>\n      <div class="form_input">\n        <div id="mobile_country_code" class="phone_country_code">+1</div>\n        <input id="mobile" name="mobile" class="phone" type="text" value=""/>\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <h2>');
17683       __out.push(__sanitize(t('Payment Information')));
17684       __out.push('</h2>\n\n      <div class="form_clear"></div>\n\n      <span><span id="top_of_form" class="error_message"></span></span>\n\n\n      <div class="form_label">\n        <label for="card_number">');
17685       __out.push(__sanitize(t('Credit Card Number')));
17686       __out.push('</label>\n      </div>\n      <div class="form_input">\n        <input id="card_number" name="card_number" type="text" value=""/>\n        <!--img id="card_icon" src="/web/img/cc_mastercard_24.png"-->\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <div class="form_label">\n        <label for="card_expiration_month">');
17687       __out.push(__sanitize(t('Expiration Date')));
17688       __out.push('</label>\n      </div>\n      <div class="form_input">\n        <select id="card_expiration_month" name="card_expiration_month">\n          <option value="01">01</option>\n          <option value="02">02</option>\n          <option value="03">03</option>\n          <option value="04">04</option>\n          <option value="05">05</option>\n          <option value="06">06</option>\n          <option value="07">07</option>\n          <option value="08">08</option>\n          <option value="09">09</option>\n          <option value="10">10</option>\n          <option value="11">11</option>\n          <option value="12">12</option>\n        </select>\n\n        <select id="card_expiration_year" name="card_expiration_year">\n          <option value="2011">2011</option>\n          <option value="2012">2012</option>\n          <option value="2013">2013</option>\n          <option value="2014">2014</option>\n          <option value="2015">2015</option>\n          <option value="2016">2016</option>\n          <option value="2017">2017</option>\n          <option value="2018">2018</option>\n          <option value="2019">2019</option>\n          <option value="2020">2020</option>\n          <option value="2021">2021</option>\n        </select>\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <div class="form_label">\n        <label for="card_number">');
17689       __out.push(__sanitize(t('Security Code')));
17690       __out.push('</label>\n      </div>\n      <div class="form_input">\n        <input id="card_code" name="card_code" type="text" value="" class="half" />\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <div class="form_label">\n        <label for="use_case">');
17691       __out.push(__sanitize(t('Type of Card')));
17692       __out.push('</label>\n      </div>\n      <div class="form_input">\n        <select id="use_case" name="use_case">\n          <option value="personal">');
17693       __out.push(__sanitize(t('Personal')));
17694       __out.push('</option>\n          <option value="business">');
17695       __out.push(__sanitize(t('Business')));
17696       __out.push('</option>\n        </select>\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <h2>');
17697       __out.push(__sanitize(t('Promotion Code')));
17698       __out.push('</h2>\n\n      <div class="form_label">\n        <label for="promotion_code">');
17699       __out.push(__sanitize(t('Code')));
17700       __out.push('</label>\n      </div>\n      <div class="form_input">\n        <input id="promotion_code" name="promotion_code" type="text" value="');
17701       __out.push(__sanitize(this.invite));
17702       __out.push('">\n        <span class="error_message"></span>\n      </div>\n\n      <div class="form_clear"></div>\n\n      <h2>');
17703       __out.push(__sanitize(t('Legal Information')));
17704       __out.push('</h2>\n\n      <p>');
17705       __out.push(t('Sign Up Agreement', {
17706         terms_link: "<a href='https://www.uber.com/terms' target='_blank' style='line-height:11px;'>" + (t('Terms and Conditions')) + "</a>",
17707         privacy_link: "<a href='https://www.uber.com/privacy' target='_blank' style='line-height:11px;'>" + (t('Privacy Policy')) + "</a>"
17708       }));
17709       __out.push('</p>\n\n      <p>');
17710       __out.push(t('Message and Data Rates Disclosure', {
17711         help_string: "<strong>" + (t('HELP')) + "</strong>",
17712         stop_string: "<strong>" + (t('STOP')) + "</strong>"
17713       }));
17714       __out.push('</p>\n\n      <p style="display:none" id="terms_error" class="error_message">');
17715       __out.push(__sanitize(t('Sign Up Agreement Error')));
17716       __out.push('</p>\n\n      <div id="signup_terms">\n        <p>\n          <input type="checkbox" name="signup_terms_agreement" />\n          <label for="signup_terms_agreement"><strong>');
17717       __out.push(t('I Agree'));
17718       __out.push('</strong></label>\n        </p>\n      </div>\n\n      <div class="formSubmitButton"><button type="submit" class="button" data-theme="a" id="sign_up_submit_button"><span>');
17719       __out.push(__sanitize(t('Sign Up')));
17720       __out.push('</span></button></div>\n\n    </form>\n  </div>\n</div>\n\n<div id="small_container_shadow"></div>\n');
17721     }).call(this);
17722     
17723   }).call(__obj);
17724   __obj.safe = __objSafe, __obj.escape = __escape;
17725   return __out.join('');
17726 }}, "templates/clients/trip_detail": function(exports, require, module) {module.exports = function(__obj) {
17727   if (!__obj) __obj = {};
17728   var __out = [], __capture = function(callback) {
17729     var out = __out, result;
17730     __out = [];
17731     callback.call(this);
17732     result = __out.join('');
17733     __out = out;
17734     return __safe(result);
17735   }, __sanitize = function(value) {
17736     if (value && value.ecoSafe) {
17737       return value;
17738     } else if (typeof value !== 'undefined' && value != null) {
17739       return __escape(value);
17740     } else {
17741       return '';
17742     }
17743   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
17744   __safe = __obj.safe = function(value) {
17745     if (value && value.ecoSafe) {
17746       return value;
17747     } else {
17748       if (!(typeof value !== 'undefined' && value != null)) value = '';
17749       var result = new String(value);
17750       result.ecoSafe = true;
17751       return result;
17752     }
17753   };
17754   if (!__escape) {
17755     __escape = __obj.escape = function(value) {
17756       return ('' + value)
17757         .replace(/&/g, '&amp;')
17758         .replace(/</g, '&lt;')
17759         .replace(/>/g, '&gt;')
17760         .replace(/"/g, '&quot;');
17761     };
17762   }
17763   (function() {
17764     (function() {
17765       var distance, fareBreakdown, printFares, printStar, _ref, _ref2, _ref3, _ref4, _ref5, _ref6;
17766       var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
17767       printStar = function() {
17768         return __out.push('\n  <img alt="Star" src="/web/img/star.png"/>\n');
17769       };
17770       __out.push('\n');
17771       fareBreakdown = this.trip.get('fare_breakdown');
17772       __out.push('\n\n');
17773       printFares = __bind(function(fare, index, list) {
17774         var _ref;
17775         __out.push('\n\n  <li>\n    <span class="fare">');
17776         __out.push(__sanitize(app.helpers.formatCurrency(fare['amount'], false, (_ref = this.trip.get('fare_breakdown_local')) != null ? _ref.currency : void 0)));
17777         __out.push('</span><br/>\n    <span class="subtext">');
17778         __out.push(__sanitize(fare['name']));
17779         __out.push('</span>\n    ');
17780         if (fare['variable_rate'] !== 0) {
17781           __out.push('\n      <br><span class="subtext">');
17782           __out.push(__sanitize("" + (app.helpers.formatCurrency(fare['variable_rate'], false, this.trip.get('fare_breakdown_local'))) + " x " + (app.helpers.roundNumber(fare['input_amount'], 3)) + " " + fare['input_type']));
17783           __out.push('</span>\n    ');
17784         }
17785         __out.push('\n  </li>\n  ');
17786         if (index !== list.length - 1) {
17787           __out.push('\n    <li class="math">+</li>\n  ');
17788         }
17789         return __out.push('\n');
17790       }, this);
17791       __out.push('\n\n');
17792       __out.push(require('templates/clients/modules/sub_header').call(this, {
17793         heading: t("Trip Details")
17794       }));
17795       __out.push('\n\n\n<div id="main_content">\n  <div class="clear"></div>\n  <div>\n    <div id="trip_details_map"></div>\n    <div id="trip_details_info">\n      <h2>\n          ');
17796       __out.push(__sanitize(t('Your Trip')));
17797       __out.push('\n      </h2>\n\n      <div id="avatars">\n        <h3>');
17798       __out.push(__sanitize(t('Driver')));
17799       __out.push('</h3>\n        <img alt="Driver image" height="45" src="');
17800       __out.push(__sanitize((_ref = this.trip.get('driver')) != null ? _ref.picture_url : void 0));
17801       __out.push('" width="45" />\n        <span>');
17802       __out.push(__sanitize((_ref2 = this.trip.get('driver')) != null ? _ref2.first_name : void 0));
17803       __out.push('</span>\n\n        <div class="clear"></div>\n      </div>\n\n        <h3>');
17804       __out.push(__sanitize(t('Rating')));
17805       __out.push('</h3>\n          ');
17806       _(this.trip.get('driver_rating')).times(printStar);
17807       __out.push('\n        <h3>');
17808       __out.push(__sanitize(t('Trip Info')));
17809       __out.push('</h3>\n        <table>\n          <tr class="first">\n            <td class="label">');
17810       __out.push(__sanitize(t('Pickup time:')));
17811       __out.push('</td>\n            <td>');
17812       __out.push(__sanitize(app.helpers.formatDate(this.trip.get('begintrip_at'), true, this.trip.get('city').timezone)));
17813       __out.push('</td>\n          </tr>\n          <tr>\n            <td class="label">');
17814       __out.push(__sanitize(t("" + (app.helpers.capitaliseFirstLetter((_ref3 = this.trip.get('city')) != null ? (_ref4 = _ref3.country) != null ? _ref4.distance_unit : void 0 : void 0)) + "s:")));
17815       __out.push('</td>\n            ');
17816       distance = this.trip.get('distance', 0);
17817       __out.push('\n            ');
17818       if (((_ref5 = this.trip.get('city')) != null ? (_ref6 = _ref5.country) != null ? _ref6.distance_unit : void 0 : void 0) === "kilometer") {
17819         __out.push('\n            ');
17820         distance = distance * 1.609344;
17821         __out.push('\n            ');
17822       }
17823       __out.push('\n            <td>');
17824       __out.push(__sanitize(app.helpers.roundNumber(distance, 2)));
17825       __out.push('</td>\n          </tr>\n          <tr>\n            <td class="label">');
17826       __out.push(__sanitize(t('Trip time:')));
17827       __out.push('</td>\n            <td>');
17828       __out.push(__sanitize(app.helpers.formatSeconds(this.trip.get('duration'))));
17829       __out.push('</td>\n          </tr>\n          <tr>\n            <td class="label">');
17830       __out.push(__sanitize(t('Fare:')));
17831       __out.push('</td>\n            <td>');
17832       __out.push(__sanitize(app.helpers.formatTripFare(this.trip)));
17833       __out.push('</td>\n          </tr>\n        </table>\n\n        <p><button class="resendReceipt"><span>Resend Receipt</span></button> <span class="resendReceiptSuccess success"></span><span class="resendReceiptError error"></span></p>\n\n        <p><a id="fare_review" href="">');
17834       __out.push(__sanitize(t('Request a fare review')));
17835       __out.push('</a></p>\n    </div>\n    <div class="clear"></div>\n\n    <div id="fare_review_box">\n\n      <span class="success_message" style="display:none;">');
17836       __out.push(__sanitize(t("Fare Review Submitted")));
17837       __out.push('</span>\n      <div id="fare_review_form_wrapper">\n        <p>');
17838       __out.push(__sanitize(t("Fair Price Consideration")));
17839       __out.push('</p>\n        <div id="pricing_breakdown">\n         <h3>');
17840       __out.push(__sanitize(t('Your Fare Calculation')));
17841       __out.push('</h3>\n\n          <h4>');
17842       __out.push(__sanitize(t('Charges')));
17843       __out.push('</h4>\n          <ul>\n            ');
17844       _.each(fareBreakdown['charges'], printFares);
17845       __out.push('\n            <div class="clear"></div>\n          </ul>\n\n          <h4>');
17846       __out.push(__sanitize(t('Discounts')));
17847       __out.push('</h4>\n          <ul>\n            ');
17848       _.each(fareBreakdown['discounts'], printFares);
17849       __out.push('\n            <div class="clear"></div>\n          </ul>\n\n          <h4>');
17850       __out.push(__sanitize(t('Total Charge')));
17851       __out.push('</h4>\n          <ul>\n            <li class="math">=</li>\n            <li class="valign"><span>$');
17852       __out.push(__sanitize(this.trip.get('fare')));
17853       __out.push('</span></li>\n            <div class="clear"></div>\n          </ul>\n        </div>\n        <ul>\n          <li>');
17854       __out.push(t('Uber Pricing Information Message', {
17855         learn_link: "<a href='" + (app.config.get('url')) + "/learn'>" + (t('Uber pricing information')) + "</a>"
17856       }));
17857       __out.push('</li>\n          <li>');
17858       __out.push(__sanitize(t('GPS Point Capture Disclosure')));
17859       __out.push('</li>\n        </ul>\n\n        <p>');
17860       __out.push(__sanitize(t('Fare Review Note')));
17861       __out.push('</p>\n        <span class="error_message" style="display:none;">');
17862       __out.push(__sanitize(t('Fare Review Error')));
17863       __out.push('</span>\n        <form id="form_review_form" action="" method="">\n          <input type="hidden" id="tripid" name="tripid" value="');
17864       __out.push(__sanitize(this.trip.get('id')));
17865       __out.push('">\n          <textarea id="form_review_message" name="message"></textarea>\n          <div class="clear"></div>\n          <button id="submit_fare_review" type="submit" class="button" data-theme="a"><span>');
17866       __out.push(__sanitize(t('Submit')));
17867       __out.push('</span></button>\n        </form>\n        <button class="button" id="fare_review_hide" data-theme="a"><span>');
17868       __out.push(__sanitize(t('Cancel')));
17869       __out.push('</span></button>\n      </div>\n    </div>\n    <div class="clear"></div>\n  </div>\n</div>\n<div id="main_shadow"></div>\n');
17870     }).call(this);
17871     
17872   }).call(__obj);
17873   __obj.safe = __objSafe, __obj.escape = __escape;
17874   return __out.join('');
17875 }}, "templates/shared/menu": function(exports, require, module) {module.exports = function(__obj) {
17876   if (!__obj) __obj = {};
17877   var __out = [], __capture = function(callback) {
17878     var out = __out, result;
17879     __out = [];
17880     callback.call(this);
17881     result = __out.join('');
17882     __out = out;
17883     return __safe(result);
17884   }, __sanitize = function(value) {
17885     if (value && value.ecoSafe) {
17886       return value;
17887     } else if (typeof value !== 'undefined' && value != null) {
17888       return __escape(value);
17889     } else {
17890       return '';
17891     }
17892   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
17893   __safe = __obj.safe = function(value) {
17894     if (value && value.ecoSafe) {
17895       return value;
17896     } else {
17897       if (!(typeof value !== 'undefined' && value != null)) value = '';
17898       var result = new String(value);
17899       result.ecoSafe = true;
17900       return result;
17901     }
17902   };
17903   if (!__escape) {
17904     __escape = __obj.escape = function(value) {
17905       return ('' + value)
17906         .replace(/&/g, '&amp;')
17907         .replace(/</g, '&lt;')
17908         .replace(/>/g, '&gt;')
17909         .replace(/"/g, '&quot;');
17910     };
17911   }
17912   (function() {
17913     (function() {
17914       __out.push('<div id="menu_main">\n  <div class="logo">\n    <a href="/"><img src="/web/img/logo-charcoal.png"></a>\n  </div>\n  <div class="nav">\n    <ul>\n      ');
17915       if (this.type === 'guest') {
17916         __out.push('\n        <li><a class="" href="/#!/sign-up" id="">');
17917         __out.push(__sanitize(t("Sign Up")));
17918         __out.push('</a></li>\n        <li><a class="" href="https://www.uber.com/learn" id="">');
17919         __out.push(__sanitize(t("Learn More")));
17920         __out.push('</a></li>\n        <li><a class="" href="http://blog.uber.com" id="">');
17921         __out.push(__sanitize(t("Blog")));
17922         __out.push('</a></li>\n        <li><a class="" href="/#!/sign-in">');
17923         __out.push(__sanitize(t("Sign In")));
17924         __out.push(' &raquo;</a></li>\n      ');
17925       }
17926       __out.push('\n      ');
17927       if (this.type === 'client') {
17928         __out.push('\n        ');
17929         if ($.cookie('user') && JSON.parse($.cookie('user')).is_admin) {
17930           __out.push('\n            <li><a class="" href="/#!/request" id="">');
17931           __out.push(__sanitize(t("Ride Request")));
17932           __out.push('</a></li>\n        ');
17933         }
17934         __out.push('\n        <li><a class="" href="/#!/dashboard" id="">');
17935         __out.push(__sanitize(t("Dashboard")));
17936         __out.push('</a></li>\n        <li><a class="" href="/#!/invite" id="">');
17937         __out.push(__sanitize(t("Invite Friends")));
17938         __out.push('</a></li>\n        <li><a class="" href="/#!/promotions" id="">');
17939         __out.push(__sanitize(t("Promotions")));
17940         __out.push('</a></li>\n        <li><a class="" href="/#!/billing" id="">');
17941         __out.push(__sanitize(t("Billing")));
17942         __out.push('</a></li>\n        <li><a class="" href="/#!/settings/information" id="">');
17943         __out.push(__sanitize(t("Settings")));
17944         __out.push('</a></li>\n        <li><a class="" href="/#!/sign-out">');
17945         __out.push(__sanitize(t("Sign Out")));
17946         __out.push(' &raquo;</a></li>\n      ');
17947       }
17948       __out.push('\n    </ul>\n  </div>\n</div>\n');
17949     }).call(this);
17950     
17951   }).call(__obj);
17952   __obj.safe = __objSafe, __obj.escape = __escape;
17953   return __out.join('');
17954 }}, "translations/en": function(exports, require, module) {(function() {
17955   exports.translations = {
17956     "Uber": "Uber",
17957     "Sign Up": "Sign Up",
17958     "Ride Request": "Ride Request",
17959     "Invite Friends": "Invite Friends",
17960     "Promotions": "Promotions",
17961     "Billing": "Billing",
17962     "Settings": "Settings",
17963     "Forgot Password?": "Forgot Password?",
17964     "Password Recovery": "Password Recovery",
17965     "Login": "Login",
17966     "Trip Detail": "Trip Detail",
17967     "Password Reset": "Password Reset",
17968     "Confirm Email": "Confirm Email",
17969     "Request Ride": "Request Ride",
17970     "Credit Card Number": "Credit Card Number",
17971     "month": "month",
17972     "01-Jan": "01-Jan",
17973     "02-Feb": "02-Feb",
17974     "03-Mar": "03-Mar",
17975     "04-Apr": "04-Apr",
17976     "05-May": "05-May",
17977     "06-Jun": "06-Jun",
17978     "07-Jul": "07-Jul",
17979     "08-Aug": "08-Aug",
17980     "09-Sep": "09-Sep",
17981     "10-Oct": "10-Oct",
17982     "11-Nov": "11-Nov",
17983     "12-Dec": "12-Dec",
17984     "year": "year",
17985     "CVV": "CVV",
17986     "Category": "Category",
17987     "personal": "personal",
17988     "business": "business",
17989     "Default Credit Card": "Default Credit Card",
17990     "Add Credit Card": "Add Credit Card",
17991     "Expiry": "Expiry",
17992     "default card": "default card",
17993     "make default": "make default",
17994     "Edit": "Edit",
17995     "Delete": "Delete",
17996     "Expiry Month": "Expiry Month",
17997     "Expiry Year": "Expiry Year",
17998     "Unable to Verify Card": "Unable to verify card at this time. Please try again later.",
17999     "Credit Card Update Succeeded": "Your card has been successfully updated!",
18000     "Credit Card Update Failed": "We couldn't save your changes. Please try again in a few minutes.",
18001     "Credit Card Delete Succeeded": "Your card has been deleted!",
18002     "Credit Card Delete Failed": "We were unable to delete your card. Please try again later.",
18003     "Credit Card Update Category Succeeded": "Successfully changed card category!",
18004     "Credit Card Update Category Failed": "We couldn't change your card category. Please try again in a few minutes.",
18005     "Credit Card Update Default Succeeded": "Successfully changed default card!",
18006     "Credit Card Update Default Failed": "We couldn't change your default card. Please try again in a few minutes.",
18007     "Hello Greeting": "Hello, <%= name %>",
18008     "Card Ending in": "Card Ending in",
18009     "Trip Map": "Trip Map",
18010     "Amount": "Amount: <%= amount %>",
18011     "Last Attempt to Bill": "Last Attempt to Bill: <%= date %>",
18012     "Charge": "Charge",
18013     "Uber Credit Balance Note": "Your account has an UberCredit balance of <%= amount %>. When billing for trips, we'll deplete your UberCredit balance before applying charges to your credit card.",
18014     "Please Add Credit Card": "Please add a credit card to bill your outstanding charges.",
18015     "Credit Cards": "Credit Cards",
18016     "add a new credit card": "add a new credit card",
18017     "Account Balance": "Account Balance",
18018     "Arrears": "Arrears",
18019     "Billing Succeeded": "Your card was successfully billed.",
18020     "Confirm Email Succeeded": "Successfully confirmed email token, redirecting to log in page...",
18021     "Confirm Email Failed": "Unable to confirm email. Please contact support@uber.com if this problem persists.",
18022     "Email Already Confirmed": "Your email address has already been confirmed, redirecting to log in page...",
18023     "Credit Card Added": "Credit Card Added",
18024     "No Credit Card": "No Credit Card",
18025     "Mobile Number Confirmed": "Mobile Number Confirmed",
18026     "No Confirmed Mobile": "No Confirmed Mobile",
18027     "E-mail Address Confirmed": "E-mail Address Confirmed",
18028     "No Confirmed E-mail": "No Confirmed E-mail",
18029     'Reply to sign up text': 'Reply "GO" to the text message you received at sign up.',
18030     "Resend text message": "Resend text message",
18031     "Click sign up link": "Click the link in the email you received at sign up.",
18032     "Resend email": "Resend email",
18033     "Add a credit card to ride": "Add a credit card and you'll be ready to ride Uber.",
18034     "Your Most Recent Trip": "Your Most Recent Trip",
18035     "details": "details",
18036     "Your Trip History ": "Your Trip History ",
18037     "Status": "Status",
18038     "Here's how it works:": "Here's how it works:",
18039     "Show all trips": "Show all trips",
18040     "Set your location:": "Set your location:",
18041     "App search for address": "iPhone/Android app: fix the pin or search for an address",
18042     "SMS text address": "SMS: text your address to UBRCAB (827222)",
18043     "Confirm pickup request": "Confirm your pickup request",
18044     "Uber sends ETA": "Uber will send you an ETA (usually within 5-10 minutes)",
18045     "Car arrives": "When your car is arriving, Uber will inform you again.",
18046     "Ride to destination": "Hop in the car and tell the driver your destination.",
18047     "Thank your driver": "That’s it! Please thank your driver but remember that your tip is included and no cash is necessary.",
18048     "Trip started here": "Trip started here",
18049     "Trip ended here": "Trip ended here",
18050     "Sending Email": "Sending email...",
18051     "Resend Email Succeeded": "We just sent the email. Please click on the confirmation link you recieve.",
18052     "Resend Email Failed": "There was an error sending the email. Please contact support if the problem persists.",
18053     "Resend Text Succeeded": 'We just sent the text message. Please reply "GO" to the message you recieve. It may take a few minutes for the message to reach you phone.',
18054     "Resend Text Failed": "There was an error sending the text message. Please contact support if the problem persists.",
18055     "Password Reset Error": "There was an error processing your password reset request.",
18056     "New Password": "New Password",
18057     "Forgot Password": "Forgot Password",
18058     "Forgot Password Error": "Your email address could not be found. Please make sure to use the same email address you used when you signed up.",
18059     "Forgot Password Success": "Please check your email for a link to reset your password.",
18060     "Forgot Password Enter Email": 'Enter your email address and Uber will send you a link to reset your password. If you remember your password, you can <a href="/#!/sign-in">sign in here</a>.',
18061     "Invite friends": "Invite friends",
18062     "Give $ Get $": "Give $10, Get $10",
18063     "Give $ Get $ Description": "Every friend you invite to Uber gets $10 of Uber credit. After someone you’ve invited takes his/her first ride, you get $10 of Uber credits too!",
18064     "What are you waiting for?": "So, what are you waiting for? Invite away!",
18065     "Tweet": "Tweet",
18066     "Invite Link": "Email or IM this link to your friends:",
18067     "Email Address": "Email Address",
18068     "Reset Password": "Reset Password",
18069     "Enter Promotion Code": "If you have a promotion code, enter it here:",
18070     "Your Active Promotions": "Your Active Promotions",
18071     "Code": "Code",
18072     "Details": "Details",
18073     "Trips Remaining": "Trips Remaining",
18074     "Expires": "Expires",
18075     "No Active Promotions": "There are no active promotions on your account.",
18076     "Your Available Promotions": "Your Available Promotions",
18077     "Where do you want us to pick you up?": "Where do you want us to pick you up?",
18078     "Address to search": "Address to search",
18079     "Search": "Search",
18080     "Driver Name:": "Driver Name:",
18081     "Driver #:": "Driver #:",
18082     "Pickup Address:": "Pickup Address:",
18083     "Add to Favorite Locations": "Add to Favorite Locations",
18084     "Star": "Star",
18085     "Nickname:": "Nickname:",
18086     "Add": "Add",
18087     "Your last trip": "Your last trip",
18088     "Please rate your driver:": "Please rate your driver:",
18089     "Comments: (optional)": "Comments: (optional)",
18090     "Rate Trip": "Rate Trip",
18091     "Pickup time:": "Pickup time:",
18092     "Miles:": "Miles:",
18093     "Trip time:": "Trip time:",
18094     "Fare:": "Fare:",
18095     "Favorite Locations": "Favorite Locations",
18096     "Search Results": "Search Results",
18097     "You have no favorite locations saved.": "You have no favorite locations saved.",
18098     "Loading...": "Loading...",
18099     "Request Pickup": "Request Pickup",
18100     "Cancel Pickup": "Cancel Pickup",
18101     "Requesting Closest Driver": "Requesting the closest driver to pick you up...",
18102     "En Route": "You are currently en route...",
18103     "Rate Last Trip": "Please rate your trip to make another request",
18104     "Rate Before Submitting": "Please rate your trip before submitting the form",
18105     "Address too short": "Address too short",
18106     "or did you mean": "or did you mean",
18107     "Search Address Failed": "Unable to find the given address. Please enter another address close to your location.",
18108     "Sending pickup request...": "Sending pickup request...",
18109     "Cancel Request Prompt": "Are you sure you want to cancel your request?",
18110     "Cancel Request Arrived Prompt": 'Are you sure you want to cancel your request? Your driver has arrived so there is a $10 cancellation fee. It may help to call your driver now',
18111     "Favorite Location Nickname Length Error": "Nickname has to be atleast 3 characters",
18112     "Favorite Location Save Succeeded": "Location Saved!",
18113     "Favorite Location Save Failed": "Unable to save your location. Please try again later.",
18114     "Favorite Location Title": "Favorite Location <%= id %>",
18115     "Search Location Title": "Search Location <%= id %>",
18116     "ETA Message": "ETA: Around <%= minutes %> Minutes",
18117     "Nearest Cab Message": "The closest driver is approximately <%= minutes %> minute(s) away",
18118     "Arrival ETA Message": "Your Uber will arrive in about <%= minutes %> minute(s)",
18119     "Arriving Now Message": "Your Uber is arriving now...",
18120     "Rating Driver Failed": "Unable to contact server. Please try again later or email support if this issue persists.",
18121     "Account Information": "Account Information",
18122     "Mobile Phone Information": "Mobile Phone Information",
18123     "settings": "settings",
18124     "Information": "Information",
18125     "Picture": "Picture",
18126     "Change password": "Change password",
18127     "Your current Picture": "Your current Picture",
18128     "Your Favorite Locations": "Your Favorite Locations",
18129     "You have no favorite locations saved.": "You have no favorite locations saved.",
18130     "Purpose of Mobile": "We send text messages to your mobile phone to tell you when your driver is arriving. You can also request trips using text messages.",
18131     "Country": "Country",
18132     "Mobile Number": "Mobile Number",
18133     "Submit": "Submit",
18134     "Favorite Location": "Favorite Location",
18135     "No Approximate Address": "Could not find an approximate address",
18136     "Address:": "Address:",
18137     "Information Update Succeeded": "Your information has been updated!",
18138     "Information Update Failed": "We couldn't update your information. Please try again in few minutes or contact support if the problem persists.",
18139     "Location Delete Succeeded": "Location deleted!",
18140     "Location Delete Failed": "We were unable to delete your favorite location. Please try again later or contact support of the issue persists.",
18141     "Location Edit Succeeded": "Changes Saved!",
18142     "Location Edit Failed": "We couldn't save your changes. Please try again in a few minutes.",
18143     "Picture Update Succeeded": "Your picture has been updated!",
18144     "Picture Update Failed": "We couldn't change your picture. Please try again in a few minutes.",
18145     "Personal Information": "Personal Information",
18146     "Mobile Phone Number": "Mobile Phone Number",
18147     "Payment Information": "Payment Information",
18148     "Purpose of Credit Card": "We keep your credit card on file so that your trip go as fast as possible. You will not be charged until you take a trip.",
18149     "Your card will not be charged until you take a trip.": "Your card will not be charged until you take a trip.",
18150     "Credit Card Number": "Credit Card Number",
18151     "Expiration Date": "Expiration Date",
18152     "Promotion Code": "Promotion Code",
18153     "Enter Promo Here": "If you have a code for a promotion, invitation or group deal, you can enter it here.",
18154     "Promotion Code Input Label": "Promotion, Invite or Groupon Code (optional)",
18155     "Terms and Conditions": "Terms and Conditions",
18156     "HELP": "HELP",
18157     "STOP": "STOP",
18158     "Legal Information": "Legal Information",
18159     "Sign Up Agreement": "By signing up, I agree to the Uber <%= terms_link %> and <%= privacy_link %> and understand that Uber is a request tool, not a transportation carrier.",
18160     "Sign Up Agreement Error": "You must agree to the Uber Terms and Conditions and Privacy Policy to continue.",
18161     "Message and Data Rates Disclosure": "Message and Data Rates May Apply. Reply <%= help_string %> to 827-222 for help. Reply <%= stop_string %> to 827-222 to stop texts. For additional assistance, visit support.uber.com or call (866) 576-1039. Supported Carriers: AT&amp;T, Sprint, Verizon, and T-Mobile.",
18162     "I Agree": "I agree to the Terms &amp; Conditions and Privacy Policy",
18163     "Security Code": "Security Code",
18164     "Type of Card": "Type of Card",
18165     "Personal": "Personal",
18166     "Business": "Business",
18167     "Code": "Code",
18168     "Zip or Postal Code": "Zip or Postal Code",
18169     "Your Trip": "Your Trip",
18170     "Trip Info": "Trip Info",
18171     "Request a fare review": "Request a fare review",
18172     "Fare Review Submitted": "Your fare review has been submitted. We'll get back to you soon about your request. Sorry for any inconvenience this may have caused!",
18173     "Fair Price Consideration": "We're committed to delivering Uber service at a fair price. Before requesting a fare review, please consider:",
18174     "Your Fare Calculation": "Your Fare Calculation",
18175     "Charges": "Charges",
18176     "Discounts": "Discounts",
18177     "Total Charge": "Total Charge",
18178     "Uber pricing information": "Uber pricing information",
18179     "Uber Pricing Information Message": "<%= learn_link %> is published on our website.",
18180     "GPS Point Capture Disclosure": "Due to a finite number of GPS point captures, corners on your trip map may appear cut off or rounded. These minor inaccuracies result in a shorter measured distance, which always results in a cheaper trip.",
18181     "Fare Review Note": "Please elaborate on why this trip requires a fare review. Your comments below will help us better establish the correct price for your trip:",
18182     "Fare Review Error": "There was an error submitting the review. Please ensure that you have a message.",
18183     "Sign In": "Sign In"
18184   };
18185 }).call(this);
18186 }, "translations/fr": function(exports, require, module) {(function() {
18187   exports.translations = {
18188     "Uber": "Uber",
18189     "Sign Up": "Inscription",
18190     "Ride Request": "Passer une Commande",
18191     "Invite Friends": "Inviter vos Amis",
18192     "Promotions": "Promotions",
18193     "Billing": "Paiement",
18194     "Settings": "Paramètres",
18195     "Forgot Password?": "Mot de passe oublié ?",
18196     "Password Recovery": "Récupération du mot de passe",
18197     "Login": "Connexion",
18198     "Trip Detail": "Détail de la Course",
18199     "Password Reset": "Réinitialisation du mot de passe",
18200     "Confirm Email": "Confirmation de l’e-mail",
18201     "Request Ride": "Passer une Commande",
18202     "Credit Card Number": "Numéro de Carte de Crédit",
18203     "month": "mois",
18204     "01-Jan": "01-Jan",
18205     "02-Feb": "02-Fév",
18206     "03-Mar": "03-Mar",
18207     "04-Apr": "04-Avr",
18208     "05-May": "05-Mai",
18209     "06-Jun": "06-Juin",
18210     "07-Jul": "07-Jui",
18211     "08-Aug": "08-Aoû",
18212     "09-Sep": "09-Sep",
18213     "10-Oct": "10-Oct",
18214     "11-Nov": "11-Nov",
18215     "12-Dec": "12-Déc",
18216     "year": "année",
18217     "CVV": "Code de Sécurité",
18218     "Category": "Type",
18219     "personal": "personnel",
18220     "business": "entreprise",
18221     "Default Credit Card": "Carte par Défaut",
18222     "Add Credit Card": "Ajouter une Carte",
18223     "Expiry": "Expire",
18224     "default card": "carte par défaut",
18225     "make default": "choisir par défaut",
18226     "Edit": "Modifier",
18227     "Delete": "Supprimer",
18228     "Expiry Month": "Mois d’Expiration",
18229     "Expiry Year": "Année d’Expiration",
18230     "Unable to Verify Card": "Impossible de vérifier la carte pour le moment. Merci de réessayer un peu plus tard.",
18231     "Credit Card Update Succeeded": "Votre carte a été mise à jour avec succès !",
18232     "Credit Card Update Failed": "Nous ne pouvons enregistrer vos changements. Merci de réessayer dans quelques minutes.",
18233     "Credit Card Delete Succeeded": "Votre carte a été supprimée !",
18234     "Credit Card Delete Failed": "Nous n’avons pas été en mesure de supprimer votre carte. Merci de réessayer plus tard.",
18235     "Credit Card Update Category Succeeded": "Changement de catégorie de carte réussi !",
18236     "Credit Card Update Category Failed": "Nous ne pouvons pas changer la catégorie de votre carte. Merci de réessayer dans quelques minutes.",
18237     "Credit Card Update Default Succeeded": "Carte par défaut changée avec succès !",
18238     "Credit Card Update Default Failed": "Nous ne pouvons pas changer votre carte par défaut. Merci de réessayer dans quelques minutes.",
18239     "Hello Greeting": "Bonjour, <%= name %>",
18240     "Card Ending in": "La carte expire dans",
18241     "Trip Map": "Carte des Courses",
18242     "Amount": "Montant: <%= amount %>",
18243     "Last Attempt to Bill": "Dernière tentative de prélèvement : <%= date %>",
18244     "Charge": "Débit",
18245     "Uber Credit Balance Note": "Votre compte a un solde de <%= amount %> UberCredits. Lorsque nous facturons des courses, nous réduirons votre solde d’UberCredits avant de prélever votre carte de crédit.",
18246     "Please Add Credit Card": "Merci d’ajouter une carte de crédit pour que nous puissions vous facturer.",
18247     "Credit Cards": "Cartes de crédit",
18248     "add a new credit card": "Ajouter une nouvelle carte de crédit",
18249     "Account Balance": "Solde du compte",
18250     "Arrears": "Arriérés",
18251     "Billing Succeeded": "Votre carte a été correctement débitée.",
18252     "Confirm Email Succeeded": "L’adresse e-mail a bien été validée, vous êtes redirigé vers le tableau de bord...",
18253     "Confirm Email Failed": "Impossible de confirmer l’adresse e-mail. Merci de contacter support@uber.com si le problème persiste.",
18254     "Credit Card Added": "Carte de crédit ajoutée",
18255     "No Credit Card": "Pas de carte de crédit",
18256     "Mobile Number Confirmed": "Numéro de téléphone confirmé",
18257     "No Confirmed Mobile": "Pas de numéro de téléphone confirmé",
18258     "E-mail Address Confirmed": "Adresse e-mail confirmée",
18259     "No Confirmed E-mail": "Pas d’adresse e-mail confirmée",
18260     'Reply to sign up text': 'Répondre "GO" au SMS que vous avez reçu à l’inscription.',
18261     "Resend text message": "Renvoyer le SMS",
18262     "Click sign up link": "Cliquez sur le lien contenu dans l’e-mail reçu à l’inscription.",
18263     "Resend email": "Renvoyer l’e-mail",
18264     "Add a credit card to ride": "Ajouter une carte de crédit et vous serez prêt à voyager avec Uber.",
18265     "Your Most Recent Trip": "Votre course la plus récente",
18266     "details": "détails",
18267     "Your Trip History": "Historique de votre trajet",
18268     "Status": "Statut",
18269     "Here's how it works:": "Voici comment ça marche :",
18270     "Show all trips": "Montrer toutes les courses",
18271     "Set your location:": "Définir votre position :",
18272     "App search for address": "Application iPhone/Android : positionner la punaise ou rechercher une adresse",
18273     "SMS text address": "SMS : envoyez votre adresse à UBRCAB (827222)",
18274     "Confirm pickup request": "Validez la commande",
18275     "Uber sends ETA": "Uber envoie un temps d’attente estimé (habituellement entre 5 et 10 minutes)",
18276     "Car arrives": "Lorsque votre voiture arrive, Uber vous en informera encore..",
18277     "Ride to destination": "Montez dans la voiture et donnez votre destination au chauffeur.",
18278     "Thank your driver": "C’est tout ! Remerciez le chauffeur mais souvenez-vous que les pourboires sont compris et qu’il n’est pas nécessaire d’avoir du liquide sur soi.",
18279     "Trip started here": "La course a commencé ici.",
18280     "Trip ended here": "La course s’est terminée ici.",
18281     "Sending Email": "Envoi de l’e-mail...",
18282     "Resend Email Succeeded": "Nous venons d’envoyer l’e-mail. Merci de cliquer sur le lien de confirmation que vous avez reçu.",
18283     "Resend Email Failed": "Il y a eu un problème lors de l’envoi de l’email. Merci de contacter le support si le problème persiste.",
18284     "Resend Text Succeeded": 'Nous venons d’envoyer le SMS. Merci de répondre "GO" au message que vous avez reçu. Il se peut que cela prenne quelques minutes pour que le message arrive sur votre téléphone.',
18285     "Resend Text Failed": "Il y a eu un problème lors de l’envoi du SMS. Merci de contacter le support si le problème persiste.",
18286     "Password Reset Error": "Il y a eu une error lors de la réinitialisation de votre mot de passe.",
18287     "New Password:": "Nouveau mot de passe:",
18288     "Forgot Password Error": "Votre nom d’utilisateur / adresse email ne peut être trouvé. Merci d’utiliser la même qu’à l’inscription.",
18289     "Forgot Password Success": "Merci de consulter votre boîte mail pour suivre la demande de ‘réinitialisation de mot de passe.",
18290     "Forgot Password Enter Email": "Merci de saisir votre adresse email et nous vous enverrons un lien vous permettant de réinitialiser votre mot de passe :",
18291     "Invite friends": "Inviter vos amis",
18292     "Give $ Get $": "Donnez $10, Recevez $10",
18293     "Give $ Get $ Description": "Chaque ami que vous invitez à Uber  recevra $10 de crédits Uber. Dès lors qu’une personne que vous aurez invité aura utilisé Uber pour la première, vous recevrez $10 de crédits Uber également !",
18294     "What are you waiting for?": "N’attendez plus ! Lancez les invitations !",
18295     "Tweet": "Tweeter",
18296     "Invite Link": "Envoyez ce lien par email ou messagerie instantanée à vos amis :",
18297     "Enter Promotion Code": "Si vous avez un code promo, saisissez-le ici:",
18298     "Your Active Promotions": "Vos Codes Promos Actifs",
18299     "Code": "Code",
18300     "Details": "Détails",
18301     "Trips Remaining": "Courses restantes",
18302     "Expires": "Expire",
18303     "No Active Promotions": "Vous n’avez pas de code promo actif.",
18304     "Your Available Promotions": "Votres Promos Disponibles",
18305     "Where do you want us to pick you up?": "Où souhaitez-vous que nous vous prenions en charge ?",
18306     "Address to search": "Adresse à rechercher",
18307     "Search": "Chercher",
18308     "Driver Name:": "Nom du chauffeur:",
18309     "Driver #:": "# Chauffeur:",
18310     "Pickup Address:": "Lieu de prise en charge:",
18311     "Add to Favorite Locations": "Ajoutez aux Lieux Favoris",
18312     "Star": "Étoiles",
18313     "Nickname:": "Pseudo",
18314     "Add": "Ajouter",
18315     "Your last trip": "Votre dernière course",
18316     "Please rate your driver:": "Merci de noter votre chauffeur :",
18317     "Comments: (optional)": "Commentaires: (optionnel)",
18318     "Rate Trip": "Notez votre course",
18319     "Pickup time:": "Heure de Prise en Charge :",
18320     "Miles:": "Kilomètres :",
18321     "Trip time:": "Temps de course :",
18322     "Fare:": "Tarif :",
18323     "Favorite Locations": "Lieux Favoris",
18324     "Search Results": "Résultats",
18325     "You have no favorite locations saved.": "Vous n’avez pas de lieux de prise en charge favoris.",
18326     "Loading...": "Chargement...",
18327     "Request Pickup": "Commander ici",
18328     "Cancel Pickup": "Annuler",
18329     "Requesting Closest Driver": "Nous demandons au chauffeur le plus proche de vous prendre en charge...",
18330     "En Route": "Vous êtes actuellement en route...",
18331     "Rate Last Trip": "Merci de noter votre précédent trajet pour faire une autre course.",
18332     "Rate Before Submitting": "Merci de noter votre trajet avant de le valider.",
18333     "Address too short": "L’adresse est trop courte",
18334     "or did you mean": "ou vouliez-vous dire",
18335     "Search Address Failed": "Impossible de trouver l’adresse spécifiée. Merci de saisir une autre adresse proche de l’endroit où vous vous trouvez.",
18336     "Sending pickup request...": "Envoi de la demande de prise en charge...",
18337     "Cancel Request Prompt": "Voulez-vous vraiment annuler votre demande ?",
18338     "Cancel Request Arrived Prompt": 'Voulez-vous vraiment annuler votre demande ? Votre chauffeur est arrivé, vous serez donc facturé de $10 de frais d’annulation. Il pourrait être utile que vous appeliez votre chauffeur maintenant.',
18339     "Favorite Location Nickname Length Error": "Le pseudo doit faire au moins 3 caractères de long",
18340     "Favorite Location Save Succeeded": "Adresse enregistrée !",
18341     "Favorite Location Save Failed": "Impossible d’enregistrer votre adresse. Merci de réessayer ultérieurement.",
18342     "Favorite Location Title": "Adresse favorie <%= id %>",
18343     "Search Location Title": "Recherche d’adresse <%= id %>",
18344     "ETA Message": "Temps d’attente estimé: environ <%= minutes %> minutes",
18345     "Nearest Cab Message": "Le chauffeur le plus proche sera là dans <%= minutes %> minute(s)",
18346     "Arrival ETA Message": "Votre chauffeur arrivera dans <%= minutes %> minute(s)",
18347     "Arriving Now Message": "Votre chauffeur est en approche...",
18348     "Rating Driver Failed": "Impossible de contacter le serveur. Merci de réessayer ultérieurement ou de contacter le support si le problème persiste.",
18349     "settings": "Paramètres",
18350     "Information": "Information",
18351     "Picture": "Photo",
18352     "Change password": "Modifier votre mot de passe",
18353     "Your current Picture": "Votre photo",
18354     "Your Favorite Locations": "Vos lieux favoris",
18355     "You have no favorite locations saved.": "Vous n’avez pas de lieu favori",
18356     "Account Information": "Informations Personnelles",
18357     "Mobile Phone Information": "Informations de Mobile",
18358     "Change Your Password": "Changez votre mot de passe.",
18359     "Country": "Pays",
18360     "Language": "Langue",
18361     "Favorite Location": "Lieu favori",
18362     "No Approximate Address": "Impossible de trouver une adresse même approximative",
18363     "Address:": "Adresse :",
18364     "Information Update Succeeded": "Vos informations ont été mises à jour !",
18365     "Information Update Failed": "Nous n’avons pas pu mettre à jour vos informations. Merci de réessayer dans quelques instants ou de contacter le support si le problème persiste.",
18366     "Location Delete Succeeded": "Adresse supprimée !",
18367     "Location Delete Failed": "Nous n’avons pas pu supprimée votre adresse favorie. Merci de réessayer plus tard ou de contacter le support si le problème persiste.",
18368     "Location Edit Succeeded": "Modifications sauvegardées !",
18369     "Location Edit Failed": "Nous n’avons pas pu sauvegarder vos modifications. Merci de réessayer dans quelques minutes.",
18370     "Picture Update Succeeded": "Votre photo a été mise à jour !",
18371     "Picture Update Failed": "Nous n’avons pas pu mettre à jour votre photo. Merci de réessayer dans quelques instants.",
18372     "Personal Information": "Informations Personnelles",
18373     "Mobile Phone Number": "Numéro de Téléphone Portable",
18374     "Payment Information": "Informations de Facturation",
18375     "Your card will not be charged until you take a trip.": "Votre carte ne sera pas débitée avant votre premier trajet.",
18376     "Card Number": "Numéro de Carte",
18377     "Promotion Code Input Label": "Code promo, code d’invitation ou “deal” acheté en ligne (optionnel)",
18378     "Terms and Conditions": "Conditions Générales",
18379     "HELP": "HELP",
18380     "STOP": "STOP",
18381     "Sign Up Agreement": "En souscrivant, j’accepte les <%= terms_link %> et <%= privacy_link %>  et comprends qu’Uber est un outil de commande de chauffeur, et non un transporteur.",
18382     "Sign Up Agreement Error": "Vous devez accepter les Conditions Générales d’utilisation d’Uber Terms and Conditions et la Politique de Confidentialité pour continuer.",
18383     "Message and Data Rates Disclosure": "Les frais d’envoi de SMS et de consommation de données peuvent s’appliquer. Répondez <%= help_string %> au 827-222 pour obtenir de l’aide. Répondez <%= stop_string %> au 827-222 pour ne plus recevoir de SMS. Pour plus d’aide, visitez support.uber.com ou appelez le (866) 576-1039. Opérateurs supportés: AT&amp;T, Sprint, Verizon, T-Mobile, Orange, SFR et Bouygues Telecom.",
18384     "Zip/Postal Code": "Code Postal",
18385     "Expiration Date": "Date D'expiration",
18386     "Security Code": "Code de Sécurité",
18387     "Type of Card": "Type",
18388     "Personal": "Personnel",
18389     "Business": "Entreprise",
18390     "Promotion Code": "Code Promo",
18391     "Legal Information": "Mentions Légales",
18392     "I Agree": "J'accepte.",
18393     "Your Trip": "Votre Course",
18394     "Trip Info": "Informations de la Course",
18395     "Request a fare review": "Demander un contrôle du tarif",
18396     "Fare Review Submitted": "Votre demande de contrôle du tarif a été soumis. Nous reviendrons vers vous rapidement concernant cette demande. Nous nous excusons pour les dérangements éventuellement occasionnés !",
18397     "Fair Price Consideration": "Nous nous engageons à proposer Uber à un tarif juste. Avant de demander un contrôle du tarif, merci de prendre en compte :",
18398     "Your Fare Calculation": "Calcul du Prix",
18399     "Charges": "Coûts",
18400     "Discounts": "Réductions",
18401     "Total Charge": "Coût total",
18402     "Uber pricing information": "Information sur les prix d’Uber",
18403     "Uber Pricing Information Message": "<%= learn_link %> est disponible sur notre site web.",
18404     "GPS Point Capture Disclosure": "A cause d’un nombre limité de coordonnées GPS sauvegardées, les angles de votre trajet sur la carte peuvent apparaître coupés ou arrondis. Ces légères incohérences débouchent sur des distances mesurées plus courtes, ce qui implique toujours un prix du trajet moins élevé.",
18405     "Fare Review Note": "Merci de nous expliquer pourquoi le tarif de cette course nécessite d’être contrôlé. Vos commentaires ci-dessous nous aideront à établir un prix plus juste si nécessaire :",
18406     "Fare Review Error": "Il y a eu une erreur lors de l’envoi de la demande. Assurez-vous d’avoir bien ajouté une description à votre demande."
18407   };
18408 }).call(this);
18409 }, "views/clients/billing": function(exports, require, module) {(function() {
18410   var clientsBillingTemplate;
18411   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
18412     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
18413     function ctor() { this.constructor = child; }
18414     ctor.prototype = parent.prototype;
18415     child.prototype = new ctor;
18416     child.__super__ = parent.prototype;
18417     return child;
18418   }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
18419   clientsBillingTemplate = require('templates/clients/billing');
18420   exports.ClientsBillingView = (function() {
18421     __extends(ClientsBillingView, UberView);
18422     function ClientsBillingView() {
18423       ClientsBillingView.__super__.constructor.apply(this, arguments);
18424     }
18425     ClientsBillingView.prototype.id = 'billing_view';
18426     ClientsBillingView.prototype.className = 'view_container';
18427     ClientsBillingView.prototype.events = {
18428       'click a#add_card': 'addCard',
18429       'click .charge_arrear': 'chargeArrear'
18430     };
18431     ClientsBillingView.prototype.render = function() {
18432       this.RefreshUserInfo(__bind(function() {
18433         var cards, newForm;
18434         this.HideSpinner();
18435         $(this.el).html(clientsBillingTemplate());
18436         if (USER.payment_gateway.payment_profiles.length === 0) {
18437           newForm = new app.views.clients.modules.creditcard;
18438           $(this.el).find("#add_card_wrapper").html(newForm.render(0).el);
18439         } else {
18440           cards = new app.views.clients.modules.creditcard;
18441           $("#cards").html(cards.render("all").el);
18442         }
18443         return this.delegateEvents();
18444       }, this));
18445       return this;
18446     };
18447     ClientsBillingView.prototype.addCard = function(e) {
18448       var newCard;
18449       e.preventDefault();
18450       newCard = new app.views.clients.modules.creditcard;
18451       $('#cards').append(newCard.render("new").el);
18452       return $("a#add_card").hide();
18453     };
18454     ClientsBillingView.prototype.chargeArrear = function(e) {
18455       var $el, arrearId, attrs, cardId, options, tryCharge;
18456       e.preventDefault();
18457       $(".error_message").text("");
18458       $el = $(e.currentTarget);
18459       arrearId = $el.attr('id');
18460       cardId = $el.parent().find('#card_to_charge').val();
18461       this.ShowSpinner('submit');
18462       tryCharge = new app.models.clientbills({
18463         id: arrearId
18464       });
18465       attrs = {
18466         payment_profile_id: cardId,
18467         dataType: 'json'
18468       };
18469       options = {
18470         success: __bind(function(data, textStatus, jqXHR) {
18471           $el.parent().find(".success_message").text(t("Billing Succeeded"));
18472           $el.hide();
18473           return $el.parent().find('#card_to_charge').hide();
18474         }, this),
18475         error: __bind(function(jqXHR, status, errorThrown) {
18476           return $el.parent().find(".error_message").text(JSON.parse(status.responseText).error);
18477         }, this),
18478         complete: __bind(function() {
18479           return this.HideSpinner();
18480         }, this)
18481       };
18482       return tryCharge.save(attrs, options);
18483     };
18484     return ClientsBillingView;
18485   })();
18486 }).call(this);
18487 }, "views/clients/confirm_email": function(exports, require, module) {(function() {
18488   var clientsConfirmEmailTemplate;
18489   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
18490     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
18491     function ctor() { this.constructor = child; }
18492     ctor.prototype = parent.prototype;
18493     child.prototype = new ctor;
18494     child.__super__ = parent.prototype;
18495     return child;
18496   }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
18497   clientsConfirmEmailTemplate = require('templates/clients/confirm_email');
18498   exports.ClientsConfirmEmailView = (function() {
18499     __extends(ClientsConfirmEmailView, UberView);
18500     function ClientsConfirmEmailView() {
18501       ClientsConfirmEmailView.__super__.constructor.apply(this, arguments);
18502     }
18503     ClientsConfirmEmailView.prototype.id = 'confirm_email_view';
18504     ClientsConfirmEmailView.prototype.className = 'view_container';
18505     ClientsConfirmEmailView.prototype.render = function(token) {
18506       var attrs;
18507       $(this.el).html(clientsConfirmEmailTemplate());
18508       attrs = {
18509         data: {
18510           email_token: token
18511         },
18512         success: __bind(function(data, textStatus, jqXHR) {
18513           var show_dashboard;
18514           this.HideSpinner();
18515           show_dashboard = function() {
18516             return app.routers.clients.navigate('!/dashboard', true);
18517           };
18518           if (data.status === 'OK') {
18519             $('.success_message').show();
18520             return _.delay(show_dashboard, 3000);
18521           } else if (data.status === 'ALREADY_COMFIRMED') {
18522             $('.already_confirmed_message').show();
18523             return _.delay(show_dashboard, 3000);
18524           } else {
18525             return $('.error_message').show();
18526           }
18527         }, this),
18528         error: __bind(function(e) {
18529           this.HideSpinner();
18530           return $('.error_message').show();
18531         }, this),
18532         complete: function(status) {
18533           return $('#attempt_text').hide();
18534         },
18535         dataType: 'json',
18536         type: 'PUT',
18537         url: "" + API + "/users/self"
18538       };
18539       $.ajax(attrs);
18540       this.ShowSpinner('submit');
18541       return this;
18542     };
18543     return ClientsConfirmEmailView;
18544   })();
18545 }).call(this);
18546 }, "views/clients/dashboard": function(exports, require, module) {(function() {
18547   var clientsDashboardTemplate;
18548   var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
18549     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
18550     function ctor() { this.constructor = child; }
18551     ctor.prototype = parent.prototype;
18552     child.prototype = new ctor;
18553     child.__super__ = parent.prototype;
18554     return child;
18555   };
18556   clientsDashboardTemplate = require('templates/clients/dashboard');
18557   exports.ClientsDashboardView = (function() {
18558     var displayFirstTrip;
18559     __extends(ClientsDashboardView, UberView);
18560     function ClientsDashboardView() {
18561       this.showAllTrips = __bind(this.showAllTrips, this);
18562       this.render = __bind(this.render, this);
18563       ClientsDashboardView.__super__.constructor.apply(this, arguments);
18564     }
18565     ClientsDashboardView.prototype.id = 'dashboard_view';
18566     ClientsDashboardView.prototype.className = 'view_container';
18567     ClientsDashboardView.prototype.events = {
18568       'click a.confirmation': 'confirmationClick',
18569       'click #resend_email': 'resendEmail',
18570       'click #resend_mobile': 'resendMobile',
18571       'click #show_all_trips': 'showAllTrips'
18572     };
18573     ClientsDashboardView.prototype.render = function() {
18574       var displayPage, downloadTrips;
18575       this.HideSpinner();
18576       displayPage = __bind(function() {
18577         $(this.el).html(clientsDashboardTemplate());
18578         this.confirmationsSetup();
18579         return this.RequireMaps(__bind(function() {
18580           if (USER.trips.models[0]) {
18581             if (!USER.trips.models[0].get("points")) {
18582               return USER.trips.models[0].fetch({
18583                 data: {
18584                   relationships: 'points'
18585                 },
18586                 success: __bind(function() {
18587                   this.CacheData("USERtrips", USER.trips);
18588                   return displayFirstTrip();
18589                 }, this)
18590               });
18591             } else {
18592               return displayFirstTrip();
18593             }
18594           }
18595         }, this));
18596       }, this);
18597       downloadTrips = __bind(function() {
18598         return this.DownloadUserTrips(displayPage, false, 10);
18599       }, this);
18600       this.RefreshUserInfo(downloadTrips);
18601       return this;
18602     };
18603     displayFirstTrip = __bind(function() {
18604       var bounds, endPos, map, myOptions, path, polyline, startPos;
18605       myOptions = {
18606         zoom: 12,
18607         mapTypeId: google.maps.MapTypeId.ROADMAP,
18608         zoomControl: false,
18609         rotateControl: false,
18610         panControl: false,
18611         mapTypeControl: false,
18612         scrollwheel: false
18613       };
18614       if (USER.trips.length === 10) {
18615         $("#show_all_trips").show();
18616       }
18617       if (USER.trips.length > 0) {
18618         map = new google.maps.Map(document.getElementById("trip_details_map"), myOptions);
18619         bounds = new google.maps.LatLngBounds();
18620         path = [];
18621         _.each(USER.trips.models[0].get('points'), __bind(function(point) {
18622           path.push(new google.maps.LatLng(point.lat, point.lng));
18623           return bounds.extend(_.last(path));
18624         }, this));
18625         map.fitBounds(bounds);
18626         startPos = new google.maps.Marker({
18627           position: _.first(path),
18628           map: map,
18629           title: t('Trip started here'),
18630           icon: 'https://uber-static.s3.amazonaws.com/marker_start.png'
18631         });
18632         endPos = new google.maps.Marker({
18633           position: _.last(path),
18634           map: map,
18635           title: t('Trip ended here'),
18636           icon: 'https://uber-static.s3.amazonaws.com/marker_end.png'
18637         });
18638         polyline = new google.maps.Polyline({
18639           path: path,
18640           strokeColor: '#003F87',
18641           strokeOpacity: 1,
18642           strokeWeight: 5
18643         });
18644         return polyline.setMap(map);
18645       }
18646     }, ClientsDashboardView);
18647     ClientsDashboardView.prototype.confirmationsSetup = function() {
18648       var blink, cardForm, element, _ref, _ref2, _ref3, _ref4, _ref5;
18649       blink = function(element) {
18650         var opacity;
18651         opacity = 0.5;
18652         if (element.css('opacity') === "0.5") {
18653           opacity = 1.0;
18654         }
18655         return element.fadeTo(2000, opacity, function() {
18656           return blink(element);
18657         });
18658       };
18659       if (((_ref = window.USER) != null ? (_ref2 = _ref.payment_gateway) != null ? (_ref3 = _ref2.payment_profiles) != null ? _ref3.length : void 0 : void 0 : void 0) === 0) {
18660         element = $('#confirmed_credit_card');
18661         cardForm = new app.views.clients.modules.creditcard;
18662         $('#card.info').append(cardForm.render().el);
18663         blink(element);
18664       }
18665       if (((_ref4 = window.USER) != null ? _ref4.confirm_email : void 0) === false) {
18666         element = $('#confirmed_email');
18667         blink(element);
18668       }
18669       if ((((_ref5 = window.USER) != null ? _ref5.confirm_mobile : void 0) != null) === false) {
18670         element = $('#confirmed_mobile');
18671         return blink(element);
18672       }
18673     };
18674     ClientsDashboardView.prototype.confirmationClick = function(e) {
18675       e.preventDefault();
18676       $('.info').hide();
18677       $('#more_info').show();
18678       switch (e.currentTarget.id) {
18679         case "card":
18680           return $('#card.info').slideToggle();
18681         case "mobile":
18682           return $('#mobile.info').slideToggle();
18683         case "email":
18684           return $('#email.info').slideToggle();
18685       }
18686     };
18687     ClientsDashboardView.prototype.resendEmail = function(e) {
18688       var $el;
18689       e.preventDefault();
18690       $el = $(e.currentTarget);
18691       $el.removeAttr('href').prop({
18692         disabled: true
18693       });
18694       $el.html(t("Sending Email"));
18695       return $.ajax({
18696         type: 'GET',
18697         url: API + '/users/request_confirm_email',
18698         data: {
18699           token: USER.token
18700         },
18701         dataType: 'json',
18702         success: __bind(function(data, textStatus, jqXHR) {
18703           return $el.html(t("Resend Email Succeeded"));
18704         }, this),
18705         error: __bind(function(jqXHR, textStatus, errorThrown) {
18706           return $el.html(t("Resend Email Failed"));
18707         }, this)
18708       });
18709     };
18710     ClientsDashboardView.prototype.resendMobile = function(e) {
18711       var $el;
18712       e.preventDefault();
18713       $el = $(e.currentTarget);
18714       $el.removeAttr('href').prop({
18715         disabled: true
18716       });
18717       $el.html("Sending message...");
18718       return $.ajax({
18719         type: 'GET',
18720         url: API + '/users/request_confirm_mobile',
18721         data: {
18722           token: USER.token
18723         },
18724         dataType: 'json',
18725         success: __bind(function(data, textStatus, jqXHR) {
18726           return $el.html(t("Resend Text Succeeded"));
18727         }, this),
18728         error: __bind(function(jqXHR, textStatus, errorThrown) {
18729           return $el.html(t("Resend Text Failed"));
18730         }, this)
18731       });
18732     };
18733     ClientsDashboardView.prototype.showAllTrips = function(e) {
18734       e.preventDefault();
18735       $(e.currentTarget).hide();
18736       return this.DownloadUserTrips(this.render, true, 1000);
18737     };
18738     return ClientsDashboardView;
18739   }).call(this);
18740 }).call(this);
18741 }, "views/clients/forgot_password": function(exports, require, module) {(function() {
18742   var clientsForgotPasswordTemplate;
18743   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
18744     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
18745     function ctor() { this.constructor = child; }
18746     ctor.prototype = parent.prototype;
18747     child.prototype = new ctor;
18748     child.__super__ = parent.prototype;
18749     return child;
18750   }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
18751   clientsForgotPasswordTemplate = require('templates/clients/forgot_password');
18752   exports.ClientsForgotPasswordView = (function() {
18753     __extends(ClientsForgotPasswordView, UberView);
18754     function ClientsForgotPasswordView() {
18755       ClientsForgotPasswordView.__super__.constructor.apply(this, arguments);
18756     }
18757     ClientsForgotPasswordView.prototype.id = 'forgotpassword_view';
18758     ClientsForgotPasswordView.prototype.className = 'view_container modal_view_container';
18759     ClientsForgotPasswordView.prototype.events = {
18760       "submit #password_reset": "passwordReset",
18761       "click #password_reset_submit": "passwordReset",
18762       "submit #forgot_password": "forgotPassword",
18763       "click #forgot_password_submit": "forgotPassword"
18764     };
18765     ClientsForgotPasswordView.prototype.render = function(token) {
18766       this.HideSpinner();
18767       $(this.el).html(clientsForgotPasswordTemplate({
18768         token: token
18769       }));
18770       this.delegateEvents();
18771       return this;
18772     };
18773     ClientsForgotPasswordView.prototype.forgotPassword = function(e) {
18774       var attrs;
18775       e.preventDefault();
18776       $('.success_message').hide();
18777       $(".error_message").hide();
18778       attrs = {
18779         data: {
18780           login: $("#login").val()
18781         },
18782         success: __bind(function(data, textStatus, jqXHR) {
18783           this.HideSpinner();
18784           $('.success_message').show();
18785           return $("#forgot_password").hide();
18786         }, this),
18787         error: __bind(function(e) {
18788           this.HideSpinner();
18789           return $('.error_message').show();
18790         }, this),
18791         dataType: 'json',
18792         type: 'PUT',
18793         url: "" + API + "/users/forgot_password"
18794       };
18795       $.ajax(attrs);
18796       return this.ShowSpinner('submit');
18797     };
18798     ClientsForgotPasswordView.prototype.passwordReset = function(e) {
18799       var attrs;
18800       e.preventDefault();
18801       attrs = {
18802         data: {
18803           email_token: $("#token").val(),
18804           password: $("#password").val()
18805         },
18806         success: __bind(function(data, textStatus, jqXHR) {
18807           this.HideSpinner();
18808           $.cookie('token', data.token);
18809           amplify.store('USERjson', data);
18810           app.refreshMenu();
18811           return location.hash = '!/dashboard';
18812         }, this),
18813         error: __bind(function(e) {
18814           this.HideSpinner();
18815           return $('#error_reset').show();
18816         }, this),
18817         dataType: 'json',
18818         type: 'PUT',
18819         url: "" + API + "/users/self"
18820       };
18821       $.ajax(attrs);
18822       return this.ShowSpinner('submit');
18823     };
18824     return ClientsForgotPasswordView;
18825   })();
18826 }).call(this);
18827 }, "views/clients/invite": function(exports, require, module) {(function() {
18828   var clientsInviteTemplate;
18829   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
18830     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
18831     function ctor() { this.constructor = child; }
18832     ctor.prototype = parent.prototype;
18833     child.prototype = new ctor;
18834     child.__super__ = parent.prototype;
18835     return child;
18836   };
18837   clientsInviteTemplate = require('templates/clients/invite');
18838   exports.ClientsInviteView = (function() {
18839     __extends(ClientsInviteView, UberView);
18840     function ClientsInviteView() {
18841       ClientsInviteView.__super__.constructor.apply(this, arguments);
18842     }
18843     ClientsInviteView.prototype.id = 'invite_view';
18844     ClientsInviteView.prototype.className = 'view_container';
18845     ClientsInviteView.prototype.render = function() {
18846       this.ReadUserInfo();
18847       this.HideSpinner();
18848       $(this.el).html(clientsInviteTemplate());
18849       console.log(screen);
18850       return this;
18851     };
18852     return ClientsInviteView;
18853   })();
18854 }).call(this);
18855 }, "views/clients/login": function(exports, require, module) {(function() {
18856   var clientsLoginTemplate;
18857   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
18858     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
18859     function ctor() { this.constructor = child; }
18860     ctor.prototype = parent.prototype;
18861     child.prototype = new ctor;
18862     child.__super__ = parent.prototype;
18863     return child;
18864   };
18865   clientsLoginTemplate = require('templates/clients/login');
18866   exports.ClientsLoginView = (function() {
18867     __extends(ClientsLoginView, UberView);
18868     function ClientsLoginView() {
18869       ClientsLoginView.__super__.constructor.apply(this, arguments);
18870     }
18871     ClientsLoginView.prototype.id = 'login_view';
18872     ClientsLoginView.prototype.className = 'view_container modal_view_container';
18873     ClientsLoginView.prototype.events = {
18874       'submit form': 'authenticate',
18875       'click button': 'authenticate'
18876     };
18877     ClientsLoginView.prototype.initialize = function() {
18878       _.bindAll(this, 'render');
18879       return this.render();
18880     };
18881     ClientsLoginView.prototype.render = function() {
18882       this.HideSpinner();
18883       $(this.el).html(clientsLoginTemplate());
18884       this.delegateEvents();
18885       return this.place();
18886     };
18887     ClientsLoginView.prototype.authenticate = function(e) {
18888       e.preventDefault();
18889       return $.ajax({
18890         type: 'POST',
18891         url: API + '/auth/web_login/client',
18892         data: {
18893           login: $("#login").val(),
18894           password: $("#password").val()
18895         },
18896         dataType: 'json',
18897         success: function(data, textStatus, jqXHR) {
18898           $.cookie('user', JSON.stringify(data));
18899           $.cookie('token', data.token);
18900           amplify.store('USERjson', data);
18901           $('header').html(app.views.shared.menu.render().el);
18902           return app.routers.clients.navigate('!/dashboard', true);
18903         },
18904         error: function(jqXHR, textStatus, errorThrown) {
18905           $.cookie('user', null);
18906           $.cookie('token', null);
18907           if (jqXHR.status === 403) {
18908             $.cookie('redirected_user', JSON.stringify(JSON.parse(jqXHR.responseText).error_obj), {
18909               domain: '.uber.com'
18910             });
18911             window.location = 'http://partners.uber.com/';
18912           }
18913           return $('.error_message').html(JSON.parse(jqXHR.responseText).error).hide().fadeIn();
18914         }
18915       });
18916     };
18917     return ClientsLoginView;
18918   })();
18919 }).call(this);
18920 }, "views/clients/modules/credit_card": function(exports, require, module) {(function() {
18921   var creditCardTemplate;
18922   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
18923     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
18924     function ctor() { this.constructor = child; }
18925     ctor.prototype = parent.prototype;
18926     child.prototype = new ctor;
18927     child.__super__ = parent.prototype;
18928     return child;
18929   }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
18930   creditCardTemplate = require('templates/clients/modules/credit_card');
18931   exports.CreditCardView = (function() {
18932     __extends(CreditCardView, UberView);
18933     function CreditCardView() {
18934       CreditCardView.__super__.constructor.apply(this, arguments);
18935     }
18936     CreditCardView.prototype.id = 'creditcard_view';
18937     CreditCardView.prototype.className = 'module_container';
18938     CreditCardView.prototype.events = {
18939       'submit #credit_card_form': 'processNewCard',
18940       'click #new_card': 'processNewCard',
18941       'change #card_number': 'showCardType',
18942       'click .edit_card_show': 'showEditCard',
18943       'click .edit_card': 'editCard',
18944       'click .delete_card': 'deleteCard',
18945       'click .make_default': 'makeDefault',
18946       'change .use_case': 'saveUseCase'
18947     };
18948     CreditCardView.prototype.initialize = function() {
18949       return app.collections.paymentprofiles.bind("refresh", __bind(function() {
18950         return this.RefreshUserInfo(__bind(function() {
18951           this.render("all");
18952           return this.HideSpinner();
18953         }, this));
18954       }, this));
18955     };
18956     CreditCardView.prototype.render = function(cards) {
18957       if (cards == null) {
18958         cards = "new";
18959       }
18960       if (cards === "all") {
18961         app.collections.paymentprofiles.reset(USER.payment_gateway.payment_profiles);
18962         cards = app.collections.paymentprofiles;
18963       }
18964       $(this.el).html(creditCardTemplate({
18965         cards: cards
18966       }));
18967       return this;
18968     };
18969     CreditCardView.prototype.processNewCard = function(e) {
18970       var $el, attrs, model, options;
18971       e.preventDefault();
18972       this.ClearGlobalStatus();
18973       $el = $("#credit_card_form");
18974       $el.find('.error_message').html("");
18975       attrs = {
18976         card_number: $el.find('#card_number').val(),
18977         card_code: $el.find('#card_code').val(),
18978         card_expiration_month: $el.find('#card_expiration_month').val(),
18979         card_expiration_year: $el.find('#card_expiration_year').val(),
18980         use_case: $el.find('#use_case').val(),
18981         "default": $el.find('#default_check').prop("checked")
18982       };
18983       options = {
18984         statusCode: {
18985           200: __bind(function(e) {
18986             this.HideSpinner();
18987             $('#cc_form_wrapper').hide();
18988             app.collections.paymentprofiles.trigger("refresh");
18989             $(this.el).remove();
18990             $("a#add_card").show();
18991             return $('section').html(app.views.clients.billing.render().el);
18992           }, this),
18993           406: __bind(function(e) {
18994             var error, errors, _i, _len, _ref, _results;
18995             this.HideSpinner();
18996             errors = JSON.parse(e.responseText);
18997             _ref = _.keys(errors);
18998             _results = [];
18999             for (_i = 0, _len = _ref.length; _i < _len; _i++) {
19000               error = _ref[_i];
19001               _results.push(error === "top_of_form" ? $("#top_of_form").html(errors[error]) : $("#credit_card_form").find("#" + error).parent().find(".error_message").html(errors[error]));
19002             }
19003             return _results;
19004           }, this),
19005           420: __bind(function(e) {
19006             this.HideSpinner();
19007             return $("#top_of_form").html(t("Unable to Verify Card"));
19008           }, this)
19009         }
19010       };
19011       this.ShowSpinner("submit");
19012       model = new app.models.paymentprofile;
19013       model.save(attrs, options);
19014       return app.collections.paymentprofiles.add(model);
19015     };
19016     CreditCardView.prototype.showCardType = function(e) {
19017       var $el, reAmerica, reDiscover, reMaster, reVisa, validCard;
19018       reVisa = /^4\d{3}-?\d{4}-?\d{4}-?\d{4}$/;
19019       reMaster = /^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/;
19020       reAmerica = /^6011-?\d{4}-?\d{4}-?\d{4}$/;
19021       reDiscover = /^3[4,7]\d{13}$/;
19022       $el = $("#card_logos");
19023       validCard = false;
19024       if (e.currentTarget.value.match(reVisa)) {
19025         validCard = true;
19026       } else if (e.currentTarget.value.match(reMaster)) {
19027         $el.css('background-position', "-60px");
19028         validCard = true;
19029       } else if (e.currentTarget.value.match(reAmerica)) {
19030         $el.css('background-position', "-120px");
19031         validCard = true;
19032       } else if (e.currentTarget.value.match(reDiscover)) {
19033         $el.css('background-position', "-180px");
19034         validCard = true;
19035       }
19036       if (validCard) {
19037         $el.css('width', "60px");
19038         return $el.css('margin-left', "180px");
19039       } else {
19040         $el.css('width', "250px");
19041         return $el.css('margin-left', "80px");
19042       }
19043     };
19044     CreditCardView.prototype.showEditCard = function(e) {
19045       var $el, id;
19046       e.preventDefault();
19047       $el = $(e.currentTarget);
19048       if ($el.html() === t("Edit")) {
19049         id = $el.html(t("Cancel")).parents("tr").attr("id").substring(1);
19050         return $("#e" + id).show();
19051       } else {
19052         id = $el.html(t("Edit")).parents("tr").attr("id").substring(1);
19053         return $("#e" + id).hide();
19054       }
19055     };
19056     CreditCardView.prototype.editCard = function(e) {
19057       var $el, attrs, id, options;
19058       e.preventDefault();
19059       this.ClearGlobalStatus();
19060       $el = $(e.currentTarget).parents("td");
19061       id = $el.parents("tr").attr("id").substring(1);
19062       $el.attr('disabled', 'disabled');
19063       this.ShowSpinner('submit');
19064       attrs = {
19065         card_expiration_month: $el.find('#card_expiration_month').val(),
19066         card_expiration_year: $el.find('#card_expiration_year').val(),
19067         card_code: $el.find('#card_code').val()
19068       };
19069       options = {
19070         success: __bind(function(response) {
19071           this.HideSpinner();
19072           this.ShowSuccess(t("Credit Card Update Succeeded"));
19073           $("#e" + id).hide();
19074           $("#d" + id).find(".edit_card_show").html(t("Edit"));
19075           return app.collections.paymentprofiles.trigger("refresh");
19076         }, this),
19077         error: __bind(function(e) {
19078           this.HideSpinner();
19079           this.ShowError(t("Credit Card Update Failed"));
19080           return $el.removeAttr('disabled');
19081         }, this)
19082       };
19083       app.collections.paymentprofiles.models[id].set(attrs);
19084       return app.collections.paymentprofiles.models[id].save({}, options);
19085     };
19086     CreditCardView.prototype.deleteCard = function(e) {
19087       var $el, id, options;
19088       e.preventDefault();
19089       $el = $(e.currentTarget).parents("td");
19090       id = $el.parents("tr").attr("id").substring(1);
19091       this.ClearGlobalStatus();
19092       this.ShowSpinner('submit');
19093       options = {
19094         success: __bind(function(response) {
19095           this.ShowSuccess(t("Credit Card Delete Succeeded"));
19096           $("form").hide();
19097           app.collections.paymentprofiles.trigger("refresh");
19098           return $('section').html(app.views.clients.billing.render().el);
19099         }, this),
19100         error: __bind(function(xhr, e) {
19101           this.HideSpinner();
19102           return this.ShowError(t("Credit Card Delete Failed"));
19103         }, this)
19104       };
19105       return app.collections.paymentprofiles.models[id].destroy(options);
19106     };
19107     CreditCardView.prototype.saveUseCase = function(e) {
19108       var $el, attrs, id, options, use_case;
19109       this.ClearGlobalStatus();
19110       $el = $(e.currentTarget);
19111       use_case = $el.val();
19112       id = $el.parents("tr").attr("id").substring(1);
19113       attrs = {
19114         use_case: use_case
19115       };
19116       options = {
19117         success: __bind(function(response) {
19118           return this.ShowSuccess(t("Credit Card Update Category Succeeded"));
19119         }, this),
19120         error: __bind(function(e) {
19121           return this.ShowError(t("Credit Card Update Category Failed"));
19122         }, this)
19123       };
19124       app.collections.paymentprofiles.models[id].set(attrs);
19125       return app.collections.paymentprofiles.models[id].save({}, options);
19126     };
19127     CreditCardView.prototype.makeDefault = function(e) {
19128       var $el, attrs, id, options;
19129       e.preventDefault();
19130       this.ClearGlobalStatus();
19131       $el = $(e.currentTarget).parents("td");
19132       id = $el.parents("tr").attr("id").substring(1);
19133       attrs = {
19134         "default": true
19135       };
19136       options = {
19137         success: __bind(function(response) {
19138           this.ShowSuccess(t("Credit Card Update Default Succeeded"));
19139           return app.collections.paymentprofiles.trigger("refresh");
19140         }, this),
19141         error: __bind(function(e) {
19142           return this.ShowError(t("Credit Card Update Default Failed"));
19143         }, this)
19144       };
19145       app.collections.paymentprofiles.models[id].set(attrs);
19146       return app.collections.paymentprofiles.models[id].save({}, options);
19147     };
19148     return CreditCardView;
19149   })();
19150 }).call(this);
19151 }, "views/clients/promotions": function(exports, require, module) {(function() {
19152   var clientsPromotionsTemplate;
19153   var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
19154     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
19155     function ctor() { this.constructor = child; }
19156     ctor.prototype = parent.prototype;
19157     child.prototype = new ctor;
19158     child.__super__ = parent.prototype;
19159     return child;
19160   };
19161   clientsPromotionsTemplate = require('templates/clients/promotions');
19162   exports.ClientsPromotionsView = (function() {
19163     __extends(ClientsPromotionsView, UberView);
19164     function ClientsPromotionsView() {
19165       this.render = __bind(this.render, this);
19166       ClientsPromotionsView.__super__.constructor.apply(this, arguments);
19167     }
19168     ClientsPromotionsView.prototype.id = 'promotions_view';
19169     ClientsPromotionsView.prototype.className = 'view_container';
19170     ClientsPromotionsView.prototype.events = {
19171       'submit form': 'submitPromo',
19172       'click button': 'submitPromo'
19173     };
19174     ClientsPromotionsView.prototype.initialize = function() {
19175       if (this.model) {
19176         return this.RefreshUserInfo(this.render);
19177       }
19178     };
19179     ClientsPromotionsView.prototype.render = function() {
19180       var renderTemplate;
19181       this.ReadUserInfo();
19182       renderTemplate = __bind(function() {
19183         $(this.el).html(clientsPromotionsTemplate({
19184           promos: window.USER.unexpired_client_promotions || []
19185         }));
19186         return this.HideSpinner();
19187       }, this);
19188       this.DownloadUserPromotions(renderTemplate);
19189       return this;
19190     };
19191     ClientsPromotionsView.prototype.submitPromo = function(e) {
19192       var attrs, model, options, refreshTable;
19193       e.preventDefault();
19194       this.ClearGlobalStatus();
19195       refreshTable = __bind(function() {
19196         $('section').html(this.render().el);
19197         return this.HideSpinner();
19198       }, this);
19199       attrs = {
19200         code: $('#code').val()
19201       };
19202       options = {
19203         success: __bind(function(response) {
19204           this.HideSpinner();
19205           if (response.get('first_name')) {
19206             return this.ShowSuccess("Your promotion has been applied in the form of an account credit. <a href='#!/billing'>Click here</a> to check your balance.");
19207           } else {
19208             this.ShowSuccess("Your promotion has successfully been applied");
19209             return this.RefreshUserInfo(this.render, true);
19210           }
19211         }, this),
19212         statusCode: {
19213           400: __bind(function(e) {
19214             this.ShowError(JSON.parse(e.responseText).error);
19215             return this.HideSpinner();
19216           }, this)
19217         }
19218       };
19219       this.ShowSpinner("submit");
19220       model = new app.models.promotions;
19221       return model.save(attrs, options);
19222     };
19223     return ClientsPromotionsView;
19224   })();
19225 }).call(this);
19226 }, "views/clients/request": function(exports, require, module) {(function() {
19227   var clientsRequestTemplate;
19228   var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
19229     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
19230     function ctor() { this.constructor = child; }
19231     ctor.prototype = parent.prototype;
19232     child.prototype = new ctor;
19233     child.__super__ = parent.prototype;
19234     return child;
19235   };
19236   clientsRequestTemplate = require('templates/clients/request');
19237   exports.ClientsRequestView = (function() {
19238     __extends(ClientsRequestView, UberView);
19239     function ClientsRequestView() {
19240       this.AjaxCall = __bind(this.AjaxCall, this);
19241       this.AskDispatch = __bind(this.AskDispatch, this);
19242       this.removeMarkers = __bind(this.removeMarkers, this);
19243       this.displaySearchLoc = __bind(this.displaySearchLoc, this);
19244       this.displayFavLoc = __bind(this.displayFavLoc, this);
19245       this.showFavLoc = __bind(this.showFavLoc, this);
19246       this.addToFavLoc = __bind(this.addToFavLoc, this);
19247       this.removeCabs = __bind(this.removeCabs, this);
19248       this.requestRide = __bind(this.requestRide, this);
19249       this.rateTrip = __bind(this.rateTrip, this);
19250       this.locationChange = __bind(this.locationChange, this);
19251       this.panToLocation = __bind(this.panToLocation, this);
19252       this.clickLocation = __bind(this.clickLocation, this);
19253       this.searchLocation = __bind(this.searchLocation, this);
19254       this.mouseoutLocation = __bind(this.mouseoutLocation, this);
19255       this.mouseoverLocation = __bind(this.mouseoverLocation, this);
19256       this.fetchTripDetails = __bind(this.fetchTripDetails, this);
19257       this.submitRating = __bind(this.submitRating, this);
19258       this.setStatus = __bind(this.setStatus, this);
19259       this.initialize = __bind(this.initialize, this);
19260       ClientsRequestView.__super__.constructor.apply(this, arguments);
19261     }
19262     ClientsRequestView.prototype.id = 'request_view';
19263     ClientsRequestView.prototype.className = 'view_container';
19264     ClientsRequestView.prototype.pollInterval = 2 * 1000;
19265     ClientsRequestView.prototype.events = {
19266       "submit #search_form": "searchAddress",
19267       "click .locations_link": "locationLinkHandle",
19268       "mouseover .location_row": "mouseoverLocation",
19269       "mouseout .location_row": "mouseoutLocation",
19270       "click .location_row": "clickLocation",
19271       "click #search_location": "searchLocation",
19272       "click #pickupHandle": "pickupHandle",
19273       "click .stars": "rateTrip",
19274       "submit #rating_form": "submitRating",
19275       "click #addToFavButton": "showFavLoc",
19276       "click #favLocNickname": "selectInputText",
19277       "submit #favLoc_form": "addToFavLoc"
19278     };
19279     ClientsRequestView.prototype.status = "";
19280     ClientsRequestView.prototype.pickupMarker = "https://uber-static.s3.amazonaws.com/pickup_marker.png";
19281     ClientsRequestView.prototype.cabMarker = "https://uber-static.s3.amazonaws.com/cab_marker.png";
19282     ClientsRequestView.prototype.initialize = function() {
19283       var displayCabs;
19284       displayCabs = __bind(function() {
19285         return this.AskDispatch("NearestCab");
19286       }, this);
19287       this.showCabs = _.throttle(displayCabs, this.pollInterval);
19288       return this.numSearchToDisplay = 1;
19289     };
19290     ClientsRequestView.prototype.setStatus = function(status) {
19291       var autocomplete;
19292       if (this.status === status) {
19293         return;
19294       }
19295       try {
19296         google.maps.event.trigger(this.map, 'resize');
19297       } catch (_e) {}
19298       switch (status) {
19299         case "init":
19300           this.AskDispatch("StatusClient");
19301           this.status = "init";
19302           return this.ShowSpinner("load");
19303         case "ready":
19304           this.HideSpinner();
19305           $(".panel").hide();
19306           $("#top_bar").fadeIn();
19307           $("#location_panel").fadeIn();
19308           $("#location_panel_control").fadeIn();
19309           $("#pickupHandle").attr("class", "button_green").fadeIn().find("span").html(t("Request Pickup"));
19310           this.pickup_icon.setDraggable(true);
19311           this.map.panTo(this.pickup_icon.getPosition());
19312           this.showCabs();
19313           try {
19314             this.pickup_icon.setMap(this.map);
19315             this.displayFavLoc();
19316             autocomplete = new google.maps.places.Autocomplete(document.getElementById('address'), {
19317               types: ['geocode']
19318             });
19319             autocomplete.bindTo('bounds', this.map);
19320           } catch (_e) {}
19321           return this.status = "ready";
19322         case "searching":
19323           this.HideSpinner();
19324           this.removeMarkers();
19325           $(".panel").hide();
19326           $("#top_bar").fadeOut();
19327           $("#status_message").html(t("Requesting Closest Driver"));
19328           $("#pickupHandle").attr("class", "button_red").fadeIn().find("span").html(t("Cancel Pickup"));
19329           this.pickup_icon.setDraggable(false);
19330           this.pickup_icon.setMap(this.map);
19331           return this.status = "searching";
19332         case "waiting":
19333           this.HideSpinner();
19334           this.removeMarkers();
19335           $(".panel").hide();
19336           $("#top_bar").fadeOut();
19337           $("#pickupHandle").attr("class", "button_red").fadeIn().find("span").html(t("Cancel Pickup"));
19338           $("#waiting_riding").fadeIn();
19339           this.pickup_icon.setDraggable(false);
19340           this.pickup_icon.setMap(this.map);
19341           return this.status = "waiting";
19342         case "arriving":
19343           this.HideSpinner();
19344           this.removeMarkers();
19345           $(".panel").hide();
19346           $("#top_bar").fadeOut();
19347           $("#pickupHandle").attr("class", "button_red").fadeIn().find("span").html(t("Cancel Pickup"));
19348           $("#waiting_riding").fadeIn();
19349           this.pickup_icon.setDraggable(false);
19350           this.pickup_icon.setMap(this.map);
19351           return this.status = "arriving";
19352         case "riding":
19353           this.HideSpinner();
19354           this.removeMarkers();
19355           $(".panel").hide();
19356           $("#top_bar").fadeOut();
19357           $("#pickupHandle").fadeIn().attr("class", "button_red").find("span").html(t("Cancel Pickup"));
19358           $("#waiting_riding").fadeIn();
19359           this.pickup_icon.setDraggable(false);
19360           this.status = "riding";
19361           return $("#status_message").html(t("En Route"));
19362         case "rate":
19363           this.HideSpinner();
19364           $(".panel").hide();
19365           $("#pickupHandle").fadeOut();
19366           $("#trip_completed_panel").fadeIn();
19367           $('#status_message').html(t("Rate Last Trip"));
19368           return this.status = "rate";
19369       }
19370     };
19371     ClientsRequestView.prototype.render = function() {
19372       this.ReadUserInfo();
19373       this.HideSpinner();
19374       this.ShowSpinner("load");
19375       $(this.el).html(clientsRequestTemplate());
19376       this.cabs = [];
19377       this.RequireMaps(__bind(function() {
19378         var center, myOptions, streetViewPano;
19379         center = new google.maps.LatLng(37.7749295, -122.4194155);
19380         this.markers = [];
19381         this.pickup_icon = new google.maps.Marker({
19382           position: center,
19383           draggable: true,
19384           clickable: true,
19385           icon: this.pickupMarker
19386         });
19387         this.geocoder = new google.maps.Geocoder();
19388         myOptions = {
19389           zoom: 12,
19390           center: center,
19391           mapTypeId: google.maps.MapTypeId.ROADMAP,
19392           rotateControl: false,
19393           rotateControl: false,
19394           panControl: false
19395         };
19396         this.map = new google.maps.Map($(this.el).find("#map_wrapper_right")[0], myOptions);
19397         if (this.status === "ready") {
19398           this.pickup_icon.setMap(this.map);
19399         }
19400         if (geo_position_js.init()) {
19401           geo_position_js.getCurrentPosition(__bind(function(data) {
19402             var location;
19403             location = new google.maps.LatLng(data.coords.latitude, data.coords.longitude);
19404             this.pickup_icon.setPosition(location);
19405             this.map.panTo(location);
19406             return this.map.setZoom(16);
19407           }, this));
19408         }
19409         this.setStatus("init");
19410         streetViewPano = this.map.getStreetView();
19411         google.maps.event.addListener(streetViewPano, 'visible_changed', __bind(function() {
19412           if (streetViewPano.getVisible()) {
19413             this.pickupMarker = "https://uber-static.s3.amazonaws.com/pickup_marker_large.png";
19414             this.cabMarker = "https://uber-static.s3.amazonaws.com/cab_marker_large.png";
19415           } else {
19416             this.pickupMarker = "https://uber-static.s3.amazonaws.com/pickup_marker.png";
19417             this.cabMarker = "https://uber-static.s3.amazonaws.com/cab_marker.png";
19418           }
19419           this.pickup_icon.setIcon(this.pickupMarker);
19420           return _.each(this.cabs, __bind(function(cab) {
19421             return cab.setIcon(this.cabMarker);
19422           }, this));
19423         }, this));
19424         if (this.status === "ready") {
19425           return this.displayFavLoc();
19426         }
19427       }, this));
19428       return this;
19429     };
19430     ClientsRequestView.prototype.submitRating = function(e) {
19431       var $el, message, rating;
19432       e.preventDefault();
19433       $el = $(e.currentTarget);
19434       rating = 0;
19435       _(5).times(function(num) {
19436         if ($el.find(".stars#" + (num + 1)).attr("src") === "/web/img/star_active.png") {
19437           return rating = num + 1;
19438         }
19439       });
19440       if (rating === 0) {
19441         $("#status_message").html("").html(t("Rate Before Submitting"));
19442       } else {
19443         this.ShowSpinner("submit");
19444         this.AskDispatch("RatingDriver", {
19445           rating: rating
19446         });
19447       }
19448       message = $el.find("#comments").val().toString();
19449       if (message.length > 5) {
19450         return this.AskDispatch("Feedback", {
19451           message: message
19452         });
19453       }
19454     };
19455     ClientsRequestView.prototype.fetchTripDetails = function(id) {
19456       var trip;
19457       trip = new app.models.trip({
19458         id: id
19459       });
19460       return trip.fetch({
19461         data: {
19462           relationships: 'points,driver,city'
19463         },
19464         dataType: 'json',
19465         success: __bind(function() {
19466           var bounds, endPos, path, polyline, startPos;
19467           bounds = new google.maps.LatLngBounds();
19468           path = [];
19469           _.each(trip.get('points'), __bind(function(point) {
19470             path.push(new google.maps.LatLng(point.lat, point.lng));
19471             return bounds.extend(_.last(path));
19472           }, this));
19473           startPos = new google.maps.Marker({
19474             position: _.first(path),
19475             map: this.map,
19476             title: t("Trip started here"),
19477             icon: 'https://uber-static.s3.amazonaws.com/carstart.png'
19478           });
19479           endPos = new google.maps.Marker({
19480             position: _.last(path),
19481             map: this.map,
19482             title: t("Trip ended here"),
19483             icon: 'https://uber-static.s3.amazonaws.com/carstop.png'
19484           });
19485           polyline = new google.maps.Polyline({
19486             path: path,
19487             strokeColor: '#003F87',
19488             strokeOpacity: 1,
19489             strokeWeight: 5
19490           });
19491           polyline.setMap(this.map);
19492           this.map.fitBounds(bounds);
19493           $("#tripTime").html(app.helpers.parseDateTime(trip.get('pickup_local_time'), trip.get('city.timezone')));
19494           $("#tripDist").html(app.helpers.RoundNumber(trip.get('distance'), 2));
19495           $("#tripDur").html(app.helpers.FormatSeconds(trip.get('duration')));
19496           return $("#tripFare").html(app.helpers.FormatCurrency(trip.get('fare')));
19497         }, this)
19498       });
19499     };
19500     ClientsRequestView.prototype.searchAddress = function(e) {
19501       var $locationsDiv, address, alphabet, bounds, showResults;
19502       alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
19503       try {
19504         e.preventDefault();
19505       } catch (_e) {}
19506       $('.error_message').html("");
19507       $locationsDiv = $("<table></table>");
19508       address = $('#address').val();
19509       bounds = new google.maps.LatLngBounds();
19510       if (address.length < 5) {
19511         $('#status_message').html(t("Address too short")).fadeIn();
19512         return false;
19513       }
19514       showResults = __bind(function(address, index) {
19515         var first_cell, row, second_cell;
19516         if (index < this.numSearchToDisplay) {
19517           first_cell = "<td class='marker_logo'><img src='https://www.google.com/mapfiles/marker" + alphabet[index] + ".png' /></td>";
19518           second_cell = "<td class='location_nickname_wrapper'>" + address.formatted_address + "</td>";
19519           row = $("<tr></tr>").attr("id", "s" + index).attr("class", "location_row").html(first_cell + second_cell);
19520           $locationsDiv.append(row);
19521         }
19522         if (index === this.numSearchToDisplay) {
19523           $locationsDiv.append("<tr><td colspan=2>" + (t('or did you mean')) + " </td></tr>");
19524           return $locationsDiv.append("<tr><td colspan=2><a id='search_location' href=''>" + address.formatted_address + "</a></td></tr>");
19525         }
19526       }, this);
19527       return this.geocoder.geocode({
19528         address: address
19529       }, __bind(function(result, status) {
19530         if (status !== "OK") {
19531           $('.error_message').html(t("Search Address Failed")).fadeIn();
19532           return;
19533         }
19534         _.each(result, showResults);
19535         $("#search_results").html($locationsDiv);
19536         this.locationChange("search");
19537         this.searchResults = result;
19538         return this.displaySearchLoc();
19539       }, this));
19540     };
19541     ClientsRequestView.prototype.mouseoverLocation = function(e) {
19542       var $el, id, marker;
19543       $el = $(e.currentTarget);
19544       id = $el.attr("id").substring(1);
19545       marker = this.markers[id];
19546       return marker.setAnimation(google.maps.Animation.BOUNCE);
19547     };
19548     ClientsRequestView.prototype.mouseoutLocation = function(e) {
19549       var $el, id, marker;
19550       $el = $(e.currentTarget);
19551       id = $el.attr("id").substring(1);
19552       marker = this.markers[id];
19553       return marker.setAnimation(null);
19554     };
19555     ClientsRequestView.prototype.searchLocation = function(e) {
19556       e.preventDefault();
19557       $("#address").val($(e.currentTarget).html());
19558       return this.searchAddress();
19559     };
19560     ClientsRequestView.prototype.favoriteClick = function(e) {
19561       var index, location;
19562       e.preventDefault();
19563       $(".favorites").attr("href", "");
19564       index = $(e.currentTarget).removeAttr("href").attr("id");
19565       location = new google.maps.LatLng(USER.locations[index].latitude, USER.locations[index].longitude);
19566       return this.panToLocation(location);
19567     };
19568     ClientsRequestView.prototype.clickLocation = function(e) {
19569       var id;
19570       id = $(e.currentTarget).attr("id").substring(1);
19571       return this.panToLocation(this.markers[id].getPosition());
19572     };
19573     ClientsRequestView.prototype.panToLocation = function(location) {
19574       this.map.panTo(location);
19575       this.map.setZoom(16);
19576       return this.pickup_icon.setPosition(location);
19577     };
19578     ClientsRequestView.prototype.locationLinkHandle = function(e) {
19579       var panelName;
19580       e.preventDefault();
19581       panelName = $(e.currentTarget).attr("id");
19582       return this.locationChange(panelName);
19583     };
19584     ClientsRequestView.prototype.locationChange = function(type) {
19585       $(".locations_link").attr("href", "").css("font-weight", "normal");
19586       switch (type) {
19587         case "favorite":
19588           $(".search_results").attr("href", "");
19589           $(".locations_link#favorite").removeAttr("href").css("font-weight", "bold");
19590           $("#search_results").hide();
19591           $("#favorite_results").fadeIn();
19592           return this.displayFavLoc();
19593         case "search":
19594           $(".favorites").attr("href", "");
19595           $(".locations_link#search").removeAttr("href").css("font-weight", "bold");
19596           $("#favorite_results").hide();
19597           $("#search_results").fadeIn();
19598           return this.displaySearchLoc();
19599       }
19600     };
19601     ClientsRequestView.prototype.rateTrip = function(e) {
19602       var rating;
19603       rating = $(e.currentTarget).attr("id");
19604       $(".stars").attr("src", "/web/img/star_inactive.png");
19605       return _(rating).times(function(index) {
19606         return $(".stars#" + (index + 1)).attr("src", "/web/img/star_active.png");
19607       });
19608     };
19609     ClientsRequestView.prototype.pickupHandle = function(e) {
19610       var $el, callback, message;
19611       e.preventDefault();
19612       $el = $(e.currentTarget).find("span");
19613       switch ($el.html()) {
19614         case t("Request Pickup"):
19615           _.delay(this.requestRide, 3000);
19616           $("#status_message").html(t("Sending pickup request..."));
19617           $el.html(t("Cancel Pickup")).parent().attr("class", "button_red");
19618           this.pickup_icon.setDraggable(false);
19619           this.map.panTo(this.pickup_icon.getPosition());
19620           return this.map.setZoom(18);
19621         case t("Cancel Pickup"):
19622           if (this.status === "ready") {
19623             $el.html(t("Request Pickup")).parent().attr("class", "button_green");
19624             return this.pickup_icon.setDraggable(true);
19625           } else {
19626             callback = __bind(function(v, m, f) {
19627               if (v) {
19628                 this.AskDispatch("PickupCanceledClient");
19629                 return this.setStatus("ready");
19630               }
19631             }, this);
19632             message = t("Cancel Request Prompt");
19633             if (this.status === "arriving") {
19634               message = 'Cancel Request Arrived Prompt';
19635             }
19636             return $.prompt(message, {
19637               buttons: {
19638                 Ok: true,
19639                 Cancel: false
19640               },
19641               callback: callback
19642             });
19643           }
19644       }
19645     };
19646     ClientsRequestView.prototype.requestRide = function() {
19647       if ($("#pickupHandle").find("span").html() === t("Cancel Pickup")) {
19648         this.AskDispatch("Pickup");
19649         return this.setStatus("searching");
19650       }
19651     };
19652     ClientsRequestView.prototype.removeCabs = function() {
19653       _.each(this.cabs, __bind(function(point) {
19654         return point.setMap(null);
19655       }, this));
19656       return this.cabs = [];
19657     };
19658     ClientsRequestView.prototype.addToFavLoc = function(e) {
19659       var $el, lat, lng, nickname;
19660       e.preventDefault();
19661       $el = $(e.currentTarget);
19662       $el.find(".error_message").html("");
19663       nickname = $el.find("#favLocNickname").val().toString();
19664       lat = $el.find("#pickupLat").val().toString();
19665       lng = $el.find("#pickupLng").val().toString();
19666       if (nickname.length < 3) {
19667         $el.find(".error_message").html(t("Favorite Location Nickname Length Error"));
19668         return;
19669       }
19670       this.ShowSpinner("submit");
19671       return $.ajax({
19672         type: 'POST',
19673         url: API + "/locations",
19674         dataType: 'json',
19675         data: {
19676           token: USER.token,
19677           nickname: nickname,
19678           latitude: lat,
19679           longitude: lng
19680         },
19681         success: __bind(function(data, textStatus, jqXHR) {
19682           return $el.html(t("Favorite Location Save Succeeded"));
19683         }, this),
19684         error: __bind(function(jqXHR, textStatus, errorThrown) {
19685           return $el.find(".error_message").html(t("Favorite Location Save Failed"));
19686         }, this),
19687         complete: __bind(function(data) {
19688           return this.HideSpinner();
19689         }, this)
19690       });
19691     };
19692     ClientsRequestView.prototype.showFavLoc = function(e) {
19693       $(e.currentTarget).fadeOut();
19694       return $("#favLoc_form").fadeIn();
19695     };
19696     ClientsRequestView.prototype.selectInputText = function(e) {
19697       e.currentTarget.focus();
19698       return e.currentTarget.select();
19699     };
19700     ClientsRequestView.prototype.displayFavLoc = function() {
19701       var alphabet, bounds;
19702       alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
19703       this.removeMarkers();
19704       bounds = new google.maps.LatLngBounds();
19705       _.each(USER.locations, __bind(function(location, index) {
19706         var marker;
19707         marker = new google.maps.Marker({
19708           position: new google.maps.LatLng(location.latitude, location.longitude),
19709           map: this.map,
19710           title: t("Favorite Location Title", {
19711             id: alphabet != null ? alphabet[index] : void 0
19712           }),
19713           icon: "https://www.google.com/mapfiles/marker" + alphabet[index] + ".png"
19714         });
19715         this.markers.push(marker);
19716         bounds.extend(marker.getPosition());
19717         return google.maps.event.addListener(marker, 'click', __bind(function() {
19718           return this.pickup_icon.setPosition(marker.getPosition());
19719         }, this));
19720       }, this));
19721       this.pickup_icon.setPosition(_.first(this.markers).getPosition());
19722       return this.map.fitBounds(bounds);
19723     };
19724     ClientsRequestView.prototype.displaySearchLoc = function() {
19725       var alphabet;
19726       alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
19727       this.removeMarkers();
19728       return _.each(this.searchResults, __bind(function(result, index) {
19729         var marker;
19730         if (index < this.numSearchToDisplay) {
19731           marker = new google.maps.Marker({
19732             position: result.geometry.location,
19733             map: this.map,
19734             title: t("Search Location Title", {
19735               id: alphabet != null ? alphabet[index] : void 0
19736             }),
19737             icon: "https://www.google.com/mapfiles/marker" + alphabet[index] + ".png"
19738           });
19739           this.markers.push(marker);
19740           return this.panToLocation(result.geometry.location);
19741         }
19742       }, this));
19743     };
19744     ClientsRequestView.prototype.removeMarkers = function() {
19745       _.each(this.markers, __bind(function(marker) {
19746         return marker.setMap(null);
19747       }, this));
19748       return this.markers = [];
19749     };
19750     ClientsRequestView.prototype.AskDispatch = function(ask, options) {
19751       var attrs, lowestETA, processData, showCab;
19752       if (ask == null) {
19753         ask = "";
19754       }
19755       if (options == null) {
19756         options = {};
19757       }
19758       switch (ask) {
19759         case "NearestCab":
19760           attrs = {
19761             latitude: this.pickup_icon.getPosition().lat(),
19762             longitude: this.pickup_icon.getPosition().lng()
19763           };
19764           lowestETA = 99999;
19765           showCab = __bind(function(cab) {
19766             var point;
19767             point = new google.maps.Marker({
19768               position: new google.maps.LatLng(cab.latitude, cab.longitude),
19769               map: this.map,
19770               icon: this.cabMarker,
19771               title: t("ETA Message", {
19772                 minutes: app.helpers.FormatSeconds(cab != null ? cab.eta : void 0, true)
19773               })
19774             });
19775             if (cab.eta < lowestETA) {
19776               lowestETA = cab.eta;
19777             }
19778             return this.cabs.push(point);
19779           }, this);
19780           processData = __bind(function(data, textStatus, jqXHR) {
19781             if (this.status === "ready") {
19782               this.removeCabs();
19783               if (data.sorry) {
19784                 $("#status_message").html(data.sorry).fadeIn();
19785               } else {
19786                 _.each(data.driverLocations, showCab);
19787                 $("#status_message").html(t("Nearest Cab Message", {
19788                   minutes: app.helpers.FormatSeconds(lowestETA, true)
19789                 })).fadeIn();
19790               }
19791               if (Backbone.history.fragment === "!/request") {
19792                 return _.delay(this.showCabs, this.pollInterval);
19793               }
19794             }
19795           }, this);
19796           return this.AjaxCall(ask, processData, attrs);
19797         case "StatusClient":
19798           processData = __bind(function(data, textStatus, jqXHR) {
19799             var bounds, cabLocation, locationSaved, point, userLocation;
19800             if (data.messageType === "OK") {
19801               switch (data.status) {
19802                 case "completed":
19803                   this.removeCabs();
19804                   this.setStatus("rate");
19805                   return this.fetchTripDetails(data.tripID);
19806                 case "open":
19807                   return this.setStatus("ready");
19808                 case "begintrip":
19809                   this.setStatus("riding");
19810                   cabLocation = new google.maps.LatLng(data.latitude, data.longitude);
19811                   this.removeCabs();
19812                   this.pickup_icon.setMap(null);
19813                   point = new google.maps.Marker({
19814                     position: cabLocation,
19815                     map: this.map,
19816                     icon: this.cabMarker
19817                   });
19818                   this.cabs.push(point);
19819                   this.map.panTo(point.getPosition());
19820                   $("#rideName").html(data.driverName);
19821                   $("#ridePhone").html(data.driverMobile);
19822                   $("#ride_address_wrapper").hide();
19823                   if (Backbone.history.fragment === "!/request") {
19824                     return _.delay(this.AskDispatch, this.pollInterval, "StatusClient");
19825                   }
19826                   break;
19827                 case "pending":
19828                   this.setStatus("searching");
19829                   if (Backbone.history.fragment === "!/request") {
19830                     return _.delay(this.AskDispatch, this.pollInterval, "StatusClient");
19831                   }
19832                   break;
19833                 case "accepted":
19834                 case "arrived":
19835                   if (data.status === "accepted") {
19836                     this.setStatus("waiting");
19837                     $("#status_message").html(t("Arrival ETA Message", {
19838                       minutes: app.helpers.FormatSeconds(data.eta, true)
19839                     }));
19840                   } else {
19841                     this.setStatus("arriving");
19842                     $("#status_message").html(t("Arriving Now Message"));
19843                   }
19844                   userLocation = new google.maps.LatLng(data.pickupLocation.latitude, data.pickupLocation.longitude);
19845                   cabLocation = new google.maps.LatLng(data.latitude, data.longitude);
19846                   this.pickup_icon.setPosition(userLocation);
19847                   this.removeCabs();
19848                   $("#rideName").html(data.driverName);
19849                   $("#ridePhone").html(data.driverMobile);
19850                   if ($("#rideAddress").html() === "") {
19851                     locationSaved = false;
19852                     _.each(USER.locations, __bind(function(location) {
19853                       if (parseFloat(location.latitude) === parseFloat(data.pickupLocation.latitude) && parseFloat(location.longitude) === parseFloat(data.pickupLocation.longitude)) {
19854                         return locationSaved = true;
19855                       }
19856                     }, this));
19857                     if (locationSaved) {
19858                       $("#addToFavButton").hide();
19859                     }
19860                     $("#pickupLat").val(data.pickupLocation.latitude);
19861                     $("#pickupLng").val(data.pickupLocation.longitude);
19862                     this.geocoder.geocode({
19863                       location: userLocation
19864                     }, __bind(function(result, status) {
19865                       $("#rideAddress").html(result[0].formatted_address);
19866                       return $("#favLocNickname").val("" + result[0].address_components[0].short_name + " " + result[0].address_components[1].short_name);
19867                     }, this));
19868                   }
19869                   point = new google.maps.Marker({
19870                     position: cabLocation,
19871                     map: this.map,
19872                     icon: this.cabMarker
19873                   });
19874                   this.cabs.push(point);
19875                   bounds = bounds = new google.maps.LatLngBounds();
19876                   bounds.extend(cabLocation);
19877                   bounds.extend(userLocation);
19878                   this.map.fitBounds(bounds);
19879                   if (Backbone.history.fragment === "!/request") {
19880                     return _.delay(this.AskDispatch, this.pollInterval, "StatusClient");
19881                   }
19882               }
19883             }
19884           }, this);
19885           return this.AjaxCall(ask, processData);
19886         case "Pickup":
19887           attrs = {
19888             latitude: this.pickup_icon.getPosition().lat(),
19889             longitude: this.pickup_icon.getPosition().lng()
19890           };
19891           processData = __bind(function(data, textStatus, jqXHR) {
19892             if (data.messageType === "Error") {
19893               return $("#status_message").html(data.description);
19894             } else {
19895               return this.AskDispatch("StatusClient");
19896             }
19897           }, this);
19898           return this.AjaxCall(ask, processData, attrs);
19899         case "PickupCanceledClient":
19900           processData = __bind(function(data, textStatus, jqXHR) {
19901             if (data.messageType === "OK") {
19902               return this.setStatus("ready");
19903             } else {
19904               return $("#status_message").html(data.description);
19905             }
19906           }, this);
19907           return this.AjaxCall(ask, processData, attrs);
19908         case "RatingDriver":
19909           attrs = {
19910             rating: options.rating
19911           };
19912           processData = __bind(function(data, textStatus, jqXHR) {
19913             if (data.messageType === "OK") {
19914               this.setStatus("init");
19915             } else {
19916               $("status_message").html(t("Rating Driver Failed"));
19917             }
19918             return this.HideSpinner();
19919           }, this);
19920           return this.AjaxCall(ask, processData, attrs);
19921         case "Feedback":
19922           attrs = {
19923             message: options.message
19924           };
19925           processData = __bind(function(data, textStatus, jqXHR) {
19926             if (data.messageType === "OK") {
19927               return alert("rated");
19928             }
19929           }, this);
19930           return this.AjaxCall(ask, processData, attrs);
19931       }
19932     };
19933     ClientsRequestView.prototype.AjaxCall = function(type, successCallback, attrs) {
19934       if (attrs == null) {
19935         attrs = {};
19936       }
19937       _.extend(attrs, {
19938         token: USER.token,
19939         messageType: type,
19940         app: "client",
19941         version: "1.0.60",
19942         device: "web"
19943       });
19944       return $.ajax({
19945         type: 'POST',
19946         url: DISPATCH + "/",
19947         processData: false,
19948         data: JSON.stringify(attrs),
19949         success: successCallback,
19950         dataType: 'json',
19951         error: __bind(function(jqXHR, textStatus, errorThrown) {
19952           $("#status_message").html(errorThrown);
19953           return this.HideSpinner();
19954         }, this)
19955       });
19956     };
19957     return ClientsRequestView;
19958   })();
19959 }).call(this);
19960 }, "views/clients/settings": function(exports, require, module) {(function() {
19961   var clientsSettingsTemplate;
19962   var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
19963     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
19964     function ctor() { this.constructor = child; }
19965     ctor.prototype = parent.prototype;
19966     child.prototype = new ctor;
19967     child.__super__ = parent.prototype;
19968     return child;
19969   };
19970   clientsSettingsTemplate = require('templates/clients/settings');
19971   exports.ClientsSettingsView = (function() {
19972     __extends(ClientsSettingsView, UberView);
19973     function ClientsSettingsView() {
19974       this.render = __bind(this.render, this);
19975       this.initialize = __bind(this.initialize, this);
19976       ClientsSettingsView.__super__.constructor.apply(this, arguments);
19977     }
19978     ClientsSettingsView.prototype.id = 'settings_view';
19979     ClientsSettingsView.prototype.className = 'view_container';
19980     ClientsSettingsView.prototype.events = {
19981       'submit #profile_pic_form': 'processPicUpload',
19982       'click #submit_pic': 'processPicUpload',
19983       'click a.setting_change': "changeTab",
19984       'submit #edit_info_form': "submitInfo",
19985       'click #change_password': 'changePass'
19986     };
19987     ClientsSettingsView.prototype.divs = {
19988       'info_div': "Information",
19989       'pic_div': "Picture"
19990     };
19991     ClientsSettingsView.prototype.pageTitle = t("Settings") + " | " + t("Uber");
19992     ClientsSettingsView.prototype.tabTitle = {
19993       'info_div': t("Information"),
19994       'pic_div': t("Picture")
19995     };
19996     ClientsSettingsView.prototype.initialize = function() {
19997       return this.mixin(require('web-lib/mixins/i18n_phone_form').i18nPhoneForm);
19998     };
19999     ClientsSettingsView.prototype.render = function(type) {
20000       if (type == null) {
20001         type = "info";
20002       }
20003       this.RefreshUserInfo(__bind(function() {
20004         var $el, alphabet;
20005         this.delegateEvents();
20006         this.HideSpinner();
20007         alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
20008         $el = $(this.el);
20009         $(this.el).html(clientsSettingsTemplate({
20010           type: type
20011         }));
20012         $el.find("#" + type + "_div").show();
20013         $el.find("a[href='" + type + "_div']").parent().addClass("active");
20014         return document.title = "" + this.tabTitle[type + '_div'] + " " + this.pageTitle;
20015       }, this));
20016       this.delegateEvents();
20017       return this;
20018     };
20019     ClientsSettingsView.prototype.changeTab = function(e) {
20020       var $eTarget, $el, div, link, pageDiv, _i, _j, _len, _len2, _ref, _ref2;
20021       e.preventDefault();
20022       $eTarget = $(e.currentTarget);
20023       this.ClearGlobalStatus();
20024       $el = $(this.el);
20025       _ref = $el.find(".setting_change");
20026       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
20027         link = _ref[_i];
20028         $(link).parent().removeClass("active");
20029       }
20030       $eTarget.parent().addClass("active");
20031       _ref2 = _.keys(this.divs);
20032       for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
20033         div = _ref2[_j];
20034         $el.find("#" + div).hide();
20035       }
20036       pageDiv = $eTarget.attr('href');
20037       $el.find("#" + pageDiv).show();
20038       Backbone.history.navigate("!/settings/" + (this.divs[pageDiv].toLowerCase().replace(" ", "-")), false);
20039       document.title = "" + this.tabTitle[pageDiv] + " " + this.pageTitle;
20040       if (pageDiv === "loc_div") {
20041         try {
20042           google.maps.event.trigger(this.map, 'resize');
20043           return this.map.fitBounds(this.bounds);
20044         } catch (_e) {}
20045       }
20046     };
20047     ClientsSettingsView.prototype.submitInfo = function(e) {
20048       var $e, attrs, client, options;
20049       $('#global_status').find('.success_message').text('');
20050       $('#global_status').find('.error_message').text('');
20051       $('.error_message').text('');
20052       e.preventDefault();
20053       $e = $(e.currentTarget);
20054       attrs = $e.serializeToJson();
20055       attrs['mobile_country_id'] = this.$('#mobile_country_id').val();
20056       if (attrs['password'] === '') {
20057         delete attrs['password'];
20058       }
20059       options = {
20060         success: __bind(function(response) {
20061           this.ShowSuccess(t("Information Update Succeeded"));
20062           return this.RefreshUserInfo();
20063         }, this),
20064         error: __bind(function(model, data) {
20065           var errors;
20066           if (data.status === 406) {
20067             errors = JSON.parse(data.responseText);
20068             return _.each(_.keys(errors), function(field) {
20069               return $("#" + field).parent().find('span.error_message').text(errors[field]);
20070             });
20071           } else {
20072             return this.ShowError(t("Information Update Failed"));
20073           }
20074         }, this),
20075         type: "PUT"
20076       };
20077       client = new app.models.client({
20078         id: USER.id
20079       });
20080       return client.save(attrs, options);
20081     };
20082     ClientsSettingsView.prototype.changePass = function(e) {
20083       e.preventDefault();
20084       $(e.currentTarget).hide();
20085       return $("#password").show();
20086     };
20087     ClientsSettingsView.prototype.processPicUpload = function(e) {
20088       e.preventDefault();
20089       this.ShowSpinner("submit");
20090       return $.ajaxFileUpload({
20091         url: API + '/user_pictures',
20092         secureuri: false,
20093         fileElementId: 'picture',
20094         data: {
20095           token: USER.token
20096         },
20097         dataType: 'json',
20098         complete: __bind(function(data, status) {
20099           this.HideSpinner();
20100           if (status === 'success') {
20101             this.ShowSuccess(t("Picture Update Succeeded"));
20102             return this.RefreshUserInfo(__bind(function() {
20103               return $("#settingsProfPic").attr("src", USER.picture_url + ("?" + (Math.floor(Math.random() * 1000))));
20104             }, this));
20105           } else {
20106             if (data.error) {
20107               return this.ShowError(data.error);
20108             } else {
20109               return this.ShowError("Picture Update Failed");
20110             }
20111           }
20112         }, this)
20113       });
20114     };
20115     return ClientsSettingsView;
20116   })();
20117 }).call(this);
20118 }, "views/clients/sign_up": function(exports, require, module) {(function() {
20119   var clientsSignUpTemplate;
20120   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
20121     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
20122     function ctor() { this.constructor = child; }
20123     ctor.prototype = parent.prototype;
20124     child.prototype = new ctor;
20125     child.__super__ = parent.prototype;
20126     return child;
20127   }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
20128   clientsSignUpTemplate = require('templates/clients/sign_up');
20129   exports.ClientsSignUpView = (function() {
20130     __extends(ClientsSignUpView, UberView);
20131     function ClientsSignUpView() {
20132       ClientsSignUpView.__super__.constructor.apply(this, arguments);
20133     }
20134     ClientsSignUpView.prototype.id = 'signup_view';
20135     ClientsSignUpView.prototype.className = 'view_container';
20136     ClientsSignUpView.prototype.initialize = function() {
20137       this.mixin(require('web-lib/mixins/i18n_phone_form').i18nPhoneForm);
20138       return $('#location_country').live('change', function() {
20139         if (!$('#mobile').val()) {
20140           return $('#mobile_country').find("option[value=" + ($(this).val()) + "]").attr('selected', 'selected').end().trigger('change');
20141         }
20142       });
20143     };
20144     ClientsSignUpView.prototype.events = {
20145       'submit form': 'signup',
20146       'click button': 'signup',
20147       'change #card_number': 'showCardType',
20148       'change #location_country': 'countryChange'
20149     };
20150     ClientsSignUpView.prototype.render = function(invite) {
20151       this.HideSpinner();
20152       $(this.el).html(clientsSignUpTemplate({
20153         invite: invite
20154       }));
20155       return this;
20156     };
20157     ClientsSignUpView.prototype.signup = function(e) {
20158       var $el, attrs, client, error_messages, options;
20159       e.preventDefault();
20160       $el = $("form");
20161       $el.find('#terms_error').hide();
20162       if (!$el.find('#signup_terms input[type=checkbox]').attr('checked')) {
20163         $('#spinner.submit').hide();
20164         $el.find('#terms_error').show();
20165         return;
20166       }
20167       error_messages = $el.find('.error_message').html("");
20168       attrs = {
20169         first_name: $el.find('#first_name').val(),
20170         last_name: $el.find('#last_name').val(),
20171         email: $el.find('#email').val(),
20172         password: $el.find('#password').val(),
20173         location_country: $el.find('#location_country option:selected').attr('data-iso2'),
20174         location: $el.find('#location').val(),
20175         language: $el.find('#language').val(),
20176         mobile_country: $el.find('#mobile_country option:selected').attr('data-iso2'),
20177         mobile: $el.find('#mobile').val(),
20178         card_number: $el.find('#card_number').val(),
20179         card_expiration_month: $el.find('#card_expiration_month').val(),
20180         card_expiration_year: $el.find('#card_expiration_year').val(),
20181         card_code: $el.find('#card_code').val(),
20182         use_case: $el.find('#use_case').val(),
20183         promotion_code: $el.find('#promotion_code').val()
20184       };
20185       options = {
20186         statusCode: {
20187           200: function(response) {
20188             $.cookie('token', response.token);
20189             amplify.store('USERjson', response);
20190             app.refreshMenu();
20191             return app.routers.clients.navigate('!/dashboard', true);
20192           },
20193           406: function(e) {
20194             var error, errors, _i, _len, _ref, _results;
20195             errors = JSON.parse(e.responseText);
20196             _ref = _.keys(errors);
20197             _results = [];
20198             for (_i = 0, _len = _ref.length; _i < _len; _i++) {
20199               error = _ref[_i];
20200               _results.push($('#' + error).parent().find('span').html($('#' + error).parent().find('span').html() + " " + errors[error]));
20201             }
20202             return _results;
20203           }
20204         },
20205         complete: __bind(function(response) {
20206           return this.HideSpinner();
20207         }, this)
20208       };
20209       client = new app.models.client;
20210       $('.spinner#submit').show();
20211       return client.save(attrs, options);
20212     };
20213     ClientsSignUpView.prototype.countryChange = function(e) {
20214       var $e;
20215       $e = $(e.currentTarget);
20216       return $("#mobile_country").val($e.val()).trigger('change');
20217     };
20218     ClientsSignUpView.prototype.showCardType = function(e) {
20219       var $el, reAmerica, reDiscover, reMaster, reVisa, validCard;
20220       reVisa = /^4\d{3}-?\d{4}-?\d{4}-?\d{4}$/;
20221       reMaster = /^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/;
20222       reAmerica = /^6011-?\d{4}-?\d{4}-?\d{4}$/;
20223       reDiscover = /^3[4,7]\d{13}$/;
20224       $el = $("#card_logos_signup");
20225       validCard = false;
20226       if (e.currentTarget.value.match(reVisa)) {
20227         $el.find("#overlay_left").css('width', "0px");
20228         return $el.find("#overlay_right").css('width', "75%");
20229       } else if (e.currentTarget.value.match(reMaster)) {
20230         $el.find("#overlay_left").css('width', "25%");
20231         return $el.find("#overlay_right").css('width', "50%");
20232       } else if (e.currentTarget.value.match(reAmerica)) {
20233         $el.find("#overlay_left").css('width', "75%");
20234         $el.find("#overlay_right").css('width', "0px");
20235         return console.log("amex");
20236       } else if (e.currentTarget.value.match(reDiscover)) {
20237         $el.find("#overlay_left").css('width', "50%");
20238         return $el.find("#overlay_right").css('width', "25%");
20239       } else {
20240         $el.find("#overlay_left").css('width', "0px");
20241         return $el.find("#overlay_right").css('width', "0px");
20242       }
20243     };
20244     return ClientsSignUpView;
20245   })();
20246 }).call(this);
20247 }, "views/clients/trip_detail": function(exports, require, module) {(function() {
20248   var clientsTripDetailTemplate;
20249   var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
20250     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
20251     function ctor() { this.constructor = child; }
20252     ctor.prototype = parent.prototype;
20253     child.prototype = new ctor;
20254     child.__super__ = parent.prototype;
20255     return child;
20256   };
20257   clientsTripDetailTemplate = require('templates/clients/trip_detail');
20258   exports.TripDetailView = (function() {
20259     __extends(TripDetailView, UberView);
20260     function TripDetailView() {
20261       this.resendReceipt = __bind(this.resendReceipt, this);
20262       TripDetailView.__super__.constructor.apply(this, arguments);
20263     }
20264     TripDetailView.prototype.id = 'trip_detail_view';
20265     TripDetailView.prototype.className = 'view_container';
20266     TripDetailView.prototype.events = {
20267       'click a#fare_review': 'showFareReview',
20268       'click #fare_review_hide': 'hideFareReview',
20269       'submit #form_review_form': 'submitFareReview',
20270       'click #submit_fare_review': 'submitFareReview',
20271       'click .resendReceipt': 'resendReceipt'
20272     };
20273     TripDetailView.prototype.render = function(id) {
20274       if (id == null) {
20275         id = 'invalid';
20276       }
20277       this.ReadUserInfo();
20278       this.HideSpinner();
20279       this.model = new app.models.trip({
20280         id: id
20281       });
20282       this.model.fetch({
20283         data: {
20284           relationships: 'points,driver,city.country'
20285         },
20286         dataType: 'json',
20287         success: __bind(function() {
20288           var trip;
20289           trip = this.model;
20290           $(this.el).html(clientsTripDetailTemplate({
20291             trip: trip
20292           }));
20293           this.RequireMaps(__bind(function() {
20294             var bounds, endPos, map, myOptions, path, polyline, startPos;
20295             bounds = new google.maps.LatLngBounds();
20296             path = [];
20297             _.each(this.model.get('points'), __bind(function(point) {
20298               path.push(new google.maps.LatLng(point.lat, point.lng));
20299               return bounds.extend(_.last(path));
20300             }, this));
20301             myOptions = {
20302               zoom: 12,
20303               center: path[0],
20304               mapTypeId: google.maps.MapTypeId.ROADMAP,
20305               zoomControl: false,
20306               rotateControl: false,
20307               panControl: false,
20308               mapTypeControl: false,
20309               scrollwheel: false
20310             };
20311             map = new google.maps.Map(document.getElementById("trip_details_map"), myOptions);
20312             map.fitBounds(bounds);
20313             startPos = new google.maps.Marker({
20314               position: _.first(path),
20315               map: map,
20316               title: t("Trip started here"),
20317               icon: 'https://uber-static.s3.amazonaws.com/marker_start.png'
20318             });
20319             endPos = new google.maps.Marker({
20320               position: _.last(path),
20321               map: map,
20322               title: t("Trip ended here"),
20323               icon: 'https://uber-static.s3.amazonaws.com/marker_end.png'
20324             });
20325             startPos.setMap(map);
20326             endPos.setMap(map);
20327             polyline = new google.maps.Polyline({
20328               path: path,
20329               strokeColor: '#003F87',
20330               strokeOpacity: 1,
20331               strokeWeight: 5
20332             });
20333             return polyline.setMap(map);
20334           }, this));
20335           return this.HideSpinner();
20336         }, this)
20337       });
20338       this.ShowSpinner('load');
20339       this.delegateEvents();
20340       return this;
20341     };
20342     TripDetailView.prototype.showFareReview = function(e) {
20343       e.preventDefault();
20344       $('#fare_review_box').slideDown();
20345       return $('#fare_review').hide();
20346     };
20347     TripDetailView.prototype.hideFareReview = function(e) {
20348       e.preventDefault();
20349       $('#fare_review_box').slideUp();
20350       return $('#fare_review').show();
20351     };
20352     TripDetailView.prototype.submitFareReview = function(e) {
20353       var attrs, errorMessage, id, options;
20354       e.preventDefault();
20355       errorMessage = $(".error_message");
20356       errorMessage.hide();
20357       id = $("#tripid").val();
20358       this.model = new app.models.trip({
20359         id: id
20360       });
20361       attrs = {
20362         note: $('#form_review_message').val(),
20363         note_type: 'client_fare_review'
20364       };
20365       options = {
20366         success: __bind(function(response) {
20367           $(".success_message").fadeIn();
20368           return $("#fare_review_form_wrapper").slideUp();
20369         }, this),
20370         error: __bind(function(error) {
20371           return errorMessage.fadeIn();
20372         }, this)
20373       };
20374       return this.model.save(attrs, options);
20375     };
20376     TripDetailView.prototype.resendReceipt = function(e) {
20377       var $e;
20378       e.preventDefault();
20379       $e = $(e.currentTarget);
20380       this.$(".resendReceiptSuccess").empty().show();
20381       this.$(".resentReceiptError").empty().show();
20382       e.preventDefault();
20383       $('#spinner').show();
20384       return $.ajax('/api/trips/func/resend_receipt', {
20385         data: {
20386           token: $.cookie('token'),
20387           trip_id: this.model.id
20388         },
20389         type: 'POST',
20390         complete: __bind(function(xhr) {
20391           var response;
20392           response = JSON.parse(xhr.responseText);
20393           $('#spinner').hide();
20394           switch (xhr.status) {
20395             case 200:
20396               this.$(".resendReceiptSuccess").html("Receipt has been emailed");
20397               return this.$(".resendReceiptSuccess").fadeOut(2000);
20398             default:
20399               this.$(".resendReceiptError").html("Receipt has failed to be emailed");
20400               return this.$(".resendReceiptError").fadeOut(2000);
20401           }
20402         }, this)
20403       });
20404     };
20405     return TripDetailView;
20406   })();
20407 }).call(this);
20408 }, "views/shared/menu": function(exports, require, module) {(function() {
20409   var menuTemplate;
20410   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
20411     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
20412     function ctor() { this.constructor = child; }
20413     ctor.prototype = parent.prototype;
20414     child.prototype = new ctor;
20415     child.__super__ = parent.prototype;
20416     return child;
20417   };
20418   menuTemplate = require('templates/shared/menu');
20419   exports.SharedMenuView = (function() {
20420     __extends(SharedMenuView, Backbone.View);
20421     function SharedMenuView() {
20422       SharedMenuView.__super__.constructor.apply(this, arguments);
20423     }
20424     SharedMenuView.prototype.id = 'menu_view';
20425     SharedMenuView.prototype.render = function() {
20426       var type;
20427       if ($.cookie('token') === null) {
20428         type = 'guest';
20429       } else {
20430         type = 'client';
20431       }
20432       $(this.el).html(menuTemplate({
20433         type: type
20434       }));
20435       return this;
20436     };
20437     return SharedMenuView;
20438   })();
20439 }).call(this);
20440 }, "web-lib/collections/countries": function(exports, require, module) {(function() {
20441   var UberCollection;
20442   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
20443     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
20444     function ctor() { this.constructor = child; }
20445     ctor.prototype = parent.prototype;
20446     child.prototype = new ctor;
20447     child.__super__ = parent.prototype;
20448     return child;
20449   };
20450   UberCollection = require('web-lib/uber_collection').UberCollection;
20451   exports.CountriesCollection = (function() {
20452     __extends(CountriesCollection, UberCollection);
20453     function CountriesCollection() {
20454       CountriesCollection.__super__.constructor.apply(this, arguments);
20455     }
20456     CountriesCollection.prototype.model = app.models.country;
20457     CountriesCollection.prototype.url = '/countries';
20458     return CountriesCollection;
20459   })();
20460 }).call(this);
20461 }, "web-lib/collections/vehicle_types": function(exports, require, module) {(function() {
20462   var UberCollection, vehicleType, _ref;
20463   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
20464     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
20465     function ctor() { this.constructor = child; }
20466     ctor.prototype = parent.prototype;
20467     child.prototype = new ctor;
20468     child.__super__ = parent.prototype;
20469     return child;
20470   };
20471   UberCollection = require('web-lib/uber_collection').UberCollection;
20472   vehicleType = (typeof app !== "undefined" && app !== null ? (_ref = app.models) != null ? _ref.vehicleType : void 0 : void 0) || require('models/vehicle_type').VehicleType;
20473   exports.VehicleTypesCollection = (function() {
20474     __extends(VehicleTypesCollection, UberCollection);
20475     function VehicleTypesCollection() {
20476       VehicleTypesCollection.__super__.constructor.apply(this, arguments);
20477     }
20478     VehicleTypesCollection.prototype.model = vehicleType;
20479     VehicleTypesCollection.prototype.url = '/vehicle_types';
20480     VehicleTypesCollection.prototype.defaultColumns = ['id', 'created_at', 'updated_at', 'deleted_at', 'created_by_user_id', 'updated_by_user_id', 'city_id', 'type', 'make', 'model', 'capacity', 'minimum_year', 'actions'];
20481     VehicleTypesCollection.prototype.tableColumns = function(cols) {
20482       var actions, c, capacity, city_id, columnValues, created_at, created_by_user_id, deleted_at, headerRow, id, make, minimum_year, model, type, updated_at, updated_by_user_id, _i, _len;
20483       id = {
20484         sTitle: 'Id'
20485       };
20486       created_at = {
20487         sTitle: 'Created At (UTC)',
20488         'sType': 'string'
20489       };
20490       updated_at = {
20491         sTitle: 'Updated At (UTC)',
20492         'sType': 'string'
20493       };
20494       deleted_at = {
20495         sTitle: 'Deleted At (UTC)',
20496         'sType': 'string'
20497       };
20498       created_by_user_id = {
20499         sTitle: 'Created By'
20500       };
20501       updated_by_user_id = {
20502         sTitle: 'Updated By'
20503       };
20504       city_id = {
20505         sTitle: 'City'
20506       };
20507       type = {
20508         sTitle: 'Type'
20509       };
20510       make = {
20511         sTitle: 'Make'
20512       };
20513       model = {
20514         sTitle: 'Model'
20515       };
20516       capacity = {
20517         sTitle: 'Capacity'
20518       };
20519       minimum_year = {
20520         sTitle: 'Min. Year'
20521       };
20522       actions = {
20523         sTitle: 'Actions'
20524       };
20525       columnValues = {
20526         id: id,
20527         created_at: created_at,
20528         updated_at: updated_at,
20529         deleted_at: deleted_at,
20530         created_by_user_id: created_by_user_id,
20531         updated_by_user_id: updated_by_user_id,
20532         city_id: city_id,
20533         type: type,
20534         make: make,
20535         model: model,
20536         capacity: capacity,
20537         minimum_year: minimum_year,
20538         actions: actions
20539       };
20540       headerRow = [];
20541       for (_i = 0, _len = cols.length; _i < _len; _i++) {
20542         c = cols[_i];
20543         if (columnValues[c]) {
20544           headerRow.push(columnValues[c]);
20545         }
20546       }
20547       return headerRow;
20548     };
20549     return VehicleTypesCollection;
20550   })();
20551 }).call(this);
20552 }, "web-lib/helpers": function(exports, require, module) {(function() {
20553   var __indexOf = Array.prototype.indexOf || function(item) {
20554     for (var i = 0, l = this.length; i < l; i++) {
20555       if (this[i] === item) return i;
20556     }
20557     return -1;
20558   }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
20559   exports.helpers = {
20560     pin: function(num, color) {
20561       if (color == null) {
20562         color = 'FF0000';
20563       }
20564       return "<img src=\"http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=" + num + "|" + color + "|000000\" width=\"14\" height=\"22\" />";
20565     },
20566     reverseGeocode: function(latitude, longitude) {
20567       if (latitude && longitude) {
20568         return "<span data-point=" + (JSON.stringify({
20569           latitude: latitude,
20570           longitude: longitude
20571         })) + ">" + latitude + ", " + longitude + "</span>";
20572       } else {
20573         return '';
20574       }
20575     },
20576     linkedName: function(model) {
20577       var first_name, id, last_name, role, url;
20578       role = model.role || model.get('role');
20579       id = model.id || model.get('id');
20580       first_name = model.first_name || model.get('first_name');
20581       last_name = model.last_name || model.get('last_name');
20582       url = "/" + role + "s/" + id;
20583       return "<a href=\"#" + url + "\">" + first_name + " " + last_name + "</a>";
20584     },
20585     linkedVehicle: function(vehicle, vehicleType) {
20586       return "<a href=\"/#/vehicles/" + vehicle.id + "\">      " + (vehicleType != null ? vehicleType.get('make') : void 0) + "      " + (vehicleType != null ? vehicleType.get('model') : void 0) + "      " + (vehicle.get('year')) + "    </a>";
20587     },
20588     linkedUserId: function(userType, userId) {
20589       return "<a href=\"#!/" + userType + "/" + userId + "\" data-user-type=\"" + userType + "\" data-user-id=\"" + userId + "\">" + userType + " " + userId + "</a>";
20590     },
20591     timeDelta: function(start, end) {
20592       var delta;
20593       if (typeof start === 'string') {
20594         start = this.parseDate(start);
20595       }
20596       if (typeof end === 'string') {
20597         end = this.parseDate(end);
20598       }
20599       if (end && start) {
20600         delta = end.getTime() - start.getTime();
20601         return this.formatSeconds(delta / 1000);
20602       } else {
20603         return '00:00';
20604       }
20605     },
20606     formatSeconds: function(s) {
20607       var minutes, seconds;
20608       s = Math.floor(s);
20609       minutes = Math.floor(s / 60);
20610       seconds = s - minutes * 60;
20611       return "" + (this.leadingZero(minutes)) + ":" + (this.leadingZero(seconds));
20612     },
20613     formatCurrency: function(strValue, reverseSign, currency) {
20614       var currency_locale, lc, mf;
20615       if (reverseSign == null) {
20616         reverseSign = false;
20617       }
20618       if (currency == null) {
20619         currency = null;
20620       }
20621       strValue = String(strValue);
20622       if (reverseSign) {
20623         strValue = ~strValue.indexOf('-') ? strValue.split('-').join('') : ['-', strValue].join('');
20624       }
20625       currency_locale = i18n.currencyToLocale[currency];
20626       try {
20627         if (!(currency_locale != null) || currency_locale === i18n.locale) {
20628           return i18n.jsworld.mf.format(strValue);
20629         } else {
20630           lc = new jsworld.Locale(POSIX_LC[currency_locale]);
20631           mf = new jsworld.MonetaryFormatter(lc);
20632           return mf.format(strValue);
20633         }
20634       } catch (error) {
20635         i18n.log(error);
20636         return strValue;
20637       }
20638     },
20639     formatTripFare: function(trip, type) {
20640       var _ref, _ref2;
20641       if (type == null) {
20642         type = "fare";
20643       }
20644       if (!trip.get('fare')) {
20645         return 'n/a';
20646       }
20647       if (((_ref = trip.get('fare_breakdown_local')) != null ? _ref.currency : void 0) != null) {
20648         return app.helpers.formatCurrency(trip.get("" + type + "_local"), false, (_ref2 = trip.get('fare_breakdown_local')) != null ? _ref2.currency : void 0);
20649       } else if (trip.get("" + type + "_string") != null) {
20650         return trip.get("" + type + "_string");
20651       } else if (trip.get("" + type + "_local") != null) {
20652         return trip.get("" + type + "_local");
20653       } else {
20654         return 'n/a';
20655       }
20656     },
20657     formatPhoneNumber: function(phoneNumber, countryCode) {
20658       if (countryCode == null) {
20659         countryCode = "+1";
20660       }
20661       if (phoneNumber != null) {
20662         phoneNumber = String(phoneNumber);
20663         switch (countryCode) {
20664           case '+1':
20665             return countryCode + ' ' + phoneNumber.substring(0, 3) + '-' + phoneNumber.substring(3, 6) + '-' + phoneNumber.substring(6, 10);
20666           case '+33':
20667             return countryCode + ' ' + phoneNumber.substring(0, 1) + ' ' + phoneNumber.substring(1, 3) + ' ' + phoneNumber.substring(3, 5) + ' ' + phoneNumber.substring(5, 7) + ' ' + phoneNumber.substring(7, 9);
20668           default:
20669             countryCode + phoneNumber;
20670         }
20671       }
20672       return "" + countryCode + " " + phoneNumber;
20673     },
20674     parseDate: function(d, cityTime, tz) {
20675       var city_filter, parsed, _ref;
20676       if (cityTime == null) {
20677         cityTime = true;
20678       }
20679       if (tz == null) {
20680         tz = null;
20681       }
20682       if (((_ref = !d.substr(-6, 1)) === '+' || _ref === '-') || d.length === 19) {
20683         d += '+00:00';
20684       }
20685       if (/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})/.test(d)) {
20686         parsed = d.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/);
20687         d = new Date();
20688         d.setUTCFullYear(parsed[1]);
20689         d.setUTCMonth(parsed[2] - 1);
20690         d.setUTCDate(parsed[3]);
20691         d.setUTCHours(parsed[4]);
20692         d.setUTCMinutes(parsed[5]);
20693         d.setUTCSeconds(parsed[6]);
20694       } else {
20695         d = Date.parse(d);
20696       }
20697       if (typeof d === 'number') {
20698         d = new Date(d);
20699       }
20700       d = new timezoneJS.Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), 'Etc/UTC');
20701       if (tz) {
20702         d.convertToTimezone(tz);
20703       } else if (cityTime) {
20704         city_filter = $.cookie('city_filter');
20705         if (city_filter) {
20706           tz = $("#city_filter option[value=" + city_filter + "]").attr('data-timezone');
20707           if (tz) {
20708             d.convertToTimezone(tz);
20709           }
20710         }
20711       }
20712       return d;
20713     },
20714     dateToTimezone: function(d) {
20715       var city_filter, tz;
20716       d = new timezoneJS.Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), 'Etc/UTC');
20717       city_filter = $.cookie('city_filter');
20718       if (city_filter) {
20719         tz = $("#city_filter option[value=" + city_filter + "]").attr('data-timezone');
20720         d.convertToTimezone(tz);
20721       }
20722       return d;
20723     },
20724     fixAMPM: function(d, formatted) {
20725       if (d.hours >= 12) {
20726         return formatted.replace(/\b[AP]M\b/, 'PM');
20727       } else {
20728         return formatted.replace(/\b[AP]M\b/, 'AM');
20729       }
20730     },
20731     formatDate: function(d, time, timezone) {
20732       var formatted;
20733       if (time == null) {
20734         time = true;
20735       }
20736       if (timezone == null) {
20737         timezone = null;
20738       }
20739       d = this.parseDate(d, true, timezone);
20740       formatted = time ? ("" + (i18n.jsworld.dtf.formatDate(d)) + " ") + this.formatTime(d, d.getTimezoneInfo()) : i18n.jsworld.dtf.formatDate(d);
20741       return this.fixAMPM(d, formatted);
20742     },
20743     formatDateLong: function(d, time, timezone) {
20744       if (time == null) {
20745         time = true;
20746       }
20747       if (timezone == null) {
20748         timezone = null;
20749       }
20750       d = this.parseDate(d, true, timezone);
20751       timezone = d.getTimezoneInfo().tzAbbr;
20752       if (time) {
20753         return (i18n.jsworld.dtf.formatDateTime(d)) + (" " + timezone);
20754       } else {
20755         return i18n.jsworld.dtf.formatDate(d);
20756       }
20757     },
20758     formatTimezoneJSDate: function(d) {
20759       var day, hours, jsDate, minutes, month, year;
20760       year = d.getFullYear();
20761       month = this.leadingZero(d.getMonth());
20762       day = this.leadingZero(d.getDate());
20763       hours = this.leadingZero(d.getHours());
20764       minutes = this.leadingZero(d.getMinutes());
20765       jsDate = new Date(year, month, day, hours, minutes, 0);
20766       return jsDate.toDateString();
20767     },
20768     formatTime: function(d, timezone) {
20769       var formatted;
20770       if (timezone == null) {
20771         timezone = null;
20772       }
20773       formatted = ("" + (i18n.jsworld.dtf.formatTime(d))) + (timezone != null ? " " + (timezone != null ? timezone.tzAbbr : void 0) : "");
20774       return this.fixAMPM(d, formatted);
20775     },
20776     formatISODate: function(d) {
20777       var pad;
20778       pad = function(n) {
20779         if (n < 10) {
20780           return '0' + n;
20781         }
20782         return n;
20783       };
20784       return d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate()) + 'T' + pad(d.getUTCHours()) + ':' + pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds()) + 'Z';
20785     },
20786     formatExpDate: function(d) {
20787       var month, year;
20788       d = this.parseDate(d);
20789       year = d.getFullYear();
20790       month = this.leadingZero(d.getMonth() + 1);
20791       return "" + year + "-" + month;
20792     },
20793     formatLatLng: function(lat, lng, precision) {
20794       if (precision == null) {
20795         precision = 8;
20796       }
20797       return parseFloat(lat).toFixed(precision) + ',' + parseFloat(lng).toFixed(precision);
20798     },
20799     leadingZero: function(num) {
20800       if (num < 10) {
20801         return "0" + num;
20802       } else {
20803         return num;
20804       }
20805     },
20806     roundNumber: function(num, dec) {
20807       return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
20808     },
20809     notesToHTML: function(notes) {
20810       var i, note, notesHTML, _i, _len;
20811       notesHTML = '';
20812       i = 1;
20813       if (notes) {
20814         for (_i = 0, _len = notes.length; _i < _len; _i++) {
20815           note = notes[_i];
20816           notesHTML += "<strong>" + note['userid'] + "</strong> &nbsp;&nbsp;&nbsp; " + (this.formatDate(note['created_at'])) + "<p>" + note['note'] + "</p>";
20817           notesHTML += "<br>";
20818         }
20819       }
20820       return notesHTML.replace("'", '&quote');
20821     },
20822     formatPhone: function(n) {
20823       var parts, phone, regexObj;
20824       n = "" + n;
20825       regexObj = /^(?:\+?1[-. ]?)?(?:\(?([0-9]{3})\)?[-. ]?)?([0-9]{3})[-. ]?([0-9]{4})$/;
20826       if (regexObj.test(n)) {
20827         parts = n.match(regexObj);
20828         phone = "";
20829         if (parts[1]) {
20830           phone += "(" + parts[1] + ") ";
20831         }
20832         phone += "" + parts[2] + "-" + parts[3];
20833       } else {
20834         phone = n;
20835       }
20836       return phone;
20837     },
20838     usStates: ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'District of Columbia', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'],
20839     onboardingPages: ['applied', 'ready_to_interview', 'pending_interview', 'interviewed', 'accepted', 'ready_to_onboard', 'pending_onboarding', 'active', 'waitlisted', 'rejected'],
20840     driverBreadCrumb: function(loc, model) {
20841       var onboardingPage, out, _i, _len, _ref;
20842       out = "<a href='#/driver_ops/summary'>Drivers</a> > ";
20843       if (!(model != null)) {
20844         out += "<select name='onboardingPage' id='onboardingPageSelector'>";
20845         _ref = this.onboardingPages;
20846         for (_i = 0, _len = _ref.length; _i < _len; _i++) {
20847           onboardingPage = _ref[_i];
20848           out += "<option value='" + onboardingPage + "' " + (onboardingPage === loc ? "selected" : void 0) + ">" + (this.onboardingUrlToName(onboardingPage)) + "</option>";
20849         }
20850         out += "</select>";
20851       } else {
20852         out += "<a href='#/driver_ops/" + (model.get('driver_status')) + "'>" + (this.onboardingUrlToName(model.get('driver_status'))) + "</a>";
20853         out += " > " + (this.linkedName(model)) + " (" + (model.get('role')) + ") #" + (model.get('id'));
20854       }
20855       return out;
20856     },
20857     onboardingUrlToName: function(url) {
20858       return url != null ? url.replace(/_/g, " ").replace(/(^|\s)([a-z])/g, function(m, p1, p2) {
20859         return p1 + p2.toUpperCase();
20860       }) : void 0;
20861     },
20862     formatVehicle: function(vehicle) {
20863       if (vehicle.get('make') && vehicle.get('model') && vehicle.get('license_plate')) {
20864         return "" + (vehicle.get('make')) + " " + (vehicle.get('model')) + " (" + (vehicle.get('license_plate')) + ")";
20865       }
20866     },
20867     docArbitraryFields: function(docName, cityDocs) {
20868       var doc, field, out, _i, _j, _len, _len2, _ref;
20869       out = "";
20870       for (_i = 0, _len = cityDocs.length; _i < _len; _i++) {
20871         doc = cityDocs[_i];
20872         if (doc.name === docName && __indexOf.call(_.keys(doc), "metaFields") >= 0) {
20873           _ref = doc.metaFields;
20874           for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) {
20875             field = _ref[_j];
20876             out += "" + field.label + ": <input type='text' name='" + field.name + "' class='arbitraryField'><br>";
20877           }
20878         }
20879       }
20880       return out;
20881     },
20882     capitaliseFirstLetter: function(string) {
20883       return string.charAt(0).toUpperCase() + string.slice(1);
20884     },
20885     createDocUploadForm: function(docName, driverId, vehicleId, cityMeta, vehicleName, expirationRequired) {
20886       var ddocs, expDropdowns, pdocs, vdocs;
20887       if (driverId == null) {
20888         driverId = "None";
20889       }
20890       if (vehicleId == null) {
20891         vehicleId = "None";
20892       }
20893       if (cityMeta == null) {
20894         cityMeta = [];
20895       }
20896       if (vehicleName == null) {
20897         vehicleName = false;
20898       }
20899       if (expirationRequired == null) {
20900         expirationRequired = false;
20901       }
20902       ddocs = cityMeta["driverRequiredDocs"] || [];
20903       pdocs = cityMeta["partnerRequiredDocs"] || [];
20904       vdocs = cityMeta["vehicleRequiredDocs"] || [];
20905       expDropdowns = "Expiration Date:\n<select name=\"expiration-year\">\n  <option value=\"2011\">2011</option>\n  <option value=\"2012\">2012</option>\n  <option value=\"2013\">2013</option>\n  <option value=\"2014\">2014</option>\n  <option value=\"2015\">2015</option>\n  <option value=\"2016\">2016</option>\n  <option value=\"2017\">2017</option>\n  <option value=\"2018\">2018</option>\n</select> -\n<select name=\"expiration-month\">\n  <option value=\"01\">01</option>\n  <option value=\"02\">02</option>\n  <option value=\"03\">03</option>\n  <option value=\"04\">04</option>\n  <option value=\"05\">05</option>\n  <option value=\"06\">06</option>\n  <option value=\"07\">07</option>\n  <option value=\"08\">08</option>\n  <option value=\"09\">09</option>\n  <option value=\"10\">10</option>\n  <option value=\"11\">11</option>\n  <option value=\"12\">12</option>\n</select>";
20906       return "  <form class=\"documentuploadform\">\n  <div>\n    <input type=\"hidden\" name=\"fileName\" value=\"" + docName + "\">\n    <input type=\"hidden\" name=\"driver_id\" value=\"" + driverId + "\">\n    <input type=\"hidden\" name=\"vehicle_id\" value=\"" + vehicleId + "\">\n\n    <div>\n      <strong>" + (vehicleName ? vehicleName : "") + " " + docName + "</strong>\n    </div>\n\n    <div>\n      <input type=\"file\" name=\"uploadContent\" id=\"" + (vehicleId !== "None" ? "vehicle_" + vehicleId + "_" : "") + "doc_upload_" + (docName.replace(/[\W]/g, "_")) + "\">\n    </div>\n\n    <div class=\"expiration\">\n      " + (expirationRequired ? expDropdowns : "") + "\n    </div>\n\n    <div>\n      " + (app.helpers.docArbitraryFields(docName, _.union(ddocs, pdocs, vdocs))) + "\n    </div>\n\n    <div>\n      <input type=\"submit\" value=\"Upload\">\n    </div>\n\n  </div>\n</form>";
20907     },
20908     countrySelector: function(name, options) {
20909       var countries, countryCodePrefix, defaultOptions;
20910       if (options == null) {
20911         options = {};
20912       }
20913       defaultOptions = {
20914         selectedKey: 'telephone_code',
20915         selectedValue: '+1',
20916         silent: false
20917       };
20918       _.extend(defaultOptions, options);
20919       options = defaultOptions;
20920       countries = new app.collections.countries();
20921       countries.fetch({
20922         data: {
20923           limit: 300
20924         },
20925         success: function(countries) {
20926           var $option, $select, country, selected, _i, _len, _ref;
20927           selected = false;
20928           _ref = countries.models || [];
20929           for (_i = 0, _len = _ref.length; _i < _len; _i++) {
20930             country = _ref[_i];
20931             $select = $("select[name=" + name + "]");
20932             $option = $('<option></option>').val(country.id).attr('data-iso2', country.get('iso2')).attr('data-prefix', country.get('telephone_code')).html(country.get('name'));
20933             if (country.get(options.selectedKey) === options.selectedValue && !selected) {
20934               selected = true;
20935               $option.attr('selected', 'selected');
20936             }
20937             $select.append($option);
20938           }
20939           if (selected && !options.silent) {
20940             return $select.val(options.selected).trigger('change');
20941           }
20942         }
20943       });
20944       countryCodePrefix = options.countryCodePrefix ? "data-country-code-prefix='" + options.countryCodePrefix + "'" : '';
20945       return "<select name='" + name + "' id='" + name + "' " + countryCodePrefix + " " + (options.disabled ? 'disabled="disabled"' : "") + "></select>";
20946     },
20947     missingDocsOnDriver: function(driver) {
20948       var city, docsReq, documents, partnerDocs;
20949       city = driver.get('city');
20950       documents = driver.get('documents');
20951       if ((city != null) && (documents != null)) {
20952         docsReq = _.pluck(city != null ? city.get('meta')["driverRequiredDocs"] : void 0, "name");
20953         if (driver.get('role') === "partner") {
20954           partnerDocs = _.pluck(city != null ? city.get('meta')["partnerRequiredDocs"] : void 0, "name");
20955           docsReq = _.union(docsReq, partnerDocs);
20956         }
20957         return _.reject(docsReq, __bind(function(doc) {
20958           return __indexOf.call((documents != null ? documents.pluck("name") : void 0) || [], doc) >= 0;
20959         }, this));
20960       } else {
20961         return [];
20962       }
20963     }
20964   };
20965 }).call(this);
20966 }, "web-lib/i18n": function(exports, require, module) {(function() {
20967   exports.i18n = {
20968     defaultLocale: 'en_US',
20969     cookieName: '_LOCALE_',
20970     locales: {
20971       'en_US': "English (US)",
20972       'fr_FR': "Français"
20973     },
20974     currencyToLocale: {
20975       'USD': 'en_US',
20976       'EUR': 'fr_FR'
20977     },
20978     logglyKey: 'd2d5a9bc-7ebe-4538-a180-81e62c705b1b',
20979     logglyHost: 'https://logs.loggly.com',
20980     init: function() {
20981       this.castor = new window.loggly({
20982         url: this.logglyHost + '/inputs/' + this.logglyKey + '?rt=1',
20983         level: 'error'
20984       });
20985       this.setLocale($.cookie(this.cookieName) || this.defaultLocale);
20986       window.t = _.bind(this.t, this);
20987       this.loadLocaleTranslations(this.locale);
20988       if (!(this[this.defaultLocale] != null)) {
20989         return this.loadLocaleTranslations(this.defaultLocale);
20990       }
20991     },
20992     loadLocaleTranslations: function(locale) {
20993       var loadPaths, path, _i, _len, _results;
20994       loadPaths = ['web-lib/translations/' + locale, 'web-lib/translations/' + locale.slice(0, 2), 'translations/' + locale, 'translations/' + locale.slice(0, 2)];
20995       _results = [];
20996       for (_i = 0, _len = loadPaths.length; _i < _len; _i++) {
20997         path = loadPaths[_i];
20998         locale = path.substring(path.lastIndexOf('/') + 1);
20999         if (this[locale] == null) {
21000           this[locale] = {};
21001         }
21002         _results.push((function() {
21003           try {
21004             return _.extend(this[locale], require(path).translations);
21005           } catch (error) {
21006
21007           }
21008         }).call(this));
21009       }
21010       return _results;
21011     },
21012     getLocale: function() {
21013       return this.locale;
21014     },
21015     setLocale: function(locale) {
21016       var message, parts, _ref;
21017       parts = locale.split('_');
21018       this.locale = parts[0].toLowerCase();
21019       if (parts.length > 1) {
21020         this.locale += "_" + (parts[1].toUpperCase());
21021       }
21022       if (this.locale) {
21023         $.cookie(this.cookieName, this.locale, {
21024           path: '/',
21025           domain: '.uber.com'
21026         });
21027       }
21028       try {
21029         ((_ref = this.jsworld) != null ? _ref : this.jsworld = {}).lc = new jsworld.Locale(POSIX_LC[this.locale]);
21030         this.jsworld.mf = new jsworld.MonetaryFormatter(this.jsworld.lc);
21031         this.jsworld.nf = new jsworld.NumericFormatter(this.jsworld.lc);
21032         this.jsworld.dtf = new jsworld.DateTimeFormatter(this.jsworld.lc);
21033         this.jsworld.np = new jsworld.NumericParser(this.jsworld.lc);
21034         this.jsworld.mp = new jsworld.MonetaryParser(this.jsworld.lc);
21035         return this.jsworld.dtp = new jsworld.DateTimeParser(this.jsworld.lc);
21036       } catch (error) {
21037         message = 'JsWorld error with locale: ' + this.locale;
21038         return this.log({
21039           message: message,
21040           error: error
21041         });
21042       }
21043     },
21044     getTemplate: function(id) {
21045       var _ref, _ref2;
21046       return ((_ref = this[this.locale]) != null ? _ref[id] : void 0) || ((_ref2 = this[this.locale.slice(0, 2)]) != null ? _ref2[id] : void 0);
21047     },
21048     getTemplateDefault: function(id) {
21049       var _ref, _ref2;
21050       return ((_ref = this[this.defaultLocale]) != null ? _ref[id] : void 0) || ((_ref2 = this[this.defaultLocale.slice(0, 2)]) != null ? _ref2[id] : void 0);
21051     },
21052     getTemplateOrDefault: function(id) {
21053       return this.getTemplate(id) || this.getTemplateDefault(id);
21054     },
21055     t: function(id, vars) {
21056       var errStr, locale, template;
21057       if (vars == null) {
21058         vars = {};
21059       }
21060       locale = this.getLocale();
21061       template = this.getTemplate(id);
21062       if (template == null) {
21063         if (/dev|test/.test(window.location.host)) {
21064           template = "(?) " + id;
21065         } else {
21066           template = this.getTemplateDefault(id);
21067         }
21068         errStr = "Missing [" + locale + "] translation for [" + id + "] at [" + window.location.hash + "] - Default template is [" + template + "]";
21069         this.log({
21070           error: errStr,
21071           locale: locale,
21072           id: id,
21073           defaultTemplate: template
21074         });
21075       }
21076       if (template) {
21077         return _.template(template, vars);
21078       } else {
21079         return id;
21080       }
21081     },
21082     log: function(error) {
21083       if (/dev/.test(window.location.host)) {
21084         if ((typeof console !== "undefined" && console !== null ? console.log : void 0) != null) {
21085           return console.log(error);
21086         }
21087       } else {
21088         _.extend(error, {
21089           host: window.location.host,
21090           hash: window.location.hash
21091         });
21092         return this.castor.error(JSON.stringify(error));
21093       }
21094     }
21095   };
21096 }).call(this);
21097 }, "web-lib/mixins/i18n_phone_form": function(exports, require, module) {(function() {
21098   exports.i18nPhoneForm = {
21099     _events: {
21100       'change select[data-country-code-prefix]': 'setCountryCodePrefix'
21101     },
21102     setCountryCodePrefix: function(e) {
21103       var $el, prefix;
21104       $el = $(e.currentTarget);
21105       prefix = $el.find('option:selected').attr('data-prefix');
21106       return $("#" + ($el.attr('data-country-code-prefix'))).text(prefix);
21107     }
21108   };
21109 }).call(this);
21110 }, "web-lib/models/country": function(exports, require, module) {(function() {
21111   var UberModel;
21112   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
21113     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
21114     function ctor() { this.constructor = child; }
21115     ctor.prototype = parent.prototype;
21116     child.prototype = new ctor;
21117     child.__super__ = parent.prototype;
21118     return child;
21119   };
21120   UberModel = require('web-lib/uber_model').UberModel;
21121   exports.Country = (function() {
21122     __extends(Country, UberModel);
21123     function Country() {
21124       Country.__super__.constructor.apply(this, arguments);
21125     }
21126     Country.prototype.url = function() {
21127       if (this.id) {
21128         return "/countries/" + this.id;
21129       } else {
21130         return '/countries';
21131       }
21132     };
21133     return Country;
21134   })();
21135 }).call(this);
21136 }, "web-lib/models/vehicle_type": function(exports, require, module) {(function() {
21137   var UberModel;
21138   var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
21139     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
21140     function ctor() { this.constructor = child; }
21141     ctor.prototype = parent.prototype;
21142     child.prototype = new ctor;
21143     child.__super__ = parent.prototype;
21144     return child;
21145   };
21146   UberModel = require('web-lib/uber_model').UberModel;
21147   exports.VehicleType = (function() {
21148     __extends(VehicleType, UberModel);
21149     function VehicleType() {
21150       this.toString = __bind(this.toString, this);
21151       VehicleType.__super__.constructor.apply(this, arguments);
21152     }
21153     VehicleType.prototype.endpoint = 'vehicle_types';
21154     VehicleType.prototype.toTableRow = function(cols) {
21155       var actions, c, capacity, city_id, columnValues, created_at, created_by_user_id, deleted_at, id, make, minimum_year, model, rows, type, updated_at, updated_by_user_id, _i, _len, _ref;
21156       id = "<a href='#/vehicle_types/" + (this.get('id')) + "'>" + (this.get('id')) + "</a>";
21157       if (this.get('created_at')) {
21158         created_at = app.helpers.formatDate(this.get('created_at'));
21159       }
21160       if (this.get('updated_at')) {
21161         updated_at = app.helpers.formatDate(this.get('updated_at'));
21162       }
21163       if (this.get('deleted_at')) {
21164         deleted_at = app.helpers.formatDate(this.get('deleted_at'));
21165       }
21166       created_by_user_id = "<a href='#/clients/" + (this.get('created_by_user_id')) + "'>" + (this.get('created_by_user_id')) + "</a>";
21167       updated_by_user_id = "<a href='#/clients/" + (this.get('updated_by_user_id')) + "'>" + (this.get('updated_by_user_id')) + "</a>";
21168       city_id = (_ref = this.get('city')) != null ? _ref.get('display_name') : void 0;
21169       type = this.get('type');
21170       make = this.get('make');
21171       model = this.get('model');
21172       capacity = this.get('capacity');
21173       minimum_year = this.get('minimum_year');
21174       actions = "<a href='#/vehicle_types/" + (this.get('id')) + "'>Show</a>";
21175       if (!this.get('deleted_at')) {
21176         actions += " <a href='#/vehicle_types/" + (this.get('id')) + "/edit'>Edit</a>";
21177         actions += " <a id='" + (this.get('id')) + "' class='delete' href='#'>Delete</a>";
21178       }
21179       columnValues = {
21180         id: id,
21181         created_at: created_at,
21182         updated_at: updated_at,
21183         deleted_at: deleted_at,
21184         created_by_user_id: created_by_user_id,
21185         updated_by_user_id: updated_by_user_id,
21186         city_id: city_id,
21187         type: type,
21188         make: make,
21189         model: model,
21190         capacity: capacity,
21191         minimum_year: minimum_year,
21192         actions: actions
21193       };
21194       rows = [];
21195       for (_i = 0, _len = cols.length; _i < _len; _i++) {
21196         c = cols[_i];
21197         rows.push(columnValues[c] ? columnValues[c] : '-');
21198       }
21199       return rows;
21200     };
21201     VehicleType.prototype.toString = function() {
21202       return this.get('make') + ' ' + this.get('model') + ' ' + this.get('type') + (" (" + (this.get('capacity')) + ")");
21203     };
21204     return VehicleType;
21205   })();
21206 }).call(this);
21207 }, "web-lib/templates/footer": function(exports, require, module) {module.exports = function(__obj) {
21208   if (!__obj) __obj = {};
21209   var __out = [], __capture = function(callback) {
21210     var out = __out, result;
21211     __out = [];
21212     callback.call(this);
21213     result = __out.join('');
21214     __out = out;
21215     return __safe(result);
21216   }, __sanitize = function(value) {
21217     if (value && value.ecoSafe) {
21218       return value;
21219     } else if (typeof value !== 'undefined' && value != null) {
21220       return __escape(value);
21221     } else {
21222       return '';
21223     }
21224   }, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
21225   __safe = __obj.safe = function(value) {
21226     if (value && value.ecoSafe) {
21227       return value;
21228     } else {
21229       if (!(typeof value !== 'undefined' && value != null)) value = '';
21230       var result = new String(value);
21231       result.ecoSafe = true;
21232       return result;
21233     }
21234   };
21235   if (!__escape) {
21236     __escape = __obj.escape = function(value) {
21237       return ('' + value)
21238         .replace(/&/g, '&amp;')
21239         .replace(/</g, '&lt;')
21240         .replace(/>/g, '&gt;')
21241         .replace(/"/g, '&quot;');
21242     };
21243   }
21244   (function() {
21245     (function() {
21246       var locale, title, _ref;
21247       __out.push('<div class="footer_col_2">\n  <ul>\n    <li class="head">');
21248       __out.push(__sanitize(t("Info")));
21249       __out.push('</li>\n    <li><a href="https://www.uber.com/learn">');
21250       __out.push(__sanitize(t("Learn More")));
21251       __out.push('</a></li>\n    <li><a href="https://www.uber.com/learn#pricing">');
21252       __out.push(__sanitize(t("Pricing")));
21253       __out.push('</a></li>\n    <li><a href="http://support.uber.com">');
21254       __out.push(__sanitize(t("Support & FAQ")));
21255       __out.push('</a></li>\n    <li><a href="https://partners.uber.com/#!/partners/new">');
21256       __out.push(__sanitize(t("Apply to Drive")));
21257       __out.push('</a></li>\n  </ul>\n</div>\n<div class="footer_col_2">\n  <ul>\n    <li class="head">');
21258       __out.push(__sanitize(t("Social")));
21259       __out.push('</li>\n    <li><a href="http://www.twitter.com/uber">');
21260       __out.push(__sanitize(t("Twitter")));
21261       __out.push('</a></li>\n    <li><a href="http://www.facebook.com/uber">');
21262       __out.push(__sanitize(t("Facebook")));
21263       __out.push('</a></li>\n    <li><a href="http://blog.uber.com">');
21264       __out.push(__sanitize(t("Blog")));
21265       __out.push('</a></li>\n    <li><a href="https://www.uber.com/contact">');
21266       __out.push(__sanitize(t("Contact Us")));
21267       __out.push('</a></li>\n  </ul>\n</div>\n<div class="footer_col_2">\n  <ul>\n    <li class="head">');
21268       __out.push(__sanitize(t("Phones")));
21269       __out.push('</li>\n    <li><a href="https://www.uber.com/phones/text">');
21270       __out.push(__sanitize(t("Text Message")));
21271       __out.push('</a></li>\n    <li><a href="https://www.uber.com/phones/iphone">');
21272       __out.push(__sanitize(t("iPhone")));
21273       __out.push('</a></li>\n    <li><a href="https://www.uber.com/phones/android">');
21274       __out.push(__sanitize(t("Android")));
21275       __out.push('</a></li>\n  </ul>\n</div>\n<div class="footer_col_2">\n  <ul>\n    <li class="head">');
21276       __out.push(__sanitize(t("Company_Footer")));
21277       __out.push('</li>\n    <li><a href="https://www.uber.com/privacy">');
21278       __out.push(__sanitize(t("Privacy Policy")));
21279       __out.push('</a></li>\n    <li><a href="https://www.uber.com/terms">');
21280       __out.push(__sanitize(t("Terms")));
21281       __out.push('</a></li>\n    <li><a href="https://www.uber.com/jobs">');
21282       __out.push(__sanitize(t("Jobs")));
21283       __out.push('</a></li>\n  </ul>\n</div>\n<div class="footer_col_copyright">\n  <p>');
21284       __out.push(t("Copyright &copy; Uber Technologies, Inc."));
21285       __out.push('</p>\n    <p>\n      ');
21286       __out.push(__sanitize(t('Language:')));
21287       __out.push('\n      ');
21288       _ref = typeof i18n !== "undefined" && i18n !== null ? i18n.locales : void 0;
21289       for (locale in _ref) {
21290         title = _ref[locale];
21291         __out.push('\n        ');
21292         if (locale === (typeof i18n !== "undefined" && i18n !== null ? i18n.getLocale() : void 0)) {
21293           __out.push('\n          <span class="language current_language" id=\'');
21294           __out.push(__sanitize(locale));
21295           __out.push('\'>');
21296           __out.push(__sanitize(title));
21297           __out.push('</span>\n        ');
21298         } else {
21299           __out.push('\n            <a href="');
21300           __out.push(__sanitize(window.location.href));
21301           __out.push('" class="language" id=\'');
21302           __out.push(__sanitize(locale));
21303           __out.push('\' title="');
21304           __out.push(__sanitize(title));
21305           __out.push('">');
21306           __out.push(__sanitize(title));
21307           __out.push('</a>\n          ');
21308         }
21309         __out.push('\n        ');
21310       }
21311       __out.push('\n    </p>\n</div>\n');
21312     }).call(this);
21313     
21314   }).call(__obj);
21315   __obj.safe = __objSafe, __obj.escape = __escape;
21316   return __out.join('');
21317 }}, "web-lib/translations/en": function(exports, require, module) {(function() {
21318   exports.translations = {
21319     "Info": "Info",
21320     "Learn More": "Learn More",
21321     "Pricing": "Pricing",
21322     "FAQ": "FAQ",
21323     "Support": "Support",
21324     "Support & FAQ": "Support & FAQ",
21325     "Contact Us": "Contact Us",
21326     "Jobs": "Jobs",
21327     "Phones": "Phones",
21328     "Text Message": "Text Message",
21329     "iPhone": "iPhone",
21330     "Android": "Android",
21331     "Drivers": "Drivers",
21332     "Apply": "Apply",
21333     "Sign In": "Sign In",
21334     "Social": "Social",
21335     "Twitter": "Twitter",
21336     "Facebook": "Facebook",
21337     "Blog": "Blog",
21338     "Legal": "Legal",
21339     "Company_Footer": "Company",
21340     "Privacy Policy": "Privacy Policy",
21341     "Terms": "Terms",
21342     "Copyright &copy; Uber Technologies, Inc.": "Copyright &copy; Uber Technologies, Inc.",
21343     "Language:": "Language:",
21344     "Apply to Drive": "Apply to Drive",
21345     "Expiration": "Expiration",
21346     "Fare": "Fare",
21347     "Driver": "Driver ",
21348     "Dashboard": "Dashboard",
21349     "Forgot Password": "Forgot Password",
21350     "Trip Details": "Trip Details",
21351     "Save": "Save",
21352     "Cancel": "Cancel",
21353     "Edit": "Edit",
21354     "Password": "Password",
21355     "First Name": "First Name",
21356     "Last Name": "Last Name",
21357     "Email Address": "Email Address",
21358     "Submit": "Submit",
21359     "Mobile Number": "Mobile Number",
21360     "Zip Code": "Zip Code",
21361     "Sign Out": "Sign Out",
21362     "Confirm Email Message": "Attempting to confirm email...",
21363     "Upload": "Upload",
21364     "Rating": "Rating",
21365     "Pickup Time": "Pickup Time",
21366     "2011": "2011",
21367     "2012": "2012",
21368     "2013": "2013",
21369     "2014": "2014",
21370     "2015": "2015",
21371     "2016": "2016",
21372     "2017": "2017",
21373     "2018": "2018",
21374     "2019": "2019",
21375     "2020": "2020",
21376     "2021": "2021",
21377     "2022": "2022",
21378     "01": "01",
21379     "02": "02",
21380     "03": "03",
21381     "04": "04",
21382     "05": "05",
21383     "06": "06",
21384     "07": "07",
21385     "08": "08",
21386     "09": "09",
21387     "10": "10",
21388     "11": "11",
21389     "12": "12"
21390   };
21391 }).call(this);
21392 }, "web-lib/translations/fr": function(exports, require, module) {(function() {
21393   exports.translations = {
21394     "Info": "Info",
21395     "Learn More": "En Savoir Plus",
21396     "Pricing": "Calcul du Prix",
21397     "Support & FAQ": "Aide & FAQ",
21398     "Contact Us": "Contactez Nous",
21399     "Jobs": "Emplois",
21400     "Phones": "Téléphones",
21401     "Text Message": "SMS",
21402     "iPhone": "iPhone",
21403     "Android": "Android",
21404     "Apply to Drive": "Candidature Chauffeur",
21405     "Sign In": "Connexion",
21406     "Social": "Contact",
21407     "Twitter": "Twitter",
21408     "Facebook": "Facebook",
21409     "Blog": "Blog",
21410     "Privacy Policy": "Protection des Données Personelles",
21411     "Terms": "Conditions Générales",
21412     "Copyright &copy; Uber Technologies, Inc.": "© Uber, Inc.",
21413     "Language:": "Langue:",
21414     "Forgot Password": "Mot de passe oublié",
21415     "Company_Footer": "À Propos d'Uber",
21416     "Expiration": "Expiration",
21417     "Fare": "Tarif",
21418     "Driver": "Chauffeur",
21419     "Drivers": "Chauffeurs",
21420     "Dashboard": "Tableau de bord",
21421     "Forgot Password": "Mot de passe oublié",
21422     "Forgot Password?": "Mot de passe oublié?",
21423     "Trip Details": "Détails de la course",
21424     "Save": "Enregistrer",
21425     "Cancel": "Annuler",
21426     "Edit": "Modifier",
21427     "Password": "Mot de passe",
21428     "First Name": "Prénom",
21429     "Last Name": "Nom",
21430     "Email Address": "E-mail",
21431     "Submit": "Soumettre",
21432     "Mobile Number": "Téléphone Portable",
21433     "Zip Code": "Code Postal",
21434     "Sign Out": "Se déconnecter",
21435     "Confirm Email Message": "E-mail de confirmation",
21436     "Upload": "Télécharger",
21437     "Rating": "Notation",
21438     "Pickup Time": "Heure de prise en charge",
21439     "2011": "2011",
21440     "2012": "2012",
21441     "2013": "2013",
21442     "2014": "2014",
21443     "2015": "2015",
21444     "2016": "2016",
21445     "2017": "2017",
21446     "2018": "2018",
21447     "2019": "2019",
21448     "2020": "2020",
21449     "2021": "2021",
21450     "2022": "2022",
21451     "01": "01",
21452     "02": "02",
21453     "03": "03",
21454     "04": "04",
21455     "05": "05",
21456     "06": "06",
21457     "07": "07",
21458     "08": "08",
21459     "09": "09",
21460     "10": "10",
21461     "11": "11",
21462     "12": "12"
21463   };
21464 }).call(this);
21465 }, "web-lib/uber_collection": function(exports, require, module) {(function() {
21466   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
21467     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
21468     function ctor() { this.constructor = child; }
21469     ctor.prototype = parent.prototype;
21470     child.prototype = new ctor;
21471     child.__super__ = parent.prototype;
21472     return child;
21473   };
21474   exports.UberCollection = (function() {
21475     __extends(UberCollection, Backbone.Collection);
21476     function UberCollection() {
21477       UberCollection.__super__.constructor.apply(this, arguments);
21478     }
21479     UberCollection.prototype.parse = function(data) {
21480       var model, tmp, _i, _in, _len, _out;
21481       _in = data.resources || data;
21482       _out = [];
21483       if (data.meta) {
21484         this.meta = data.meta;
21485       }
21486       for (_i = 0, _len = _in.length; _i < _len; _i++) {
21487         model = _in[_i];
21488         tmp = new this.model;
21489         tmp.set(tmp.parse(model));
21490         _out.push(tmp);
21491       }
21492       return _out;
21493     };
21494     UberCollection.prototype.isRenderable = function() {
21495       if (this.models.length) {
21496         return true;
21497       }
21498     };
21499     UberCollection.prototype.toTableRows = function(cols) {
21500       var tableRows;
21501       tableRows = [];
21502       _.each(this.models, function(model) {
21503         return tableRows.push(model.toTableRow(cols));
21504       });
21505       return tableRows;
21506     };
21507     return UberCollection;
21508   })();
21509 }).call(this);
21510 }, "web-lib/uber_model": function(exports, require, module) {(function() {
21511   var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
21512     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
21513     function ctor() { this.constructor = child; }
21514     ctor.prototype = parent.prototype;
21515     child.prototype = new ctor;
21516     child.__super__ = parent.prototype;
21517     return child;
21518   }, __indexOf = Array.prototype.indexOf || function(item) {
21519     for (var i = 0, l = this.length; i < l; i++) {
21520       if (this[i] === item) return i;
21521     }
21522     return -1;
21523   };
21524   exports.UberModel = (function() {
21525     __extends(UberModel, Backbone.Model);
21526     function UberModel() {
21527       this.refetch = __bind(this.refetch, this);
21528       this.fetch = __bind(this.fetch, this);
21529       this.save = __bind(this.save, this);
21530       this.parse = __bind(this.parse, this);
21531       UberModel.__super__.constructor.apply(this, arguments);
21532     }
21533     UberModel.prototype.endpoint = 'set_api_endpoint_in_subclass';
21534     UberModel.prototype.refetchOptions = {};
21535     UberModel.prototype.url = function(type) {
21536       var endpoint_path;
21537       endpoint_path = "/" + this.endpoint;
21538       if (this.get('id')) {
21539         return endpoint_path + ("/" + (this.get('id')));
21540       } else {
21541         return endpoint_path;
21542       }
21543     };
21544     UberModel.prototype.isRenderable = function() {
21545       var i, key, value, _ref;
21546       i = 0;
21547       _ref = this.attributes;
21548       for (key in _ref) {
21549         if (!__hasProp.call(_ref, key)) continue;
21550         value = _ref[key];
21551         if (this.attributes.hasOwnProperty(key)) {
21552           i += 1;
21553         }
21554         if (i > 1) {
21555           return true;
21556         }
21557       }
21558       return !(i === 1);
21559     };
21560     UberModel.prototype.parse = function(response) {
21561       var attrs, key, model, models, _i, _j, _k, _len, _len2, _len3, _ref, _ref2;
21562       if (typeof response === 'object') {
21563         _ref = _.intersection(_.keys(app.models), _.keys(response));
21564         for (_i = 0, _len = _ref.length; _i < _len; _i++) {
21565           key = _ref[_i];
21566           if (response[key]) {
21567             attrs = this.parse(response[key]);
21568             if (typeof attrs === 'object') {
21569               response[key] = new app.models[key](attrs);
21570             }
21571           }
21572         }
21573         _ref2 = _.intersection(_.keys(app.collections), _.keys(response));
21574         for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
21575           key = _ref2[_j];
21576           models = response[key];
21577           if (_.isArray(models)) {
21578             response[key] = new app.collections[key];
21579             for (_k = 0, _len3 = models.length; _k < _len3; _k++) {
21580               model = models[_k];
21581               attrs = app.collections[key].prototype.model.prototype.parse(model);
21582               response[key].add(new response[key].model(attrs));
21583             }
21584           }
21585         }
21586       }
21587       return response;
21588     };
21589     UberModel.prototype.save = function(attributes, options) {
21590       var attr, _i, _j, _len, _len2, _ref, _ref2;
21591       if (options == null) {
21592         options = {};
21593       }
21594       _ref = _.intersection(_.keys(app.models), _.keys(this.attributes));
21595       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
21596         attr = _ref[_i];
21597         if (typeof this.get(attr) === "object") {
21598           this.unset(attr, {
21599             silent: true
21600           });
21601         }
21602       }
21603       _ref2 = _.intersection(_.keys(app.collections), _.keys(this.attributes));
21604       for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
21605         attr = _ref2[_j];
21606         if (typeof this.get(attr) === "object") {
21607           this.unset(attr, {
21608             silent: true
21609           });
21610         }
21611       }
21612       if ((options != null) && options.diff && (attributes != null) && attributes !== {}) {
21613         attributes['id'] = this.get('id');
21614         attributes['token'] = this.get('token');
21615         this.clear({
21616           'silent': true
21617         });
21618         this.set(attributes, {
21619           silent: true
21620         });
21621       }
21622       if (__indexOf.call(_.keys(options), "data") < 0 && __indexOf.call(_.keys(this.refetchOptions || {}), "data") >= 0) {
21623         options.data = this.refetchOptions.data;
21624       }
21625       return Backbone.Model.prototype.save.call(this, attributes, options);
21626     };
21627     UberModel.prototype.fetch = function(options) {
21628       this.refetchOptions = options;
21629       return Backbone.Model.prototype.fetch.call(this, options);
21630     };
21631     UberModel.prototype.refetch = function() {
21632       return this.fetch(this.refetchOptions);
21633     };
21634     return UberModel;
21635   })();
21636 }).call(this);
21637 }, "web-lib/uber_router": function(exports, require, module) {(function() {
21638   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
21639     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
21640     function ctor() { this.constructor = child; }
21641     ctor.prototype = parent.prototype;
21642     child.prototype = new ctor;
21643     child.__super__ = parent.prototype;
21644     return child;
21645   };
21646   exports.UberRouter = (function() {
21647     __extends(UberRouter, Backbone.Router);
21648     function UberRouter() {
21649       UberRouter.__super__.constructor.apply(this, arguments);
21650     }
21651     UberRouter.prototype.datePickers = function(format) {
21652       if (format == null) {
21653         format = "%Z-%m-%dT%H:%i:%s%:";
21654       }
21655       $('.datepicker').AnyTime_noPicker();
21656       return $('.datepicker').AnyTime_picker({
21657         'format': format,
21658         'formatUtcOffset': '%@'
21659       });
21660     };
21661     UberRouter.prototype.autoGrowInput = function() {
21662       return $('.editable input').autoGrowInput();
21663     };
21664     UberRouter.prototype.windowTitle = function(title) {
21665       return $(document).attr('title', title);
21666     };
21667     return UberRouter;
21668   })();
21669 }).call(this);
21670 }, "web-lib/uber_show_view": function(exports, require, module) {(function() {
21671   var UberView;
21672   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
21673     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
21674     function ctor() { this.constructor = child; }
21675     ctor.prototype = parent.prototype;
21676     child.prototype = new ctor;
21677     child.__super__ = parent.prototype;
21678     return child;
21679   }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
21680   UberView = require('web-lib/uber_view').UberView;
21681   exports.UberShowView = (function() {
21682     __extends(UberShowView, UberView);
21683     function UberShowView() {
21684       UberShowView.__super__.constructor.apply(this, arguments);
21685     }
21686     UberShowView.prototype.view = 'show';
21687     UberShowView.prototype.events = {
21688       'click #edit': 'edit',
21689       'submit form': 'save',
21690       'click .cancel': 'cancel'
21691     };
21692     UberShowView.prototype.errors = null;
21693     UberShowView.prototype.showTemplate = null;
21694     UberShowView.prototype.editTemplate = null;
21695     UberShowView.prototype.initialize = function() {
21696       if (this.init_hook) {
21697         this.init_hook();
21698       }
21699       _.bindAll(this, 'render');
21700       return this.model.bind('change', this.render);
21701     };
21702     UberShowView.prototype.render = function() {
21703       var $el;
21704       $el = $(this.el);
21705       this.selectView();
21706       if (this.view === 'show') {
21707         $el.html(this.showTemplate({
21708           model: this.model
21709         }));
21710       } else if (this.view === 'edit') {
21711         $el.html(this.editTemplate({
21712           model: this.model,
21713           errors: this.errors || {},
21714           collections: this.collections || {}
21715         }));
21716       } else {
21717         $el.html(this.newTemplate({
21718           model: this.model,
21719           errors: this.errors || {},
21720           collections: this.collections || {}
21721         }));
21722       }
21723       if (this.render_hook) {
21724         this.render_hook();
21725       }
21726       this.errors = null;
21727       this.userIdsToLinkedNames();
21728       this.datePickers();
21729       return this.place();
21730     };
21731     UberShowView.prototype.selectView = function() {
21732       var url;
21733       if (this.options.urlRendering) {
21734         url = window.location.hash;
21735         if (url.match(/\/new/)) {
21736           return this.view = 'new';
21737         } else if (url.match(/\/edit/)) {
21738           return this.view = 'edit';
21739         } else {
21740           return this.view = 'show';
21741         }
21742       }
21743     };
21744     UberShowView.prototype.edit = function(e) {
21745       e.preventDefault();
21746       if (this.options.urlRendering) {
21747         window.location.hash = '#/' + this.model.endpoint + '/' + this.model.get('id') + '/edit';
21748       } else {
21749         this.view = 'edit';
21750       }
21751       return this.model.change();
21752     };
21753     UberShowView.prototype.save = function(e) {
21754       var attributes, ele, form_attrs, _i, _len, _ref;
21755       e.preventDefault();
21756       attributes = $(e.currentTarget).serializeToJson();
21757       form_attrs = {};
21758       _ref = $('input[type="radio"]');
21759       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
21760         ele = _ref[_i];
21761         if ($(ele).is(':checked')) {
21762           form_attrs[$(ele).attr('name')] = $(ele).attr('value');
21763         }
21764       }
21765       attributes = _.extend(attributes, form_attrs);
21766       if (this.relationships) {
21767         attributes = _.extend(attributes, {
21768           relationships: this.relationships
21769         });
21770       }
21771       if (this.filter_attributes != null) {
21772         this.filter_attributes(attributes);
21773       }
21774       return this.model.save(attributes, {
21775         silent: true,
21776         success: __bind(function(model) {
21777           if (this.options.urlRendering) {
21778             window.location.hash = '#/' + this.model.endpoint + '/' + this.model.get('id');
21779           } else {
21780             this.view = 'show';
21781           }
21782           return this.flash('success', "Uber save!");
21783         }, this),
21784         statusCode: {
21785           406: __bind(function(xhr) {
21786             this.errors = JSON.parse(xhr.responseText);
21787             return this.flash('error', 'That was not Uber.');
21788           }, this)
21789         },
21790         error: __bind(function(model, xhr) {
21791           var code, message, responseJSON, responseText;
21792           code = xhr.status;
21793           responseText = xhr.responseText;
21794           if (responseText) {
21795             responseJSON = JSON.parse(responseText);
21796           }
21797           if (responseJSON && (typeof responseJSON === 'object') && (responseJSON.hasOwnProperty('error'))) {
21798             message = responseJSON.error;
21799           }
21800           return this.flash('error', (code || 'Unknown') + ' error' + (': ' + message || ''));
21801         }, this),
21802         complete: __bind(function() {
21803           return this.model.change();
21804         }, this)
21805       });
21806     };
21807     UberShowView.prototype.cancel = function(e) {
21808       e.preventDefault();
21809       if (this.options.urlRendering) {
21810         window.location.hash = '#/' + this.model.endpoint + '/' + this.model.get('id');
21811       } else {
21812         this.view = 'show';
21813       }
21814       return this.model.fetch({
21815         silent: true,
21816         complete: __bind(function() {
21817           return this.model.change();
21818         }, this)
21819       });
21820     };
21821     return UberShowView;
21822   })();
21823 }).call(this);
21824 }, "web-lib/uber_sync": function(exports, require, module) {(function() {
21825   var methodType;
21826   var __indexOf = Array.prototype.indexOf || function(item) {
21827     for (var i = 0, l = this.length; i < l; i++) {
21828       if (this[i] === item) return i;
21829     }
21830     return -1;
21831   };
21832   methodType = {
21833     create: 'POST',
21834     update: 'PUT',
21835     "delete": 'DELETE',
21836     read: 'GET'
21837   };
21838   exports.UberSync = function(method, model, options) {
21839     var token;
21840     options.type = methodType[method];
21841     options.url = _.isString(this.url) ? '/api' + this.url : '/api' + this.url(options.type);
21842     options.data = _.extend({}, options.data);
21843     if (__indexOf.call(_.keys(options.data), "city_id") < 0) {
21844       if ($.cookie('city_filter')) {
21845         _.extend(options.data, {
21846           city_id: $.cookie('city_filter')
21847         });
21848       }
21849     } else {
21850       delete options.data['city_id'];
21851     }
21852     if (options.type === 'POST' || options.type === 'PUT') {
21853       _.extend(options.data, model.toJSON());
21854     }
21855     token = $.cookie('token') ? $.cookie('token') : typeof USER !== "undefined" && USER !== null ? USER.get('token') : "";
21856     _.extend(options.data, {
21857       token: token
21858     });
21859     if (method === "delete") {
21860       options.contentType = 'application/json';
21861       options.data = JSON.stringify(options.data);
21862     }
21863     return $.ajax(options);
21864   };
21865 }).call(this);
21866 }, "web-lib/uber_view": function(exports, require, module) {(function() {
21867   var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
21868     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
21869     function ctor() { this.constructor = child; }
21870     ctor.prototype = parent.prototype;
21871     child.prototype = new ctor;
21872     child.__super__ = parent.prototype;
21873     return child;
21874   };
21875   exports.UberView = (function() {
21876     __extends(UberView, Backbone.View);
21877     function UberView() {
21878       this.processDocumentUpload = __bind(this.processDocumentUpload, this);
21879       UberView.__super__.constructor.apply(this, arguments);
21880     }
21881     UberView.prototype.className = 'view_container';
21882     UberView.prototype.hashId = function() {
21883       return parseInt(location.hash.split('/')[2]);
21884     };
21885     UberView.prototype.place = function(content) {
21886       var $target;
21887       $target = this.options.scope ? this.options.scope.find(this.options.selector) : $(this.options.selector);
21888       $target[this.options.method || 'html'](content || this.el);
21889       this.delegateEvents();
21890       $('#spinner').hide();
21891       return this;
21892     };
21893     UberView.prototype.mixin = function(m, args) {
21894       var events, self;
21895       if (args == null) {
21896         args = {};
21897       }
21898       self = this;
21899       events = m._events;
21900       _.extend(this, m);
21901       if (m.initialize) {
21902         m.initialize(self, args);
21903       }
21904       return _.each(_.keys(events), function(key) {
21905         var event, func, selector, split;
21906         split = key.split(' ');
21907         event = split[0];
21908         selector = split[1];
21909         func = events[key];
21910         return $(self.el).find(selector).live(event, function(e) {
21911           return self[func](e);
21912         });
21913       });
21914     };
21915     UberView.prototype.datePickers = function(format) {
21916       if (format == null) {
21917         format = "%Z-%m-%dT%H:%i:%s%:";
21918       }
21919       $('.datepicker').AnyTime_noPicker();
21920       return $('.datepicker').AnyTime_picker({
21921         'format': format,
21922         'formatUtcOffset': '%@'
21923       });
21924     };
21925     UberView.prototype.dataTable = function(collection, selector, options, params, cols) {
21926       var defaults;
21927       if (selector == null) {
21928         selector = 'table';
21929       }
21930       if (options == null) {
21931         options = {};
21932       }
21933       if (params == null) {
21934         params = {};
21935       }
21936       if (cols == null) {
21937         cols = [];
21938       }
21939       $(selector).empty();
21940       if (!cols.length) {
21941         cols = collection.defaultColumns;
21942       }
21943       defaults = {
21944         aoColumns: collection.tableColumns(cols),
21945         bDestroy: true,
21946         bSort: false,
21947         bProcessing: true,
21948         bFilter: false,
21949         bServerSide: true,
21950         bPaginate: true,
21951         bScrollInfinite: true,
21952         bScrollCollapse: true,
21953         sScrollY: '600px',
21954         iDisplayLength: 50,
21955         fnServerData: function(source, data, callback) {
21956           var defaultParams;
21957           defaultParams = {
21958             limit: data[4].value,
21959             offset: data[3].value
21960           };
21961           return collection.fetch({
21962             data: _.extend(defaultParams, params),
21963             success: function() {
21964               return callback({
21965                 aaData: collection.toTableRows(cols),
21966                 iTotalRecords: collection.meta.count,
21967                 iTotalDisplayRecords: collection.meta.count
21968               });
21969             },
21970             error: function() {
21971               return new Error({
21972                 message: 'Loading error.'
21973               });
21974             }
21975           });
21976         },
21977         fnRowCallback: function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
21978           $('[data-tooltip]', nRow).qtip({
21979             content: {
21980               attr: 'data-tooltip'
21981             },
21982             style: {
21983               classes: "ui-tooltip-light ui-tooltip-rounded ui-tooltip-shadow"
21984             }
21985           });
21986           return nRow;
21987         }
21988       };
21989       return $(this.el).find(selector).dataTable(_.extend(defaults, options));
21990     };
21991     UberView.prototype.dataTableLocal = function(collection, selector, options, params, cols) {
21992       var $dataTable, defaults;
21993       if (selector == null) {
21994         selector = 'table';
21995       }
21996       if (options == null) {
21997         options = {};
21998       }
21999       if (params == null) {
22000         params = {};
22001       }
22002       if (cols == null) {
22003         cols = [];
22004       }
22005       $(selector).empty();
22006       if (!cols.length || cols.length === 0) {
22007         cols = collection.defaultColumns;
22008       }
22009       defaults = {
22010         aaData: collection.toTableRows(cols),
22011         aoColumns: collection.tableColumns(cols),
22012         bDestroy: true,
22013         bSort: false,
22014         bProcessing: true,
22015         bFilter: false,
22016         bScrollInfinite: true,
22017         bScrollCollapse: true,
22018         sScrollY: '600px',
22019         iDisplayLength: -1
22020       };
22021       $dataTable = $(this.el).find(selector).dataTable(_.extend(defaults, options));
22022       _.delay(__bind(function() {
22023         if ($dataTable && $dataTable.length > 0) {
22024           return $dataTable.fnAdjustColumnSizing();
22025         }
22026       }, this), 1);
22027       return $dataTable;
22028     };
22029     UberView.prototype.reverseGeocode = function() {
22030       var $el;
22031       return '';
22032       $el = $(this.el);
22033       return this.requireMaps(function() {
22034         var geocoder;
22035         geocoder = new google.maps.Geocoder();
22036         return $el.find('[data-point]').each(function() {
22037           var $this, latLng, point;
22038           $this = $(this);
22039           point = JSON.parse($this.attr('data-point'));
22040           latLng = new google.maps.LatLng(point.latitude, point.longitude);
22041           return geocoder.geocode({
22042             latLng: latLng
22043           }, function(data, status) {
22044             if (status === google.maps.GeocoderStatus.OK) {
22045               return $this.text(data[0].formatted_address);
22046             }
22047           });
22048         });
22049       });
22050     };
22051     UberView.prototype.userIdsToLinkedNames = function() {
22052       var $el;
22053       $el = $(this.el);
22054       return $el.find('a[data-user-id][data-user-type]').each(function() {
22055         var $this, user, userType;
22056         $this = $(this);
22057         userType = $this.attr('data-user-type') === 'user' ? 'client' : $this.attr('data-user-type');
22058         user = new app.models[userType]({
22059           id: $this.attr('data-user-id')
22060         });
22061         return user.fetch({
22062           success: function(user) {
22063             return $this.html(app.helpers.linkedName(user)).attr('href', "!/" + user.role + "s/" + user.id);
22064           },
22065           error: function() {
22066             if ($this.attr('data-user-type') === 'user') {
22067               user = new app.models['driver']({
22068                 id: $this.attr('data-user-id')
22069               });
22070               return user.fetch({
22071                 success: function(user) {
22072                   return $this.html(app.helpers.linkedName(user)).attr('href', "!/driver/" + user.id);
22073                 }
22074               });
22075             }
22076           }
22077         });
22078       });
22079     };
22080     UberView.prototype.selectedCity = function() {
22081       var $selected, city, cityFilter;
22082       cityFilter = $.cookie('city_filter');
22083       $selected = $("#city_filter option[value=" + cityFilter + "]");
22084       if (city_filter && $selected.length) {
22085         return city = {
22086           lat: parseFloat($selected.attr('data-lat')),
22087           lng: parseFloat($selected.attr('data-lng')),
22088           timezone: $selected.attr('data-timezone')
22089         };
22090       } else {
22091         return city = {
22092           lat: 37.775,
22093           lng: -122.45,
22094           timezone: 'Etc/UTC'
22095         };
22096       }
22097     };
22098     UberView.prototype.updateModel = function(e, success) {
22099       var $el, attrs, model, self;
22100       e.preventDefault();
22101       $el = $(e.currentTarget);
22102       self = this;
22103       model = new this.model.__proto__.constructor({
22104         id: this.model.id
22105       });
22106       attrs = {};
22107       $el.find('[name]').each(function() {
22108         var $this;
22109         $this = $(this);
22110         return attrs["" + ($this.attr('name'))] = $this.val();
22111       });
22112       self.model.set(attrs);
22113       $el.find('span.error').text('');
22114       return model.save(attrs, {
22115         complete: function(xhr) {
22116           var response;
22117           response = JSON.parse(xhr.responseText);
22118           switch (xhr.status) {
22119             case 200:
22120               self.model = model;
22121               $el.find('[name]').val('');
22122               if (success) {
22123                 return success();
22124               }
22125               break;
22126             case 406:
22127               return _.each(response, function(error, field) {
22128                 return $el.find("[name=" + field + "]").parent().find('span.error').text(error);
22129               });
22130             default:
22131               return this.unanticipatedError(response);
22132           }
22133         }
22134       });
22135     };
22136     UberView.prototype.autoUpdateModel = function(e) {
22137       var $el, arg, model, self, val;
22138       $el = $(e.currentTarget);
22139       val = $el.val();
22140       self = this;
22141       if (val !== this.model.get($el.attr('id'))) {
22142         arg = {};
22143         arg[$el.attr('id')] = $el.is(':checkbox') ? $el.is(':checked') ? 1 : 0 : val;
22144         $('.editable span').empty();
22145         this.model.set(arg);
22146         model = new this.model.__proto__.constructor({
22147           id: this.model.id
22148         });
22149         return model.save(arg, {
22150           complete: function(xhr) {
22151             var key, response, _i, _len, _ref, _results;
22152             response = JSON.parse(xhr.responseText);
22153             switch (xhr.status) {
22154               case 200:
22155                 self.flash('success', 'Saved!');
22156                 return $el.blur();
22157               case 406:
22158                 self.flash('error', 'That was not Uber.');
22159                 _ref = _.keys(response);
22160                 _results = [];
22161                 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
22162                   key = _ref[_i];
22163                   _results.push($el.parent().find('span').html(response[key]));
22164                 }
22165                 return _results;
22166                 break;
22167               default:
22168                 return self.unanticipatedError;
22169             }
22170           }
22171         });
22172       }
22173     };
22174     UberView.prototype.unanticipatedError = function(response) {
22175       return self.flash('error', response);
22176     };
22177     UberView.prototype.flash = function(type, text) {
22178       var $banner;
22179       $banner = $("." + type);
22180       $banner.find('p').text(text).end().css('border', '1px solid #999').animate({
22181         top: 0
22182       }, 500);
22183       return setTimeout(function() {
22184         return $banner.animate({
22185           top: -$banner.outerHeight()
22186         }, 500);
22187       }, 3000);
22188     };
22189     UberView.prototype.requireMaps = function(callback) {
22190       if (typeof google !== 'undefined' && google.maps) {
22191         return callback();
22192       } else {
22193         return $.getScript("https://www.google.com/jsapi?key=" + CONFIG.googleJsApiKey, function() {
22194           return google.load('maps', 3, {
22195             callback: callback,
22196             other_params: 'sensor=false&language=en'
22197           });
22198         });
22199       }
22200     };
22201     UberView.prototype.select_drop_down = function(model, key) {
22202       var value;
22203       value = model.get(key);
22204       if (value) {
22205         return $("select[id='" + key + "'] option[value='" + value + "']").attr('selected', 'selected');
22206       }
22207     };
22208     UberView.prototype.processDocumentUpload = function(e) {
22209       var $fi, $form, arbData, curDate, data, expDate, expM, expY, expiration, fileElementId, invalid;
22210       e.preventDefault();
22211       $form = $(e.currentTarget);
22212       $fi = $("input[type=file]", $form);
22213       $(".validationError").removeClass("validationError");
22214       if (!$fi.val()) {
22215         return $fi.addClass("validationError");
22216       } else {
22217         fileElementId = $fi.attr('id');
22218         expY = $("select[name=expiration-year]", $form).val();
22219         expM = $("select[name=expiration-month]", $form).val();
22220         invalid = false;
22221         if (expY && expM) {
22222           expDate = new Date(expY, expM, 28);
22223           curDate = new Date();
22224           if (expDate < curDate) {
22225             invalid = true;
22226             $(".expiration", $form).addClass("validationError");
22227           }
22228           expiration = "" + expY + "-" + expM + "-28T23:59:59Z";
22229         }
22230         arbData = {};
22231         $(".arbitraryField", $form).each(__bind(function(i, e) {
22232           arbData[$(e).attr('name')] = $(e).val();
22233           if ($(e).val() === "") {
22234             invalid = true;
22235             return $(e).addClass("validationError");
22236           }
22237         }, this));
22238         if (!invalid) {
22239           data = {
22240             token: $.cookie('token') || USER.get('token'),
22241             name: $("input[name=fileName]", $form).val(),
22242             meta: escape(JSON.stringify(arbData)),
22243             user_id: $("input[name=driver_id]", $form).val(),
22244             vehicle_id: $("input[name=vehicle_id]", $form).val()
22245           };
22246           if (expiration) {
22247             data['expiration'] = expiration;
22248           }
22249           $("#spinner").show();
22250           return $.ajaxFileUpload({
22251             url: '/api/documents',
22252             secureuri: false,
22253             fileElementId: fileElementId,
22254             data: data,
22255             complete: __bind(function(resp, status) {
22256               var key, _i, _len, _ref, _results;
22257               $("#spinner").hide();
22258               if (status === "success") {
22259                 if (this.model) {
22260                   this.model.refetch();
22261                 } else {
22262                   USER.refetch();
22263                 }
22264               }
22265               if (status === "error") {
22266                 _ref = _.keys(resp);
22267                 _results = [];
22268                 for (_i = 0, _len = _ref.length; _i < _len; _i++) {
22269                   key = _ref[_i];
22270                   _results.push($("*[name=" + key + "]", $form).addClass("validationError"));
22271                 }
22272                 return _results;
22273               }
22274             }, this)
22275           });
22276         }
22277       }
22278     };
22279     return UberView;
22280   })();
22281 }).call(this);
22282 }, "web-lib/views/footer": function(exports, require, module) {(function() {
22283   var footerTemplate;
22284   var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
22285     for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
22286     function ctor() { this.constructor = child; }
22287     ctor.prototype = parent.prototype;
22288     child.prototype = new ctor;
22289     child.__super__ = parent.prototype;
22290     return child;
22291   };
22292   footerTemplate = require('web-lib/templates/footer');
22293   exports.SharedFooterView = (function() {
22294     __extends(SharedFooterView, Backbone.View);
22295     function SharedFooterView() {
22296       SharedFooterView.__super__.constructor.apply(this, arguments);
22297     }
22298     SharedFooterView.prototype.id = 'footer_view';
22299     SharedFooterView.prototype.events = {
22300       'click .language': 'intl_set_cookie_locale'
22301     };
22302     SharedFooterView.prototype.render = function() {
22303       $(this.el).html(footerTemplate());
22304       this.delegateEvents();
22305       return this;
22306     };
22307     SharedFooterView.prototype.intl_set_cookie_locale = function(e) {
22308       var _ref;
22309       i18n.setLocale(e != null ? (_ref = e.srcElement) != null ? _ref.id : void 0 : void 0);
22310       return location.reload();
22311     };
22312     return SharedFooterView;
22313   })();
22314 }).call(this);
22315 }});