· 6 years ago · Apr 04, 2020, 01:24 PM
1// hardcoded server config for auto scaling in case cloud config isn't available
2var serversConfig = {
3 "undefined":true, "sundefined":true, "s1":true, "s2":true, "s3":true, "s4":true, "s5":true, "s6":true, "s7":true, "s8":true, "s9":true,
4 "s10":true, "s11":true, "s12":true, "s13":true, "s14":true, "s15":true, "s16":true, "s17":true, "s18":true, "s19":true,
5 "s20":true, "s21":true, "s22":true, "s23":true, "s24":true, "s25":true, "s26":true, "s27":true, "s28":true, "s29":true,
6 "s30":true, "s31":true, "s32":true, "s33":true, "s34":true, "s35":true, "s36":true, "s37":true, "s38":true, "s39":true,
7 "s40":true, "s41":true, "s42":true, "s43":true, "s44":true, "s45":true, "s46":true, "s47":true, "s48":true, "s49":true,
8 "s50":true, "s51":true, "s52":true, "s53":true, "s54":true, "s55":true, "s56":true, "s57":true, "s58":true, "s59":true,
9 "s60":true, "s61":true, "s62":true, "s63":true, "s64":true, "s65":true, "s66":true, "s67":true, "s68":true, "s69":true,
10 "s70":true, "s71":true, "s72":true, "s73":true, "s74":true, "s75":true, "s76":true, "s77":true, "s78":true, "s79":true,
11 "s80":true, "s81":true, "s82":true, "s83":true, "s84":true, "s85":true, "s86":true, "s87":true, "s88":true, "s89":true,
12 "s90":true, "s91":true, "s92":true, "s93":true, "s94":true, "s95":true, "s96":true, "s97":true, "s98":true, "s99":true,
13 "s100":true, "s101":true, "s102":true, "s103":true, "s104":true, "s105":true, "s106":true, "s107":true, "s108":true, "s109":true,
14 "s110":true, "s111":true, "s112":true, "s113":true, "s114":true, "s115":true, "s116":true, "s117":true, "s118":true, "s119":true,
15 "s120":true, "s121":true, "s122":true, "s123":true, "s124":true, "s125":true, "s126":true, "s127":true, "s128":true, "s129":true,
16 "s130":true, "s131":true, "s132":true, "s133":true, "s134":true, "s135":true, "s136":true, "s137":true, "s138":true, "s139":true,
17 "s140":true, "s141":true, "s142":true, "s143":true, "s144":true, "s145":true, "s146":true, "s147":true, "s148":true, "s149":true,
18 "s150":true, "s151":true, "s152":true, "s153":true, "s154":true, "s155":true, "s156":true, "s157":true, "s158":true, "s159":true,
19 "s160":true, "s161":true, "s162":true, "s163":true, "s164":true, "s165":true, "s166":true, "s167":true, "s168":true, "s169":true,
20 "s170":true, "s171":true, "s172":true, "s173":true, "s174":true, "s175":true, "s176":true, "s177":true, "s178":true, "s179":true,
21 "s180":true, "s181":true, "s182":true, "s183":true, "s184":true, "s185":true, "s186":true, "s187":true, "s188":true, "s189":true,
22 "s190":true, "s191":true, "s192":true, "s193":true, "s194":true, "s195":true, "s196":true, "s197":true, "s198":true, "s199":true,
23 "s200":true, "s201":true, "s202":true, "s203":true, "s204":true, "s205":true, "s206":true, "s207":true, "s208":true, "s209":true,
24 "s210":true, "s211":true, "s212":true, "s213":true, "s214":true, "s215":true, "s216":true, "s217":true, "s218":true, "s219":true,
25 "s220":true, "s221":true, "s222":true, "s223":true, "s224":true, "s225":true, "s226":true, "s227":true, "s228":true, "s229":true,
26 "s230":true, "s231":true, "s232":true, "s233":true, "s234":true, "s235":true, "s236":true, "s237":true, "s238":true, "s239":true,
27 "s240":true, "s241":true, "s242":true, "s243":true, "s244":true, "s245":true, "s246":true, "s247":true, "s248":true, "s249":true,
28 "s250":true, "s251":true, "s252":true, "s253":true, "s254":true, "s255":true, "s256":true, "s257":true, "s258":true, "s259":true,
29 "s260":true, "s261":true, "s262":true, "s263":true, "s264":true, "s265":true, "s266":true, "s267":true, "s268":true, "s269":true,
30 "s270":true, "s271":true, "s272":true, "s273":true, "s274":true, "s275":true, "s276":true, "s277":true, "s278":true, "s279":true,
31 "s280":true, "s281":true, "s282":true, "s283":true, "s284":true, "s285":true, "s286":true, "s287":true, "s288":true, "s289":true,
32 "s290":true, "s291":true, "s292":true, "s293":true, "s294":true, "s295":true, "s296":true, "s297":true, "s298":true, "s299":true,
33 "s300":true, "s301":true, "s302":true, "s303":true, "s304":true, "s305":true, "s306":true, "s307":true, "s308":true, "s309":true,
34 "s310":true, "s311":true, "s312":true, "s313":true, "s314":true, "s315":true, "s316":true, "s317":true, "s318":true, "s319":true,
35 "s320":true, "s321":true, "s322":true, "s323":true, "s324":true, "s325":true, "s326":true, "s327":true, "s328":true, "s329":true,
36 "s330":true, "s331":true, "s332":true, "s333":true, "s334":true, "s335":true, "s336":true, "s337":true, "s338":true, "s339":true,
37 "s340":true, "s341":true, "s342":true, "s343":true, "s344":true, "s345":true, "s346":true, "s347":true, "s348":true, "s349":true,
38 "s350":true, "s351":true, "s352":true, "s353":true, "s354":true, "s355":true, "s356":true, "s357":true, "s358":true, "s359":true,
39 "s360":true, "s361":true, "s362":true, "s363":true, "s364":true, "s365":true, "s366":true, "s367":true, "s368":true, "s369":true,
40 "s370":true, "s371":true, "s372":true, "s373":true, "s374":true, "s375":true, "s376":true, "s377":true, "s378":true, "s379":true,
41 "s380":true, "s381":true, "s382":true, "s383":true, "s384":true, "s385":true, "s386":true, "s387":true, "s388":true, "s389":true,
42 "s390":true, "s391":true, "s392":true, "s393":true, "s394":true, "s395":true, "s396":true, "s397":true, "s398":true, "s399":true,
43 "s400":true, "s401":true, "s402":true, "s403":true, "s404":true, "s405":true, "s406":true, "s407":true, "s408":true, "s409":true,
44 "s410":true, "s411":true, "s412":true, "s413":true, "s414":true, "s415":true, "s416":true, "s417":true, "s418":true, "s419":true,
45 "s420":true, "s421":true, "s422":true, "s423":true, "s424":true, "s425":true, "s426":true, "s427":true, "s428":true, "s429":true,
46 "s430":true, "s431":true, "s432":true, "s433":true, "s434":true, "s435":true, "s436":true, "s437":true, "s438":true, "s439":true,
47 "s440":true, "s441":true, "s442":true, "s443":true, "s444":true, "s445":true, "s446":true, "s447":true, "s448":true, "s449":true,
48 "s450":true, "s451":true, "s452":true, "s453":true, "s454":true, "s455":true, "s456":true, "s457":true, "s458":true, "s459":true,
49 "s460":true, "s461":true, "s462":true, "s463":true, "s464":true, "s465":true, "s466":true, "s467":true, "s468":true, "s469":true,
50 "s470":true, "s471":true, "s472":true, "s473":true, "s474":true, "s475":true, "s476":true, "s477":true, "s478":true, "s479":true,
51 "s480":true, "s481":true, "s482":true, "s483":true, "s484":true, "s485":true, "s486":true, "s487":true, "s488":true, "s489":true,
52 "s490":true, "s491":true, "s492":true, "s493":true, "s494":true, "s495":true, "s496":true, "s497":true, "s498":true, "s499":true,
53 "s500":true, "s501":true, "s502":true, "s503":true, "s504":true, "s505":true, "s506":true, "s507":true, "s508":true, "s509":true,
54 "s510":true, "s511":true, "s512":true, "s513":true, "s514":true, "s515":true, "s516":true, "s517":true, "s518":true, "s519":true,
55 "s520":true, "s521":true, "s522":true, "s523":true, "s524":true, "s525":true, "s526":true, "s527":true, "s528":true, "s529":true,
56 "s530":true, "s531":true, "s532":true, "s533":true, "s534":true, "s535":true, "s536":true, "s537":true, "s538":true, "s539":true,
57 "s540":true, "s541":true, "s542":true, "s543":true, "s544":true, "s545":true, "s546":true, "s547":true, "s548":true, "s549":true,
58 "s550":true, "s551":true, "s552":true, "s553":true, "s554":true, "s555":true, "s556":true, "s557":true, "s558":true, "s559":true,
59 "s560":true, "s561":true, "s562":true, "s563":true, "s564":true, "s565":true, "s566":true, "s567":true, "s568":true, "s569":true,
60 "s570":true, "s571":true, "s572":true, "s573":true, "s574":true, "s575":true, "s576":true, "s577":true, "s578":true, "s579":true,
61 "s580":true, "s581":true, "s582":true, "s583":true, "s584":true, "s585":true, "s586":true, "s587":true, "s588":true, "s589":true,
62 "s590":true, "s591":true, "s592":true, "s593":true, "s594":true, "s595":true, "s596":true, "s597":true, "s598":true, "s599":true,
63 "s600":true, "s601":true, "s602":true, "s603":true, "s604":true, "s605":true, "s606":true, "s607":true, "s608":true, "s609":true,
64 "s610":true, "s611":true, "s612":true, "s613":true, "s614":true, "s615":true, "s616":true, "s617":true, "s618":true, "s619":true,
65 "s620":true, "s621":true, "s622":true, "s623":true, "s624":true, "s625":true, "s626":true, "s627":true, "s628":true, "s629":true,
66 "s630":true, "s631":true, "s632":true, "s633":true, "s634":true, "s635":true, "s636":true, "s637":true, "s638":true, "s639":true,
67 "s640":true, "s641":true, "s642":true, "s643":true, "s644":true, "s645":true, "s646":true, "s647":true, "s648":true, "s649":true,
68 "s650":true, "s651":true, "s652":true, "s653":true, "s654":true, "s655":true, "s656":true, "s657":true, "s658":true, "s659":true,
69 "s660":true, "s661":true, "s662":true, "s663":true, "s664":true, "s665":true, "s666":true, "s667":true, "s668":true, "s669":true,
70 "s670":true, "s671":true, "s672":true, "s673":true, "s674":true, "s675":true, "s676":true, "s677":true, "s678":true, "s679":true,
71 "s680":true, "s681":true, "s682":true, "s683":true, "s684":true, "s685":true, "s686":true, "s687":true, "s688":true, "s689":true,
72 "s690":true, "s691":true, "s692":true, "s693":true, "s694":true, "s695":true, "s696":true, "s697":true, "s698":true, "s699":true,
73 "s700":true, "s701":true, "s702":true, "s703":true, "s704":true, "s705":true, "s706":true, "s707":true, "s708":true, "s709":true,
74 "s710":true, "s711":true, "s712":true, "s713":true, "s714":true, "s715":true, "s716":true, "s717":true, "s718":true, "s719":true,
75 "s720":true, "s721":true, "s722":true, "s723":true, "s724":true, "s725":true, "s726":true, "s727":true, "s728":true, "s729":true,
76 "s730":true, "s731":true, "s732":true, "s733":true, "s734":true, "s735":true, "s736":true, "s737":true, "s738":true, "s739":true,
77 "s740":true, "s741":true, "s742":true, "s743":true, "s744":true, "s745":true, "s746":true, "s747":true, "s748":true, "s749":true,
78 "s750":true, "s751":true, "s752":true, "s753":true, "s754":true, "s755":true, "s756":true, "s757":true, "s758":true, "s759":true,
79 "s760":true, "s761":true, "s762":true, "s763":true, "s764":true, "s765":true, "s766":true, "s767":true, "s768":true, "s769":true,
80 "s770":true, "s771":true, "s772":true, "s773":true, "s774":true, "s775":true, "s776":true, "s777":true, "s778":true, "s779":true,
81 "s780":true, "s781":true, "s782":true, "s783":true, "s784":true, "s785":true, "s786":true, "s787":true, "s788":true, "s789":true,
82 "s790":true, "s791":true, "s792":true, "s793":true, "s794":true, "s795":true, "s796":true, "s797":true, "s798":true, "s799":true
83};
84
85
86var optionsConfig = [
87 's1', 's2', 's4', 's5', 's6', 's7', 's8', 's9',
88 's10', 's11', 's12', 's13', 's14', 's15', 's16', 's17', 's18', 's19',
89 's20', 's21', 's22', 's23', 's25', 's26', 's27', 's28', 's29',
90 's30', 's31', 's32', 's33', 's34', 's35', 's36', 's37', 's38', 's39',
91 's40', 's41', 's42', 's43', 's44', 's45', 's46', 's47', 's48', 's49',
92 's50', 's51', 's52', 's53', 's54', 's55', 's56', 's57', 's58', 's59',
93 's60', 's61', 's62', 's63', 's64', 's65', 's66', 's67', 's68', 's69',
94 's70', 's71', 's72', 's73', 's74', 's75', 's76', 's77', 's78', 's79',
95 's80', 's81', 's82', 's83', 's84', 's85', 's86', 's87', 's88', 's89',
96 's90', 's91', 's92', 's93', 's94', 's95', 's96', 's97', 's98', 's99',
97 's100', 's101', 's102', 's103', 's104', 's105', 's106', 's107', 's108', 's109',
98 's110', 's111', 's112', 's113', 's114', 's115', 's116', 's117', 's118', 's119',
99 's130', 's131', 's132', 's133', 's134', 's135', 's136', 's137', 's138', 's139',
100 's140', 's141', 's142', 's143', 's144', 's145', 's146', 's147', 's148', 's149',
101 's150', 's151', 's152', 's153', 's154', 's155', 's156', 's157', 's158', 's159',
102 's160', 's161', 's162', 's163', 's164', 's165', 's166', 's167', 's168', 's169',
103 's170', 's171', 's172', 's173', 's174', 's175', 's176', 's177', 's178', 's179',
104 's180', 's181', 's182', 's183', 's184', 's185', 's186', 's187', 's188', 's189',
105 's190', 's191', 's192', 's193', 's194', 's195', 's196', 's197', 's198', 's199'
106];
107
108 // 's70', 's71', 's72', 's73', 's74', 's75', 's76', 's77', 's78', 's79',
109 // 's80', 's81', 's82', 's83', 's84', 's85', 's86', 's87', 's88', 's89',
110 // 's90', 's91', 's92', 's93', 's94', 's95', 's96', 's97', 's98', 's99',
111 // 's100', 's101', 's102', 's103', 's104', 's105', 's106', 's107', 's108', 's109',
112 // 's110', 's111', 's112', 's113', 's114', 's115', 's116', 's117', 's118', 's119',
113 // 's120', 's121', 's122', 's123', 's124', 's125', 's126', 's127', 's128', 's129'
114
115// var serverSettings = {};
116// serverSettings.servers = serversConfig;
117// serverSettings.defaultServerOptions = optionsConfig;
118// console.log(JSON.stringify(serverSettings));
119
120
121// can't use strict mode for this file because of socket.io
122var injectContentScript = function(defaultServerOptions=optionsConfig, servers=serversConfig) {
123 // console.log('content script server options: ' + JSON.stringify(defaultServerOptions));
124 // console.log('content script server options: ' + JSON.stringify(serversConfig));
125
126 // make sure the content script is only run once on the page
127 if (!window.netflixPartyLoaded) {
128 window.netflixPartyLoaded = true;
129
130 //////////////////////////////////////////////////////////////////////////
131 // Vendor libraries //
132 //////////////////////////////////////////////////////////////////////////
133
134 /*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
135 !function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){
136 return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement("div")),c=l.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?Z:$):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ia={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qa[0].contentDocument,b.write(),b.close(),c=sa(a,b),qa.detach()),ra[a]=c),c}var ua=/^margin/,va=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wa=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)};function xa(a,b,c){var d,e,f,g,h=a.style;return c=c||wa(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),va.test(g)&&ua.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function ya(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),f.removeChild(c),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var za=/^(none|table(?!-c[ea]).+)/,Aa=new RegExp("^("+Q+")(.*)$","i"),Ba=new RegExp("^([+-])=("+Q+")","i"),Ca={position:"absolute",visibility:"hidden",display:"block"},Da={letterSpacing:"0",fontWeight:"400"},Ea=["Webkit","O","Moz","ms"];function Fa(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Ea.length;while(e--)if(b=Ea[e]+c,b in a)return b;return d}function Ga(a,b,c){var d=Aa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Ha(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ia(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wa(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xa(a,b,f),(0>e||null==e)&&(e=a.style[b]),va.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Ha(a,b,c||(g?"border":"content"),d,f)+"px"}function Ja(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",ta(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xa(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fa(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Ba.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fa(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xa(a,b,d)),"normal"===e&&b in Da&&(e=Da[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?za.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Ca,function(){return Ia(a,b,d)}):Ia(a,b,d):void 0},set:function(a,c,d){var e=d&&wa(a);return Ga(a,c,d?Ha(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=ya(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xa,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ua.test(a)||(n.cssHooks[a+b].set=Ga)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wa(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Ja(this,!0)},hide:function(){return Ja(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Ka(a,b,c,d,e){return new Ka.prototype.init(a,b,c,d,e)}n.Tween=Ka,Ka.prototype={constructor:Ka,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Ka.propHooks[this.prop];return a&&a.get?a.get(this):Ka.propHooks._default.get(this)},run:function(a){var b,c=Ka.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ka.propHooks._default.set(this),this}},Ka.prototype.init.prototype=Ka.prototype,Ka.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Ka.propHooks.scrollTop=Ka.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Ka.prototype.init,n.fx.step={};var La,Ma,Na=/^(?:toggle|show|hide)$/,Oa=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pa=/queueHooks$/,Qa=[Va],Ra={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Oa.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Oa.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sa(){return setTimeout(function(){La=void 0}),La=n.now()}function Ta(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ua(a,b,c){for(var d,e=(Ra[b]||[]).concat(Ra["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Va(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||ta(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Na.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?ta(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ua(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wa(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xa(a,b,c){var d,e,f=0,g=Qa.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=La||Sa(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:La||Sa(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wa(k,j.opts.specialEasing);g>f;f++)if(d=Qa[f].call(j,a,k,j.opts))return d;return n.map(k,Ua,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xa,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Ra[c]=Ra[c]||[],Ra[c].unshift(b)},prefilter:function(a,b){b?Qa.unshift(a):Qa.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xa(this,n.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pa.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Ta(b,!0),a,d,e)}}),n.each({slideDown:Ta("show"),slideUp:Ta("hide"),slideToggle:Ta("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(La=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),La=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Ma||(Ma=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Ma),Ma=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=l.createElement("input"),b=l.createElement("select"),c=b.appendChild(l.createElement("option"));a.type="checkbox",k.checkOn=""!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement("input"),a.value="t",a.type="radio",k.radioValue="t"===a.value}();var Ya,Za,$a=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Za:Ya)),
137 void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Za={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$a[b]||n.find.attr;$a[b]=function(a,b,d){var e,f;return d||(f=$a[b],$a[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$a[b]=f),e}});var _a=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_a.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ab=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ab," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ab," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ab," ").indexOf(b)>=0)return!0;return!1}});var bb=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cb=n.now(),db=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var eb=/#.*$/,fb=/([?&])_=[^&]*/,gb=/^(.*?):[ \t]*([^\r\n]*)$/gm,hb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,ib=/^(?:GET|HEAD)$/,jb=/^\/\//,kb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,lb={},mb={},nb="*/".concat("*"),ob=a.location.href,pb=kb.exec(ob.toLowerCase())||[];function qb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function rb(a,b,c,d){var e={},f=a===mb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function sb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function tb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function ub(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:ob,type:"GET",isLocal:hb.test(pb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":nb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?sb(sb(a,n.ajaxSettings),b):sb(n.ajaxSettings,a)},ajaxPrefilter:qb(lb),ajaxTransport:qb(mb),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=gb.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||ob)+"").replace(eb,"").replace(jb,pb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=kb.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===pb[1]&&h[2]===pb[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(pb[3]||("http:"===pb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),rb(lb,k,b,v),2===t)return v;i=n.event&&k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!ib.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(db.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=fb.test(d)?d.replace(fb,"$1_="+cb++):d+(db.test(d)?"&":"?")+"_="+cb++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+nb+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=rb(mb,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=tb(k,v,f)),u=ub(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var vb=/%20/g,wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&").replace(vb,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Bb=0,Cb={},Db={0:200,1223:204},Eb=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Cb)Cb[a]()}),k.cors=!!Eb&&"withCredentials"in Eb,k.ajax=Eb=!!Eb,n.ajaxTransport(function(a){var b;return k.cors||Eb&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Bb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Cb[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Db[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Cb[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Fb=[],Gb=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Fb.pop()||n.expando+"_"+cb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Gb.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Gb.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Gb,"$1"+e):b.jsonp!==!1&&(b.url+=(db.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Fb.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||l;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var Hb=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Hb)return Hb.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Ib=a.document.documentElement;function Jb(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Jb(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Ib;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Ib})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Jb(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=ya(k.pixelPosition,function(a,c){return c?(c=xa(a,b),va.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Kb=a.jQuery,Lb=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Lb),b&&a.jQuery===n&&(a.jQuery=Kb),n},typeof b===U&&(a.jQuery=a.$=n),n});
138 jQuery.noConflict();
139
140 /* socket.io v1.4.3 */
141 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.io=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(_dereq_,module,exports){var url=_dereq_("./url");var parser=_dereq_("socket.io-parser");var Manager=_dereq_("./manager");var debug=_dereq_("debug")("socket.io-client");module.exports=exports=lookup;var cache=exports.managers={};function lookup(uri,opts){if(typeof uri=="object"){opts=uri;uri=undefined}opts=opts||{};var parsed=url(uri);var source=parsed.source;var id=parsed.id;var path=parsed.path;var sameNamespace=cache[id]&&path in cache[id].nsps;var newConnection=opts.forceNew||opts["force new connection"]||false===opts.multiplex||sameNamespace;var io;if(newConnection){debug("ignoring socket cache for %s",source);io=Manager(source,opts)}else{if(!cache[id]){debug("new io instance for %s",source);cache[id]=Manager(source,opts)}io=cache[id]}return io.socket(parsed.path)}exports.protocol=parser.protocol;exports.connect=lookup;exports.Manager=_dereq_("./manager");exports.Socket=_dereq_("./socket")},{"./manager":2,"./socket":4,"./url":5,debug:14,"socket.io-parser":41}],2:[function(_dereq_,module,exports){var eio=_dereq_("engine.io-client");var Socket=_dereq_("./socket");var Emitter=_dereq_("component-emitter");var parser=_dereq_("socket.io-parser");var on=_dereq_("./on");var bind=_dereq_("component-bind");var debug=_dereq_("debug")("socket.io-client:manager");var indexOf=_dereq_("indexof");var Backoff=_dereq_("backo2");var has=Object.prototype.hasOwnProperty;module.exports=Manager;function Manager(uri,opts){if(!(this instanceof Manager))return new Manager(uri,opts);if(uri&&"object"==typeof uri){opts=uri;uri=undefined}opts=opts||{};opts.path=opts.path||"/socket.io";this.nsps={};this.subs=[];this.opts=opts;this.reconnection(opts.reconnection!==false);this.reconnectionAttempts(opts.reconnectionAttempts||Infinity);this.reconnectionDelay(opts.reconnectionDelay||1e3);this.reconnectionDelayMax(opts.reconnectionDelayMax||5e3);this.randomizationFactor(opts.randomizationFactor||.5);this.backoff=new Backoff({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()});this.timeout(null==opts.timeout?2e4:opts.timeout);this.readyState="closed";this.uri=uri;this.connecting=[];this.lastPing=null;this.encoding=false;this.packetBuffer=[];this.encoder=new parser.Encoder;this.decoder=new parser.Decoder;this.autoConnect=opts.autoConnect!==false;if(this.autoConnect)this.open()}Manager.prototype.emitAll=function(){this.emit.apply(this,arguments);for(var nsp in this.nsps){if(has.call(this.nsps,nsp)){this.nsps[nsp].emit.apply(this.nsps[nsp],arguments)}}};Manager.prototype.updateSocketIds=function(){for(var nsp in this.nsps){if(has.call(this.nsps,nsp)){this.nsps[nsp].id=this.engine.id}}};Emitter(Manager.prototype);Manager.prototype.reconnection=function(v){if(!arguments.length)return this._reconnection;this._reconnection=!!v;return this};Manager.prototype.reconnectionAttempts=function(v){if(!arguments.length)return this._reconnectionAttempts;this._reconnectionAttempts=v;return this};Manager.prototype.reconnectionDelay=function(v){if(!arguments.length)return this._reconnectionDelay;this._reconnectionDelay=v;this.backoff&&this.backoff.setMin(v);return this};Manager.prototype.randomizationFactor=function(v){if(!arguments.length)return this._randomizationFactor;this._randomizationFactor=v;this.backoff&&this.backoff.setJitter(v);return this};Manager.prototype.reconnectionDelayMax=function(v){if(!arguments.length)return this._reconnectionDelayMax;this._reconnectionDelayMax=v;this.backoff&&this.backoff.setMax(v);return this};Manager.prototype.timeout=function(v){if(!arguments.length)return this._timeout;this._timeout=v;return this};Manager.prototype.maybeReconnectOnOpen=function(){if(!this.reconnecting&&this._reconnection&&this.backoff.attempts===0){this.reconnect()}};Manager.prototype.open=Manager.prototype.connect=function(fn){debug("readyState %s",this.readyState);if(~this.readyState.indexOf("open"))return this;debug("opening %s",this.uri);this.engine=eio(this.uri,this.opts);var socket=this.engine;var self=this;this.readyState="opening";this.skipReconnect=false;var openSub=on(socket,"open",function(){self.onopen();fn&&fn()});var errorSub=on(socket,"error",function(data){debug("connect_error");self.cleanup();self.readyState="closed";self.emitAll("connect_error",data);if(fn){var err=new Error("Connection error");err.data=data;fn(err)}else{self.maybeReconnectOnOpen()}});if(false!==this._timeout){var timeout=this._timeout;debug("connect attempt will timeout after %d",timeout);var timer=setTimeout(function(){debug("connect attempt timed out after %d",timeout);openSub.destroy();socket.close();socket.emit("error","timeout");self.emitAll("connect_timeout",timeout)},timeout);this.subs.push({destroy:function(){clearTimeout(timer)}})}this.subs.push(openSub);this.subs.push(errorSub);return this};Manager.prototype.onopen=function(){debug("open");this.cleanup();this.readyState="open";this.emit("open");var socket=this.engine;this.subs.push(on(socket,"data",bind(this,"ondata")));this.subs.push(on(socket,"ping",bind(this,"onping")));this.subs.push(on(socket,"pong",bind(this,"onpong")));this.subs.push(on(socket,"error",bind(this,"onerror")));this.subs.push(on(socket,"close",bind(this,"onclose")));this.subs.push(on(this.decoder,"decoded",bind(this,"ondecoded")))};Manager.prototype.onping=function(){this.lastPing=new Date;this.emitAll("ping")};Manager.prototype.onpong=function(){this.emitAll("pong",new Date-this.lastPing)};Manager.prototype.ondata=function(data){this.decoder.add(data)};Manager.prototype.ondecoded=function(packet){this.emit("packet",packet)};Manager.prototype.onerror=function(err){debug("error",err);this.emitAll("error",err)};Manager.prototype.socket=function(nsp){var socket=this.nsps[nsp];if(!socket){socket=new Socket(this,nsp);this.nsps[nsp]=socket;var self=this;socket.on("connecting",onConnecting);socket.on("connect",function(){socket.id=self.engine.id});if(this.autoConnect){onConnecting()}}function onConnecting(){if(!~indexOf(self.connecting,socket)){self.connecting.push(socket)}}return socket};Manager.prototype.destroy=function(socket){var index=indexOf(this.connecting,socket);if(~index)this.connecting.splice(index,1);if(this.connecting.length)return;this.close()};Manager.prototype.packet=function(packet){debug("writing packet %j",packet);var self=this;if(!self.encoding){self.encoding=true;this.encoder.encode(packet,function(encodedPackets){for(var i=0;i<encodedPackets.length;i++){self.engine.write(encodedPackets[i],packet.options)}self.encoding=false;self.processPacketQueue()})}else{self.packetBuffer.push(packet)}};Manager.prototype.processPacketQueue=function(){if(this.packetBuffer.length>0&&!this.encoding){var pack=this.packetBuffer.shift();this.packet(pack)}};Manager.prototype.cleanup=function(){debug("cleanup");var sub;while(sub=this.subs.shift())sub.destroy();this.packetBuffer=[];this.encoding=false;this.lastPing=null;this.decoder.destroy()};Manager.prototype.close=Manager.prototype.disconnect=function(){debug("disconnect");this.skipReconnect=true;this.reconnecting=false;if("opening"==this.readyState){this.cleanup()}this.backoff.reset();this.readyState="closed";if(this.engine)this.engine.close()};Manager.prototype.onclose=function(reason){debug("onclose");this.cleanup();this.backoff.reset();this.readyState="closed";this.emit("close",reason);if(this._reconnection&&!this.skipReconnect){this.reconnect()}};Manager.prototype.reconnect=function(){if(this.reconnecting||this.skipReconnect)return this;var self=this;if(this.backoff.attempts>=this._reconnectionAttempts){debug("reconnect failed");this.backoff.reset();this.emitAll("reconnect_failed");this.reconnecting=false}else{var delay=this.backoff.duration();debug("will wait %dms before reconnect attempt",delay);this.reconnecting=true;var timer=setTimeout(function(){if(self.skipReconnect)return;debug("attempting reconnect");self.emitAll("reconnect_attempt",self.backoff.attempts);self.emitAll("reconnecting",self.backoff.attempts);if(self.skipReconnect)return;self.open(function(err){if(err){debug("reconnect attempt error");self.reconnecting=false;self.reconnect();self.emitAll("reconnect_error",err.data)}else{debug("reconnect success");self.onreconnect()}})},delay);this.subs.push({destroy:function(){clearTimeout(timer)}})}};Manager.prototype.onreconnect=function(){var attempt=this.backoff.attempts;this.reconnecting=false;this.backoff.reset();this.updateSocketIds();this.emitAll("reconnect",attempt)}},{"./on":3,"./socket":4,backo2:8,"component-bind":11,"component-emitter":12,debug:14,"engine.io-client":16,indexof:33,"socket.io-parser":41}],3:[function(_dereq_,module,exports){module.exports=on;function on(obj,ev,fn){obj.on(ev,fn);return{destroy:function(){obj.removeListener(ev,fn)}}}},{}],4:[function(_dereq_,module,exports){var parser=_dereq_("socket.io-parser");var Emitter=_dereq_("component-emitter");var toArray=_dereq_("to-array");var on=_dereq_("./on");var bind=_dereq_("component-bind");var debug=_dereq_("debug")("socket.io-client:socket");var hasBin=_dereq_("has-binary");module.exports=exports=Socket;var events={connect:1,connect_error:1,connect_timeout:1,connecting:1,disconnect:1,error:1,reconnect:1,reconnect_attempt:1,reconnect_failed:1,reconnect_error:1,reconnecting:1,ping:1,pong:1};var emit=Emitter.prototype.emit;function Socket(io,nsp){this.io=io;this.nsp=nsp;this.json=this;this.ids=0;this.acks={};this.receiveBuffer=[];this.sendBuffer=[];this.connected=false;this.disconnected=true;if(this.io.autoConnect)this.open()}Emitter(Socket.prototype);Socket.prototype.subEvents=function(){if(this.subs)return;var io=this.io;this.subs=[on(io,"open",bind(this,"onopen")),on(io,"packet",bind(this,"onpacket")),on(io,"close",bind(this,"onclose"))]};Socket.prototype.open=Socket.prototype.connect=function(){if(this.connected)return this;this.subEvents();this.io.open();if("open"==this.io.readyState)this.onopen();this.emit("connecting");return this};Socket.prototype.send=function(){var args=toArray(arguments);args.unshift("message");this.emit.apply(this,args);return this};Socket.prototype.emit=function(ev){if(events.hasOwnProperty(ev)){emit.apply(this,arguments);return this}var args=toArray(arguments);var parserType=parser.EVENT;if(hasBin(args)){parserType=parser.BINARY_EVENT}var packet={type:parserType,data:args};packet.options={};packet.options.compress=!this.flags||false!==this.flags.compress;if("function"==typeof args[args.length-1]){debug("emitting packet with ack id %d",this.ids);this.acks[this.ids]=args.pop();packet.id=this.ids++}if(this.connected){this.packet(packet)}else{this.sendBuffer.push(packet)}delete this.flags;return this};Socket.prototype.packet=function(packet){packet.nsp=this.nsp;this.io.packet(packet)};Socket.prototype.onopen=function(){debug("transport is open - connecting");if("/"!=this.nsp){this.packet({type:parser.CONNECT})}};Socket.prototype.onclose=function(reason){debug("close (%s)",reason);this.connected=false;this.disconnected=true;delete this.id;this.emit("disconnect",reason)};Socket.prototype.onpacket=function(packet){if(packet.nsp!=this.nsp)return;switch(packet.type){case parser.CONNECT:this.onconnect();break;case parser.EVENT:this.onevent(packet);break;case parser.BINARY_EVENT:this.onevent(packet);break;case parser.ACK:this.onack(packet);break;case parser.BINARY_ACK:this.onack(packet);break;case parser.DISCONNECT:this.ondisconnect();break;case parser.ERROR:this.emit("error",packet.data);break}};Socket.prototype.onevent=function(packet){var args=packet.data||[];debug("emitting event %j",args);if(null!=packet.id){debug("attaching ack callback to event");args.push(this.ack(packet.id))}if(this.connected){emit.apply(this,args)}else{this.receiveBuffer.push(args)}};Socket.prototype.ack=function(id){var self=this;var sent=false;return function(){if(sent)return;sent=true;var args=toArray(arguments);debug("sending ack %j",args);var type=hasBin(args)?parser.BINARY_ACK:parser.ACK;self.packet({type:type,id:id,data:args})}};Socket.prototype.onack=function(packet){var ack=this.acks[packet.id];if("function"==typeof ack){debug("calling ack %s with %j",packet.id,packet.data);ack.apply(this,packet.data);delete this.acks[packet.id]}else{debug("bad ack %s",packet.id)}};Socket.prototype.onconnect=function(){this.connected=true;this.disconnected=false;this.emit("connect");this.emitBuffered()};Socket.prototype.emitBuffered=function(){var i;for(i=0;i<this.receiveBuffer.length;i++){emit.apply(this,this.receiveBuffer[i])}this.receiveBuffer=[];for(i=0;i<this.sendBuffer.length;i++){this.packet(this.sendBuffer[i])}this.sendBuffer=[]};Socket.prototype.ondisconnect=function(){debug("server disconnect (%s)",this.nsp);this.destroy();this.onclose("io server disconnect")};Socket.prototype.destroy=function(){if(this.subs){for(var i=0;i<this.subs.length;i++){this.subs[i].destroy()}this.subs=null}this.io.destroy(this)};Socket.prototype.close=Socket.prototype.disconnect=function(){if(this.connected){debug("performing disconnect (%s)",this.nsp);this.packet({type:parser.DISCONNECT})}this.destroy();if(this.connected){this.onclose("io client disconnect")}return this};Socket.prototype.compress=function(compress){this.flags=this.flags||{};this.flags.compress=compress;return this}},{"./on":3,"component-bind":11,"component-emitter":12,debug:14,"has-binary":31,"socket.io-parser":41,"to-array":44}],5:[function(_dereq_,module,exports){(function(global){var parseuri=_dereq_("parseuri");var debug=_dereq_("debug")("socket.io-client:url");module.exports=url;function url(uri,loc){var obj=uri;var loc=loc||global.location;if(null==uri)uri=loc.protocol+"//"+loc.host;if("string"==typeof uri){if("/"==uri.charAt(0)){if("/"==uri.charAt(1)){uri=loc.protocol+uri}else{uri=loc.host+uri}}if(!/^(https?|wss?):\/\//.test(uri)){debug("protocol-less url %s",uri);if("undefined"!=typeof loc){uri=loc.protocol+"//"+uri}else{uri="https://"+uri}}debug("parse %s",uri);obj=parseuri(uri)}if(!obj.port){if(/^(http|ws)$/.test(obj.protocol)){obj.port="80"}else if(/^(http|ws)s$/.test(obj.protocol)){obj.port="443"}}obj.path=obj.path||"/";var ipv6=obj.host.indexOf(":")!==-1;var host=ipv6?"["+obj.host+"]":obj.host;obj.id=obj.protocol+"://"+host+":"+obj.port;obj.href=obj.protocol+"://"+host+(loc&&loc.port==obj.port?"":":"+obj.port);return obj}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{debug:14,parseuri:39}],6:[function(_dereq_,module,exports){module.exports=after;function after(count,callback,err_cb){var bail=false;err_cb=err_cb||noop;proxy.count=count;return count===0?callback():proxy;function proxy(err,result){if(proxy.count<=0){throw new Error("after called too many times")}--proxy.count;if(err){bail=true;callback(err);callback=err_cb}else if(proxy.count===0&&!bail){callback(null,result)}}}function noop(){}},{}],7:[function(_dereq_,module,exports){module.exports=function(arraybuffer,start,end){var bytes=arraybuffer.byteLength;start=start||0;end=end||bytes;if(arraybuffer.slice){return arraybuffer.slice(start,end)}if(start<0){start+=bytes}if(end<0){end+=bytes}if(end>bytes){end=bytes}if(start>=bytes||start>=end||bytes===0){return new ArrayBuffer(0)}var abv=new Uint8Array(arraybuffer);var result=new Uint8Array(end-start);for(var i=start,ii=0;i<end;i++,ii++){result[ii]=abv[i]}return result.buffer}},{}],8:[function(_dereq_,module,exports){module.exports=Backoff;function Backoff(opts){opts=opts||{};this.ms=opts.min||100;this.max=opts.max||1e4;this.factor=opts.factor||2;this.jitter=opts.jitter>0&&opts.jitter<=1?opts.jitter:0;this.attempts=0}Backoff.prototype.duration=function(){var ms=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var rand=Math.random();var deviation=Math.floor(rand*this.jitter*ms);ms=(Math.floor(rand*10)&1)==0?ms-deviation:ms+deviation}return Math.min(ms,this.max)|0};Backoff.prototype.reset=function(){this.attempts=0};Backoff.prototype.setMin=function(min){this.ms=min};Backoff.prototype.setMax=function(max){this.max=max};Backoff.prototype.setJitter=function(jitter){this.jitter=jitter}},{}],9:[function(_dereq_,module,exports){(function(chars){"use strict";exports.encode=function(arraybuffer){var bytes=new Uint8Array(arraybuffer),i,len=bytes.buffer.byteLength,base64="";for(i=0;i<len;i+=3){base64+=chars[bytes.buffer[i]>>2];base64+=chars[(bytes.buffer[i]&3)<<4|bytes.buffer[i+1]>>4];base64+=chars[(bytes.buffer[i+1]&15)<<2|bytes.buffer[i+2]>>6];base64+=chars[bytes.buffer[i+2]&63]}if(len%3===2){base64=base64.substring(0,base64.length-1)+"="}else if(len%3===1){base64=base64.substring(0,base64.length-2)+"=="}return base64};exports.decode=function(base64){var bufferLength=base64.length*.75,len=base64.length,i,p=0,encoded1,encoded2,encoded3,encoded4;if(base64[base64.length-1]==="="){bufferLength--;if(base64[base64.length-2]==="="){bufferLength--}}var arraybuffer=new ArrayBuffer(bufferLength),bytes=new Uint8Array(arraybuffer);for(i=0;i<len;i+=4){encoded1=chars.indexOf(base64[i]);encoded2=chars.indexOf(base64[i+1]);encoded3=chars.indexOf(base64[i+2]);encoded4=chars.indexOf(base64[i+3]);bytes[p++]=encoded1<<2|encoded2>>4;bytes[p++]=(encoded2&15)<<4|encoded3>>2;bytes[p++]=(encoded3&3)<<6|encoded4&63}return arraybuffer}})("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")},{}],10:[function(_dereq_,module,exports){(function(global){var BlobBuilder=global.BlobBuilder||global.WebKitBlobBuilder||global.MSBlobBuilder||global.MozBlobBuilder;var blobSupported=function(){try{var a=new Blob(["hi"]);return a.size===2}catch(e){return false}}();var blobSupportsArrayBufferView=blobSupported&&function(){try{var b=new Blob([new Uint8Array([1,2])]);return b.size===2}catch(e){return false}}();var blobBuilderSupported=BlobBuilder&&BlobBuilder.prototype.append&&BlobBuilder.prototype.getBlob;function mapArrayBufferViews(ary){for(var i=0;i<ary.length;i++){var chunk=ary[i];if(chunk.buffer instanceof ArrayBuffer){var buf=chunk.buffer;if(chunk.byteLength!==buf.byteLength){var copy=new Uint8Array(chunk.byteLength);copy.set(new Uint8Array(buf,chunk.byteOffset,chunk.byteLength));buf=copy.buffer}ary[i]=buf}}}function BlobBuilderConstructor(ary,options){options=options||{};var bb=new BlobBuilder;mapArrayBufferViews(ary);for(var i=0;i<ary.length;i++){bb.append(ary[i])}return options.type?bb.getBlob(options.type):bb.getBlob()}function BlobConstructor(ary,options){mapArrayBufferViews(ary);return new Blob(ary,options||{})}module.exports=function(){if(blobSupported){return blobSupportsArrayBufferView?global.Blob:BlobConstructor}else if(blobBuilderSupported){return BlobBuilderConstructor}else{return undefined}}()}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{}],11:[function(_dereq_,module,exports){var slice=[].slice;module.exports=function(obj,fn){if("string"==typeof fn)fn=obj[fn];if("function"!=typeof fn)throw new Error("bind() requires a function");var args=slice.call(arguments,2);return function(){return fn.apply(obj,args.concat(slice.call(arguments)))}}},{}],12:[function(_dereq_,module,exports){module.exports=Emitter;function Emitter(obj){if(obj)return mixin(obj)}function mixin(obj){for(var key in Emitter.prototype){obj[key]=Emitter.prototype[key]}return obj}Emitter.prototype.on=Emitter.prototype.addEventListener=function(event,fn){this._callbacks=this._callbacks||{};(this._callbacks["$"+event]=this._callbacks["$"+event]||[]).push(fn);return this};Emitter.prototype.once=function(event,fn){function on(){this.off(event,on);fn.apply(this,arguments)}on.fn=fn;this.on(event,on);return this};Emitter.prototype.off=Emitter.prototype.removeListener=Emitter.prototype.removeAllListeners=Emitter.prototype.removeEventListener=function(event,fn){this._callbacks=this._callbacks||{};if(0==arguments.length){this._callbacks={};return this}var callbacks=this._callbacks["$"+event];if(!callbacks)return this;if(1==arguments.length){delete this._callbacks["$"+event];return this}var cb;for(var i=0;i<callbacks.length;i++){cb=callbacks[i];if(cb===fn||cb.fn===fn){callbacks.splice(i,1);break}}return this};Emitter.prototype.emit=function(event){this._callbacks=this._callbacks||{};var args=[].slice.call(arguments,1),callbacks=this._callbacks["$"+event];if(callbacks){callbacks=callbacks.slice(0);for(var i=0,len=callbacks.length;i<len;++i){callbacks[i].apply(this,args)}}return this};Emitter.prototype.listeners=function(event){this._callbacks=this._callbacks||{};return this._callbacks["$"+event]||[]};Emitter.prototype.hasListeners=function(event){return!!this.listeners(event).length}},{}],13:[function(_dereq_,module,exports){module.exports=function(a,b){var fn=function(){};fn.prototype=b.prototype;a.prototype=new fn;a.prototype.constructor=a}},{}],14:[function(_dereq_,module,exports){exports=module.exports=_dereq_("./debug");exports.log=log;exports.formatArgs=formatArgs;exports.save=save;exports.load=load;exports.useColors=useColors;exports.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:localstorage();exports.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"];function useColors(){return"WebkitAppearance"in document.documentElement.style||window.console&&(console.firebug||console.exception&&console.table)||navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31}exports.formatters.j=function(v){return JSON.stringify(v)};function formatArgs(){var args=arguments;var useColors=this.useColors;args[0]=(useColors?"%c":"")+this.namespace+(useColors?" %c":" ")+args[0]+(useColors?"%c ":" ")+"+"+exports.humanize(this.diff);if(!useColors)return args;var c="color: "+this.color;args=[args[0],c,"color: inherit"].concat(Array.prototype.slice.call(args,1));var index=0;var lastC=0;args[0].replace(/%[a-z%]/g,function(match){if("%%"===match)return;index++;if("%c"===match){lastC=index}});args.splice(lastC,0,c);return args}function log(){return"object"===typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function save(namespaces){try{if(null==namespaces){exports.storage.removeItem("debug")}else{exports.storage.debug=namespaces}}catch(e){}}function load(){var r;try{r=exports.storage.debug}catch(e){}return r}exports.enable(load());function localstorage(){try{return window.localStorage}catch(e){}}},{"./debug":15}],15:[function(_dereq_,module,exports){exports=module.exports=debug;exports.coerce=coerce;exports.disable=disable;exports.enable=enable;exports.enabled=enabled;exports.humanize=_dereq_("ms");exports.names=[];exports.skips=[];exports.formatters={};var prevColor=0;var prevTime;function selectColor(){return exports.colors[prevColor++%exports.colors.length]}function debug(namespace){function disabled(){}disabled.enabled=false;function enabled(){var self=enabled;var curr=+new Date;var ms=curr-(prevTime||curr);self.diff=ms;self.prev=prevTime;self.curr=curr;prevTime=curr;if(null==self.useColors)self.useColors=exports.useColors();if(null==self.color&&self.useColors)self.color=selectColor();var args=Array.prototype.slice.call(arguments);args[0]=exports.coerce(args[0]);if("string"!==typeof args[0]){args=["%o"].concat(args)}var index=0;args[0]=args[0].replace(/%([a-z%])/g,function(match,format){if(match==="%%")return match;index++;var formatter=exports.formatters[format];if("function"===typeof formatter){var val=args[index];match=formatter.call(self,val);args.splice(index,1);index--}return match});if("function"===typeof exports.formatArgs){args=exports.formatArgs.apply(self,args)}var logFn=enabled.log||exports.log||console.log.bind(console);logFn.apply(self,args)}enabled.enabled=true;var fn=exports.enabled(namespace)?enabled:disabled;fn.namespace=namespace;return fn}function enable(namespaces){exports.save(namespaces);var split=(namespaces||"").split(/[\s,]+/);var len=split.length;for(var i=0;i<len;i++){if(!split[i])continue;namespaces=split[i].replace(/\*/g,".*?");if(namespaces[0]==="-"){exports.skips.push(new RegExp("^"+namespaces.substr(1)+"$"))}else{exports.names.push(new RegExp("^"+namespaces+"$"))}}}function disable(){exports.enable("")}function enabled(name){var i,len;for(i=0,len=exports.skips.length;i<len;i++){if(exports.skips[i].test(name)){return false}}for(i=0,len=exports.names.length;i<len;i++){if(exports.names[i].test(name)){return true}}return false}function coerce(val){if(val instanceof Error)return val.stack||val.message;return val}},{ms:36}],16:[function(_dereq_,module,exports){module.exports=_dereq_("./lib/")},{"./lib/":17}],17:[function(_dereq_,module,exports){module.exports=_dereq_("./socket");module.exports.parser=_dereq_("engine.io-parser")},{"./socket":18,"engine.io-parser":27}],18:[function(_dereq_,module,exports){(function(global){var transports=_dereq_("./transports");var Emitter=_dereq_("component-emitter");var debug=_dereq_("debug")("engine.io-client:socket");var index=_dereq_("indexof");var parser=_dereq_("engine.io-parser");var parseuri=_dereq_("parseuri");var parsejson=_dereq_("parsejson");var parseqs=_dereq_("parseqs");module.exports=Socket;function noop(){}function Socket(uri,opts){if(!(this instanceof Socket))return new Socket(uri,opts);opts=opts||{};if(uri&&"object"==typeof uri){opts=uri;uri=null}if(uri){uri=parseuri(uri);opts.hostname=uri.host;opts.secure=uri.protocol=="https"||uri.protocol=="wss";opts.port=uri.port;if(uri.query)opts.query=uri.query}else if(opts.host){opts.hostname=parseuri(opts.host).host}this.secure=null!=opts.secure?opts.secure:global.location&&"https:"==location.protocol;if(opts.hostname&&!opts.port){opts.port=this.secure?"443":"80"}this.agent=opts.agent||false;this.hostname=opts.hostname||(global.location?location.hostname:"localhost");this.port=opts.port||(global.location&&location.port?location.port:this.secure?443:80);this.query=opts.query||{};if("string"==typeof this.query)this.query=parseqs.decode(this.query);this.upgrade=false!==opts.upgrade;this.path=(opts.path||"/engine.io").replace(/\/$/,"")+"/";this.forceJSONP=!!opts.forceJSONP;this.jsonp=false!==opts.jsonp;this.forceBase64=!!opts.forceBase64;this.enablesXDR=!!opts.enablesXDR;this.timestampParam=opts.timestampParam||"t";this.timestampRequests=opts.timestampRequests;this.transports=opts.transports||["polling","websocket"];this.readyState="";this.writeBuffer=[];this.policyPort=opts.policyPort||843;this.rememberUpgrade=opts.rememberUpgrade||false;this.binaryType=null;this.onlyBinaryUpgrades=opts.onlyBinaryUpgrades;this.perMessageDeflate=false!==opts.perMessageDeflate?opts.perMessageDeflate||{}:false;if(true===this.perMessageDeflate)this.perMessageDeflate={};if(this.perMessageDeflate&&null==this.perMessageDeflate.threshold){this.perMessageDeflate.threshold=1024}this.pfx=opts.pfx||null;this.key=opts.key||null;this.passphrase=opts.passphrase||null;this.cert=opts.cert||null;this.ca=opts.ca||null;this.ciphers=opts.ciphers||null;this.rejectUnauthorized=opts.rejectUnauthorized===undefined?null:opts.rejectUnauthorized;var freeGlobal=typeof global=="object"&&global;if(freeGlobal.global===freeGlobal){if(opts.extraHeaders&&Object.keys(opts.extraHeaders).length>0){this.extraHeaders=opts.extraHeaders}}this.open()}Socket.priorWebsocketSuccess=false;Emitter(Socket.prototype);Socket.protocol=parser.protocol;Socket.Socket=Socket;Socket.Transport=_dereq_("./transport");Socket.transports=_dereq_("./transports");Socket.parser=_dereq_("engine.io-parser");Socket.prototype.createTransport=function(name){debug('creating transport "%s"',name);var query=clone(this.query);query.EIO=parser.protocol;query.transport=name;if(this.id)query.sid=this.id;var transport=new transports[name]({agent:this.agent,hostname:this.hostname,port:this.port,secure:this.secure,path:this.path,query:query,forceJSONP:this.forceJSONP,jsonp:this.jsonp,forceBase64:this.forceBase64,enablesXDR:this.enablesXDR,timestampRequests:this.timestampRequests,timestampParam:this.timestampParam,policyPort:this.policyPort,socket:this,pfx:this.pfx,key:this.key,passphrase:this.passphrase,cert:this.cert,ca:this.ca,ciphers:this.ciphers,rejectUnauthorized:this.rejectUnauthorized,perMessageDeflate:this.perMessageDeflate,extraHeaders:this.extraHeaders});return transport};function clone(obj){var o={};for(var i in obj){if(obj.hasOwnProperty(i)){o[i]=obj[i]}}return o}Socket.prototype.open=function(){var transport;if(this.rememberUpgrade&&Socket.priorWebsocketSuccess&&this.transports.indexOf("websocket")!=-1){transport="websocket"}else if(0===this.transports.length){var self=this;setTimeout(function(){self.emit("error","No transports available")},0);return}else{transport=this.transports[0]}this.readyState="opening";try{transport=this.createTransport(transport)}catch(e){this.transports.shift();this.open();return}transport.open();this.setTransport(transport)};Socket.prototype.setTransport=function(transport){debug("setting transport %s",transport.name);var self=this;if(this.transport){debug("clearing existing transport %s",this.transport.name);this.transport.removeAllListeners()}this.transport=transport;transport.on("drain",function(){self.onDrain()}).on("packet",function(packet){self.onPacket(packet)}).on("error",function(e){self.onError(e)}).on("close",function(){self.onClose("transport close")})};Socket.prototype.probe=function(name){debug('probing transport "%s"',name);var transport=this.createTransport(name,{probe:1}),failed=false,self=this;Socket.priorWebsocketSuccess=false;function onTransportOpen(){if(self.onlyBinaryUpgrades){var upgradeLosesBinary=!this.supportsBinary&&self.transport.supportsBinary;failed=failed||upgradeLosesBinary}if(failed)return;debug('probe transport "%s" opened',name);transport.send([{type:"ping",data:"probe"}]);transport.once("packet",function(msg){if(failed)return;if("pong"==msg.type&&"probe"==msg.data){debug('probe transport "%s" pong',name);self.upgrading=true;self.emit("upgrading",transport);if(!transport)return;Socket.priorWebsocketSuccess="websocket"==transport.name;debug('pausing current transport "%s"',self.transport.name);self.transport.pause(function(){if(failed)return;if("closed"==self.readyState)return;debug("changing transport and sending upgrade packet");cleanup();self.setTransport(transport);transport.send([{type:"upgrade"}]);self.emit("upgrade",transport);transport=null;self.upgrading=false;self.flush()})}else{debug('probe transport "%s" failed',name);var err=new Error("probe error");err.transport=transport.name;self.emit("upgradeError",err)}})}function freezeTransport(){if(failed)return;failed=true;cleanup();transport.close();transport=null}function onerror(err){var error=new Error("probe error: "+err);error.transport=transport.name;freezeTransport();debug('probe transport "%s" failed because of error: %s',name,err);self.emit("upgradeError",error)}function onTransportClose(){onerror("transport closed")}function onclose(){onerror("socket closed")}function onupgrade(to){if(transport&&to.name!=transport.name){debug('"%s" works - aborting "%s"',to.name,transport.name);freezeTransport()}}function cleanup(){transport.removeListener("open",onTransportOpen);transport.removeListener("error",onerror);transport.removeListener("close",onTransportClose);self.removeListener("close",onclose);self.removeListener("upgrading",onupgrade)}transport.once("open",onTransportOpen);transport.once("error",onerror);transport.once("close",onTransportClose);
142 this.once("close",onclose);this.once("upgrading",onupgrade);transport.open()};Socket.prototype.onOpen=function(){debug("socket open");this.readyState="open";Socket.priorWebsocketSuccess="websocket"==this.transport.name;this.emit("open");this.flush();if("open"==this.readyState&&this.upgrade&&this.transport.pause){debug("starting upgrade probes");for(var i=0,l=this.upgrades.length;i<l;i++){this.probe(this.upgrades[i])}}};Socket.prototype.onPacket=function(packet){if("opening"==this.readyState||"open"==this.readyState){debug('socket receive: type "%s", data "%s"',packet.type,packet.data);this.emit("packet",packet);this.emit("heartbeat");switch(packet.type){case"open":this.onHandshake(parsejson(packet.data));break;case"pong":this.setPing();this.emit("pong");break;case"error":var err=new Error("server error");err.code=packet.data;this.onError(err);break;case"message":this.emit("data",packet.data);this.emit("message",packet.data);break}}else{debug('packet received with socket readyState "%s"',this.readyState)}};Socket.prototype.onHandshake=function(data){this.emit("handshake",data);this.id=data.sid;this.transport.query.sid=data.sid;this.upgrades=this.filterUpgrades(data.upgrades);this.pingInterval=data.pingInterval;this.pingTimeout=data.pingTimeout;this.onOpen();if("closed"==this.readyState)return;this.setPing();this.removeListener("heartbeat",this.onHeartbeat);this.on("heartbeat",this.onHeartbeat)};Socket.prototype.onHeartbeat=function(timeout){clearTimeout(this.pingTimeoutTimer);var self=this;self.pingTimeoutTimer=setTimeout(function(){if("closed"==self.readyState)return;self.onClose("ping timeout")},timeout||self.pingInterval+self.pingTimeout)};Socket.prototype.setPing=function(){var self=this;clearTimeout(self.pingIntervalTimer);self.pingIntervalTimer=setTimeout(function(){debug("writing ping packet - expecting pong within %sms",self.pingTimeout);self.ping();self.onHeartbeat(self.pingTimeout)},self.pingInterval)};Socket.prototype.ping=function(){var self=this;this.sendPacket("ping",function(){self.emit("ping")})};Socket.prototype.onDrain=function(){this.writeBuffer.splice(0,this.prevBufferLen);this.prevBufferLen=0;if(0===this.writeBuffer.length){this.emit("drain")}else{this.flush()}};Socket.prototype.flush=function(){if("closed"!=this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){debug("flushing %d packets in socket",this.writeBuffer.length);this.transport.send(this.writeBuffer);this.prevBufferLen=this.writeBuffer.length;this.emit("flush")}};Socket.prototype.write=Socket.prototype.send=function(msg,options,fn){this.sendPacket("message",msg,options,fn);return this};Socket.prototype.sendPacket=function(type,data,options,fn){if("function"==typeof data){fn=data;data=undefined}if("function"==typeof options){fn=options;options=null}if("closing"==this.readyState||"closed"==this.readyState){return}options=options||{};options.compress=false!==options.compress;var packet={type:type,data:data,options:options};this.emit("packetCreate",packet);this.writeBuffer.push(packet);if(fn)this.once("flush",fn);this.flush()};Socket.prototype.close=function(){if("opening"==this.readyState||"open"==this.readyState){this.readyState="closing";var self=this;if(this.writeBuffer.length){this.once("drain",function(){if(this.upgrading){waitForUpgrade()}else{close()}})}else if(this.upgrading){waitForUpgrade()}else{close()}}function close(){self.onClose("forced close");debug("socket closing - telling transport to close");self.transport.close()}function cleanupAndClose(){self.removeListener("upgrade",cleanupAndClose);self.removeListener("upgradeError",cleanupAndClose);close()}function waitForUpgrade(){self.once("upgrade",cleanupAndClose);self.once("upgradeError",cleanupAndClose)}return this};Socket.prototype.onError=function(err){debug("socket error %j",err);Socket.priorWebsocketSuccess=false;this.emit("error",err);this.onClose("transport error",err)};Socket.prototype.onClose=function(reason,desc){if("opening"==this.readyState||"open"==this.readyState||"closing"==this.readyState){debug('socket close with reason: "%s"',reason);var self=this;clearTimeout(this.pingIntervalTimer);clearTimeout(this.pingTimeoutTimer);this.transport.removeAllListeners("close");this.transport.close();this.transport.removeAllListeners();this.readyState="closed";this.id=null;this.emit("close",reason,desc);self.writeBuffer=[];self.prevBufferLen=0}};Socket.prototype.filterUpgrades=function(upgrades){var filteredUpgrades=[];for(var i=0,j=upgrades.length;i<j;i++){if(~index(this.transports,upgrades[i]))filteredUpgrades.push(upgrades[i])}return filteredUpgrades}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"./transport":19,"./transports":20,"component-emitter":26,debug:14,"engine.io-parser":27,indexof:33,parsejson:37,parseqs:38,parseuri:39}],19:[function(_dereq_,module,exports){var parser=_dereq_("engine.io-parser");var Emitter=_dereq_("component-emitter");module.exports=Transport;function Transport(opts){this.path=opts.path;this.hostname=opts.hostname;this.port=opts.port;this.secure=opts.secure;this.query=opts.query;this.timestampParam=opts.timestampParam;this.timestampRequests=opts.timestampRequests;this.readyState="";this.agent=opts.agent||false;this.socket=opts.socket;this.enablesXDR=opts.enablesXDR;this.pfx=opts.pfx;this.key=opts.key;this.passphrase=opts.passphrase;this.cert=opts.cert;this.ca=opts.ca;this.ciphers=opts.ciphers;this.rejectUnauthorized=opts.rejectUnauthorized;this.extraHeaders=opts.extraHeaders}Emitter(Transport.prototype);Transport.prototype.onError=function(msg,desc){var err=new Error(msg);err.type="TransportError";err.description=desc;this.emit("error",err);return this};Transport.prototype.open=function(){if("closed"==this.readyState||""==this.readyState){this.readyState="opening";this.doOpen()}return this};Transport.prototype.close=function(){if("opening"==this.readyState||"open"==this.readyState){this.doClose();this.onClose()}return this};Transport.prototype.send=function(packets){if("open"==this.readyState){this.write(packets)}else{throw new Error("Transport not open")}};Transport.prototype.onOpen=function(){this.readyState="open";this.writable=true;this.emit("open")};Transport.prototype.onData=function(data){var packet=parser.decodePacket(data,this.socket.binaryType);this.onPacket(packet)};Transport.prototype.onPacket=function(packet){this.emit("packet",packet)};Transport.prototype.onClose=function(){this.readyState="closed";this.emit("close")}},{"component-emitter":26,"engine.io-parser":27}],20:[function(_dereq_,module,exports){(function(global){var XMLHttpRequest=_dereq_("xmlhttprequest-ssl");var XHR=_dereq_("./polling-xhr");var JSONP=_dereq_("./polling-jsonp");var websocket=_dereq_("./websocket");exports.polling=polling;exports.websocket=websocket;function polling(opts){var xhr;var xd=false;var xs=false;var jsonp=false!==opts.jsonp;if(global.location){var isSSL="https:"==location.protocol;var port=location.port;if(!port){port=isSSL?443:80}xd=opts.hostname!=location.hostname||port!=opts.port;xs=opts.secure!=isSSL}opts.xdomain=xd;opts.xscheme=xs;xhr=new XMLHttpRequest(opts);if("open"in xhr&&!opts.forceJSONP){return new XHR(opts)}else{if(!jsonp)throw new Error("JSONP disabled");return new JSONP(opts)}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"./polling-jsonp":21,"./polling-xhr":22,"./websocket":24,"xmlhttprequest-ssl":25}],21:[function(_dereq_,module,exports){(function(global){var Polling=_dereq_("./polling");var inherit=_dereq_("component-inherit");module.exports=JSONPPolling;var rNewline=/\n/g;var rEscapedNewline=/\\n/g;var callbacks;var index=0;function empty(){}function JSONPPolling(opts){Polling.call(this,opts);this.query=this.query||{};if(!callbacks){if(!global.___eio)global.___eio=[];callbacks=global.___eio}this.index=callbacks.length;var self=this;callbacks.push(function(msg){self.onData(msg)});this.query.j=this.index;if(global.document&&global.addEventListener){global.addEventListener("beforeunload",function(){if(self.script)self.script.onerror=empty},false)}}inherit(JSONPPolling,Polling);JSONPPolling.prototype.supportsBinary=false;JSONPPolling.prototype.doClose=function(){if(this.script){this.script.parentNode.removeChild(this.script);this.script=null}if(this.form){this.form.parentNode.removeChild(this.form);this.form=null;this.iframe=null}Polling.prototype.doClose.call(this)};JSONPPolling.prototype.doPoll=function(){var self=this;var script=document.createElement("script");if(this.script){this.script.parentNode.removeChild(this.script);this.script=null}script.async=true;script.src=this.uri();script.onerror=function(e){self.onError("jsonp poll error",e)};var insertAt=document.getElementsByTagName("script")[0];insertAt.parentNode.insertBefore(script,insertAt);this.script=script;var isUAgecko="undefined"!=typeof navigator&&/gecko/i.test(navigator.userAgent);if(isUAgecko){setTimeout(function(){var iframe=document.createElement("iframe");document.body.appendChild(iframe);document.body.removeChild(iframe)},100)}};JSONPPolling.prototype.doWrite=function(data,fn){var self=this;if(!this.form){var form=document.createElement("form");var area=document.createElement("textarea");var id=this.iframeId="eio_iframe_"+this.index;var iframe;form.className="socketio";form.style.position="absolute";form.style.top="-1000px";form.style.left="-1000px";form.target=id;form.method="POST";form.setAttribute("accept-charset","utf-8");area.name="d";form.appendChild(area);document.body.appendChild(form);this.form=form;this.area=area}this.form.action=this.uri();function complete(){initIframe();fn()}function initIframe(){if(self.iframe){try{self.form.removeChild(self.iframe)}catch(e){self.onError("jsonp polling iframe removal error",e)}}try{var html='<iframe src="javascript:0" name="'+self.iframeId+'">';iframe=document.createElement(html)}catch(e){iframe=document.createElement("iframe");iframe.name=self.iframeId;iframe.src="javascript:0"}iframe.id=self.iframeId;self.form.appendChild(iframe);self.iframe=iframe}initIframe();data=data.replace(rEscapedNewline,"\\\n");this.area.value=data.replace(rNewline,"\\n");try{this.form.submit()}catch(e){}if(this.iframe.attachEvent){this.iframe.onreadystatechange=function(){if(self.iframe.readyState=="complete"){complete()}}}else{this.iframe.onload=complete}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"./polling":23,"component-inherit":13}],22:[function(_dereq_,module,exports){(function(global){var XMLHttpRequest=_dereq_("xmlhttprequest-ssl");var Polling=_dereq_("./polling");var Emitter=_dereq_("component-emitter");var inherit=_dereq_("component-inherit");var debug=_dereq_("debug")("engine.io-client:polling-xhr");module.exports=XHR;module.exports.Request=Request;function empty(){}function XHR(opts){Polling.call(this,opts);if(global.location){var isSSL="https:"==location.protocol;var port=location.port;if(!port){port=isSSL?443:80}this.xd=opts.hostname!=global.location.hostname||port!=opts.port;this.xs=opts.secure!=isSSL}else{this.extraHeaders=opts.extraHeaders}}inherit(XHR,Polling);XHR.prototype.supportsBinary=true;XHR.prototype.request=function(opts){opts=opts||{};opts.uri=this.uri();opts.xd=this.xd;opts.xs=this.xs;opts.agent=this.agent||false;opts.supportsBinary=this.supportsBinary;opts.enablesXDR=this.enablesXDR;opts.pfx=this.pfx;opts.key=this.key;opts.passphrase=this.passphrase;opts.cert=this.cert;opts.ca=this.ca;opts.ciphers=this.ciphers;opts.rejectUnauthorized=this.rejectUnauthorized;opts.extraHeaders=this.extraHeaders;return new Request(opts)};XHR.prototype.doWrite=function(data,fn){var isBinary=typeof data!=="string"&&data!==undefined;var req=this.request({method:"POST",data:data,isBinary:isBinary});var self=this;req.on("success",fn);req.on("error",function(err){self.onError("xhr post error",err)});this.sendXhr=req};XHR.prototype.doPoll=function(){debug("xhr poll");var req=this.request();var self=this;req.on("data",function(data){self.onData(data)});req.on("error",function(err){self.onError("xhr poll error",err)});this.pollXhr=req};function Request(opts){this.method=opts.method||"GET";this.uri=opts.uri;this.xd=!!opts.xd;this.xs=!!opts.xs;this.async=false!==opts.async;this.data=undefined!=opts.data?opts.data:null;this.agent=opts.agent;this.isBinary=opts.isBinary;this.supportsBinary=opts.supportsBinary;this.enablesXDR=opts.enablesXDR;this.pfx=opts.pfx;this.key=opts.key;this.passphrase=opts.passphrase;this.cert=opts.cert;this.ca=opts.ca;this.ciphers=opts.ciphers;this.rejectUnauthorized=opts.rejectUnauthorized;this.extraHeaders=opts.extraHeaders;this.create()}Emitter(Request.prototype);Request.prototype.create=function(){var opts={agent:this.agent,xdomain:this.xd,xscheme:this.xs,enablesXDR:this.enablesXDR};opts.pfx=this.pfx;opts.key=this.key;opts.passphrase=this.passphrase;opts.cert=this.cert;opts.ca=this.ca;opts.ciphers=this.ciphers;opts.rejectUnauthorized=this.rejectUnauthorized;var xhr=this.xhr=new XMLHttpRequest(opts);var self=this;try{debug("xhr open %s: %s",this.method,this.uri);xhr.open(this.method,this.uri,this.async);try{if(this.extraHeaders){xhr.setDisableHeaderCheck(true);for(var i in this.extraHeaders){if(this.extraHeaders.hasOwnProperty(i)){xhr.setRequestHeader(i,this.extraHeaders[i])}}}}catch(e){}if(this.supportsBinary){xhr.responseType="arraybuffer"}if("POST"==this.method){try{if(this.isBinary){xhr.setRequestHeader("Content-type","application/octet-stream")}else{xhr.setRequestHeader("Content-type","text/plain;charset=UTF-8")}}catch(e){}}if("withCredentials"in xhr){xhr.withCredentials=true}if(this.hasXDR()){xhr.onload=function(){self.onLoad()};xhr.onerror=function(){self.onError(xhr.responseText)}}else{xhr.onreadystatechange=function(){if(4!=xhr.readyState)return;if(200==xhr.status||1223==xhr.status){self.onLoad()}else{setTimeout(function(){self.onError(xhr.status)},0)}}}debug("xhr data %s",this.data);xhr.send(this.data)}catch(e){setTimeout(function(){self.onError(e)},0);return}if(global.document){this.index=Request.requestsCount++;Request.requests[this.index]=this}};Request.prototype.onSuccess=function(){this.emit("success");this.cleanup()};Request.prototype.onData=function(data){this.emit("data",data);this.onSuccess()};Request.prototype.onError=function(err){this.emit("error",err);this.cleanup(true)};Request.prototype.cleanup=function(fromError){if("undefined"==typeof this.xhr||null===this.xhr){return}if(this.hasXDR()){this.xhr.onload=this.xhr.onerror=empty}else{this.xhr.onreadystatechange=empty}if(fromError){try{this.xhr.abort()}catch(e){}}if(global.document){delete Request.requests[this.index]}this.xhr=null};Request.prototype.onLoad=function(){var data;try{var contentType;try{contentType=this.xhr.getResponseHeader("Content-Type").split(";")[0]}catch(e){}if(contentType==="application/octet-stream"){data=this.xhr.response}else{if(!this.supportsBinary){data=this.xhr.responseText}else{try{data=String.fromCharCode.apply(null,new Uint8Array(this.xhr.response))}catch(e){var ui8Arr=new Uint8Array(this.xhr.response);var dataArray=[];for(var idx=0,length=ui8Arr.length;idx<length;idx++){dataArray.push(ui8Arr[idx])}data=String.fromCharCode.apply(null,dataArray)}}}}catch(e){this.onError(e)}if(null!=data){this.onData(data)}};Request.prototype.hasXDR=function(){return"undefined"!==typeof global.XDomainRequest&&!this.xs&&this.enablesXDR};Request.prototype.abort=function(){this.cleanup()};if(global.document){Request.requestsCount=0;Request.requests={};if(global.attachEvent){global.attachEvent("onunload",unloadHandler)}else if(global.addEventListener){global.addEventListener("beforeunload",unloadHandler,false)}}function unloadHandler(){for(var i in Request.requests){if(Request.requests.hasOwnProperty(i)){Request.requests[i].abort()}}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"./polling":23,"component-emitter":26,"component-inherit":13,debug:14,"xmlhttprequest-ssl":25}],23:[function(_dereq_,module,exports){var Transport=_dereq_("../transport");var parseqs=_dereq_("parseqs");var parser=_dereq_("engine.io-parser");var inherit=_dereq_("component-inherit");var yeast=_dereq_("yeast");var debug=_dereq_("debug")("engine.io-client:polling");module.exports=Polling;var hasXHR2=function(){var XMLHttpRequest=_dereq_("xmlhttprequest-ssl");var xhr=new XMLHttpRequest({xdomain:false});return null!=xhr.responseType}();function Polling(opts){var forceBase64=opts&&opts.forceBase64;if(!hasXHR2||forceBase64){this.supportsBinary=false}Transport.call(this,opts)}inherit(Polling,Transport);Polling.prototype.name="polling";Polling.prototype.doOpen=function(){this.poll()};Polling.prototype.pause=function(onPause){var pending=0;var self=this;this.readyState="pausing";function pause(){debug("paused");self.readyState="paused";onPause()}if(this.polling||!this.writable){var total=0;if(this.polling){debug("we are currently polling - waiting to pause");total++;this.once("pollComplete",function(){debug("pre-pause polling complete");--total||pause()})}if(!this.writable){debug("we are currently writing - waiting to pause");total++;this.once("drain",function(){debug("pre-pause writing complete");--total||pause()})}}else{pause()}};Polling.prototype.poll=function(){debug("polling");this.polling=true;this.doPoll();this.emit("poll")};Polling.prototype.onData=function(data){var self=this;debug("polling got data %s",data);var callback=function(packet,index,total){if("opening"==self.readyState){self.onOpen()}if("close"==packet.type){self.onClose();return false}self.onPacket(packet)};parser.decodePayload(data,this.socket.binaryType,callback);if("closed"!=this.readyState){this.polling=false;this.emit("pollComplete");if("open"==this.readyState){this.poll()}else{debug('ignoring poll - transport state "%s"',this.readyState)}}};Polling.prototype.doClose=function(){var self=this;function close(){debug("writing close packet");self.write([{type:"close"}])}if("open"==this.readyState){debug("transport open - closing");close()}else{debug("transport not open - deferring close");this.once("open",close)}};Polling.prototype.write=function(packets){var self=this;this.writable=false;var callbackfn=function(){self.writable=true;self.emit("drain")};var self=this;parser.encodePayload(packets,this.supportsBinary,function(data){self.doWrite(data,callbackfn)})};Polling.prototype.uri=function(){var query=this.query||{};var schema=this.secure?"https":"http";var port="";if(false!==this.timestampRequests){query[this.timestampParam]=yeast()}if(!this.supportsBinary&&!query.sid){query.b64=1}query=parseqs.encode(query);if(this.port&&("https"==schema&&this.port!=443||"http"==schema&&this.port!=80)){port=":"+this.port}if(query.length){query="?"+query}var ipv6=this.hostname.indexOf(":")!==-1;return schema+"://"+(ipv6?"["+this.hostname+"]":this.hostname)+port+this.path+query}},{"../transport":19,"component-inherit":13,debug:14,"engine.io-parser":27,parseqs:38,"xmlhttprequest-ssl":25,yeast:46}],24:[function(_dereq_,module,exports){(function(global){var Transport=_dereq_("../transport");var parser=_dereq_("engine.io-parser");var parseqs=_dereq_("parseqs");var inherit=_dereq_("component-inherit");var yeast=_dereq_("yeast");var debug=_dereq_("debug")("engine.io-client:websocket");var BrowserWebSocket=global.WebSocket||global.MozWebSocket;var WebSocket=BrowserWebSocket||(typeof window!=="undefined"?null:_dereq_("ws"));module.exports=WS;function WS(opts){var forceBase64=opts&&opts.forceBase64;if(forceBase64){this.supportsBinary=false}this.perMessageDeflate=opts.perMessageDeflate;Transport.call(this,opts)}inherit(WS,Transport);WS.prototype.name="websocket";WS.prototype.supportsBinary=true;WS.prototype.doOpen=function(){if(!this.check()){return}var self=this;var uri=this.uri();var protocols=void 0;var opts={agent:this.agent,perMessageDeflate:this.perMessageDeflate};opts.pfx=this.pfx;opts.key=this.key;opts.passphrase=this.passphrase;opts.cert=this.cert;opts.ca=this.ca;opts.ciphers=this.ciphers;opts.rejectUnauthorized=this.rejectUnauthorized;if(this.extraHeaders){opts.headers=this.extraHeaders}this.ws=BrowserWebSocket?new WebSocket(uri):new WebSocket(uri,protocols,opts);if(this.ws.binaryType===undefined){this.supportsBinary=false}if(this.ws.supports&&this.ws.supports.binary){this.supportsBinary=true;this.ws.binaryType="buffer"}else{this.ws.binaryType="arraybuffer"}this.addEventListeners()};WS.prototype.addEventListeners=function(){var self=this;this.ws.onopen=function(){self.onOpen()};this.ws.onclose=function(){self.onClose()};this.ws.onmessage=function(ev){self.onData(ev.data)};this.ws.onerror=function(e){self.onError("websocket error",e)}};if("undefined"!=typeof navigator&&/iPad|iPhone|iPod/i.test(navigator.userAgent)){WS.prototype.onData=function(data){var self=this;setTimeout(function(){Transport.prototype.onData.call(self,data)},0)}}WS.prototype.write=function(packets){var self=this;this.writable=false;var total=packets.length;for(var i=0,l=total;i<l;i++){(function(packet){parser.encodePacket(packet,self.supportsBinary,function(data){if(!BrowserWebSocket){var opts={};if(packet.options){opts.compress=packet.options.compress}if(self.perMessageDeflate){var len="string"==typeof data?global.Buffer.byteLength(data):data.length;if(len<self.perMessageDeflate.threshold){opts.compress=false}}}try{if(BrowserWebSocket){self.ws.send(data)}else{self.ws.send(data,opts)}}catch(e){debug("websocket closed before onclose event")}--total||done()})})(packets[i])}function done(){self.emit("flush");setTimeout(function(){self.writable=true;self.emit("drain")},0)}};WS.prototype.onClose=function(){Transport.prototype.onClose.call(this)};WS.prototype.doClose=function(){if(typeof this.ws!=="undefined"){this.ws.close()}};WS.prototype.uri=function(){var query=this.query||{};var schema=this.secure?"wss":"ws";var port="";if(this.port&&("wss"==schema&&this.port!=443||"ws"==schema&&this.port!=80)){port=":"+this.port}if(this.timestampRequests){query[this.timestampParam]=yeast()}if(!this.supportsBinary){query.b64=1}query=parseqs.encode(query);if(query.length){query="?"+query}var ipv6=this.hostname.indexOf(":")!==-1;return schema+"://"+(ipv6?"["+this.hostname+"]":this.hostname)+port+this.path+query};WS.prototype.check=function(){return!!WebSocket&&!("__initialize"in WebSocket&&this.name===WS.prototype.name)}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"../transport":19,"component-inherit":13,debug:14,"engine.io-parser":27,parseqs:38,ws:undefined,yeast:46}],25:[function(_dereq_,module,exports){var hasCORS=_dereq_("has-cors");module.exports=function(opts){var xdomain=opts.xdomain;var xscheme=opts.xscheme;var enablesXDR=opts.enablesXDR;try{if("undefined"!=typeof XMLHttpRequest&&(!xdomain||hasCORS)){return new XMLHttpRequest}}catch(e){}try{if("undefined"!=typeof XDomainRequest&&!xscheme&&enablesXDR){return new XDomainRequest}}catch(e){}if(!xdomain){try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}}}},{"has-cors":32}],26:[function(_dereq_,module,exports){module.exports=Emitter;function Emitter(obj){if(obj)return mixin(obj)}function mixin(obj){for(var key in Emitter.prototype){obj[key]=Emitter.prototype[key]}return obj}Emitter.prototype.on=Emitter.prototype.addEventListener=function(event,fn){this._callbacks=this._callbacks||{};(this._callbacks[event]=this._callbacks[event]||[]).push(fn);return this};Emitter.prototype.once=function(event,fn){var self=this;this._callbacks=this._callbacks||{};function on(){self.off(event,on);fn.apply(this,arguments)}on.fn=fn;this.on(event,on);return this};Emitter.prototype.off=Emitter.prototype.removeListener=Emitter.prototype.removeAllListeners=Emitter.prototype.removeEventListener=function(event,fn){this._callbacks=this._callbacks||{};if(0==arguments.length){this._callbacks={};return this}var callbacks=this._callbacks[event];if(!callbacks)return this;if(1==arguments.length){delete this._callbacks[event];return this}var cb;for(var i=0;i<callbacks.length;i++){cb=callbacks[i];if(cb===fn||cb.fn===fn){callbacks.splice(i,1);break}}return this};Emitter.prototype.emit=function(event){this._callbacks=this._callbacks||{};var args=[].slice.call(arguments,1),callbacks=this._callbacks[event];if(callbacks){callbacks=callbacks.slice(0);for(var i=0,len=callbacks.length;i<len;++i){callbacks[i].apply(this,args)}}return this};Emitter.prototype.listeners=function(event){this._callbacks=this._callbacks||{};return this._callbacks[event]||[]};Emitter.prototype.hasListeners=function(event){return!!this.listeners(event).length}},{}],27:[function(_dereq_,module,exports){(function(global){var keys=_dereq_("./keys");var hasBinary=_dereq_("has-binary");var sliceBuffer=_dereq_("arraybuffer.slice");var base64encoder=_dereq_("base64-arraybuffer");var after=_dereq_("after");var utf8=_dereq_("utf8");var isAndroid=navigator.userAgent.match(/Android/i);var isPhantomJS=/PhantomJS/i.test(navigator.userAgent);var dontSendBlobs=isAndroid||isPhantomJS;exports.protocol=3;var packets=exports.packets={open:0,close:1,ping:2,pong:3,message:4,upgrade:5,noop:6};var packetslist=keys(packets);var err={type:"error",data:"parser error"};var Blob=_dereq_("blob");exports.encodePacket=function(packet,supportsBinary,utf8encode,callback){if("function"==typeof supportsBinary){callback=supportsBinary;supportsBinary=false}if("function"==typeof utf8encode){callback=utf8encode;utf8encode=null}var data=packet.data===undefined?undefined:packet.data.buffer||packet.data;if(global.ArrayBuffer&&data instanceof ArrayBuffer){return encodeArrayBuffer(packet,supportsBinary,callback)}else if(Blob&&data instanceof global.Blob){return encodeBlob(packet,supportsBinary,callback)}if(data&&data.base64){return encodeBase64Object(packet,callback)}var encoded=packets[packet.type];if(undefined!==packet.data){encoded+=utf8encode?utf8.encode(String(packet.data)):String(packet.data)}return callback(""+encoded)};function encodeBase64Object(packet,callback){var message="b"+exports.packets[packet.type]+packet.data.data;return callback(message)}function encodeArrayBuffer(packet,supportsBinary,callback){if(!supportsBinary){return exports.encodeBase64Packet(packet,callback)}var data=packet.data;var contentArray=new Uint8Array(data);var resultBuffer=new Uint8Array(1+data.byteLength);resultBuffer[0]=packets[packet.type];for(var i=0;i<contentArray.length;i++){resultBuffer[i+1]=contentArray[i]}return callback(resultBuffer.buffer)}function encodeBlobAsArrayBuffer(packet,supportsBinary,callback){if(!supportsBinary){return exports.encodeBase64Packet(packet,callback)}var fr=new FileReader;fr.onload=function(){packet.data=fr.result;exports.encodePacket(packet,supportsBinary,true,callback)};return fr.readAsArrayBuffer(packet.data)}function encodeBlob(packet,supportsBinary,callback){if(!supportsBinary){return exports.encodeBase64Packet(packet,callback)}if(dontSendBlobs){return encodeBlobAsArrayBuffer(packet,supportsBinary,callback)}var length=new Uint8Array(1);length[0]=packets[packet.type];var blob=new Blob([length.buffer,packet.data]);return callback(blob)}exports.encodeBase64Packet=function(packet,callback){var message="b"+exports.packets[packet.type];if(Blob&&packet.data instanceof global.Blob){var fr=new FileReader;fr.onload=function(){var b64=fr.result.split(",")[1];callback(message+b64)};return fr.readAsDataURL(packet.data)}var b64data;try{b64data=String.fromCharCode.apply(null,new Uint8Array(packet.data))}catch(e){var typed=new Uint8Array(packet.data);var basic=new Array(typed.length);for(var i=0;i<typed.length;i++){basic[i]=typed[i]}b64data=String.fromCharCode.apply(null,basic)}message+=global.btoa(b64data);return callback(message)};exports.decodePacket=function(data,binaryType,utf8decode){if(typeof data=="string"||data===undefined){if(data.charAt(0)=="b"){return exports.decodeBase64Packet(data.substr(1),binaryType)}if(utf8decode){try{data=utf8.decode(data)}catch(e){return err}}var type=data.charAt(0);if(Number(type)!=type||!packetslist[type]){return err}if(data.length>1){return{type:packetslist[type],data:data.substring(1)}}else{return{type:packetslist[type]}}}var asArray=new Uint8Array(data);var type=asArray[0];var rest=sliceBuffer(data,1);if(Blob&&binaryType==="blob"){rest=new Blob([rest])}return{type:packetslist[type],data:rest}};exports.decodeBase64Packet=function(msg,binaryType){var type=packetslist[msg.charAt(0)];if(!global.ArrayBuffer){return{type:type,data:{base64:true,data:msg.substr(1)}}}var data=base64encoder.decode(msg.substr(1));if(binaryType==="blob"&&Blob){data=new Blob([data])}return{type:type,data:data}};exports.encodePayload=function(packets,supportsBinary,callback){if(typeof supportsBinary=="function"){callback=supportsBinary;supportsBinary=null}var isBinary=hasBinary(packets);if(supportsBinary&&isBinary){if(Blob&&!dontSendBlobs){return exports.encodePayloadAsBlob(packets,callback)}return exports.encodePayloadAsArrayBuffer(packets,callback)}if(!packets.length){return callback("0:")}function setLengthHeader(message){return message.length+":"+message}function encodeOne(packet,doneCallback){exports.encodePacket(packet,!isBinary?false:supportsBinary,true,function(message){doneCallback(null,setLengthHeader(message))})}map(packets,encodeOne,function(err,results){return callback(results.join(""))})};function map(ary,each,done){var result=new Array(ary.length);var next=after(ary.length,done);var eachWithIndex=function(i,el,cb){each(el,function(error,msg){result[i]=msg;cb(error,result)})};for(var i=0;i<ary.length;i++){eachWithIndex(i,ary[i],next)}}exports.decodePayload=function(data,binaryType,callback){if(typeof data!="string"){return exports.decodePayloadAsBinary(data,binaryType,callback)}if(typeof binaryType==="function"){callback=binaryType;binaryType=null}var packet;if(data==""){return callback(err,0,1)}var length="",n,msg;for(var i=0,l=data.length;i<l;i++){var chr=data.charAt(i);if(":"!=chr){length+=chr}else{if(""==length||length!=(n=Number(length))){return callback(err,0,1)}msg=data.substr(i+1,n);if(length!=msg.length){return callback(err,0,1)}if(msg.length){packet=exports.decodePacket(msg,binaryType,true);if(err.type==packet.type&&err.data==packet.data){return callback(err,0,1)}var ret=callback(packet,i+n,l);if(false===ret)return}i+=n;length=""}}if(length!=""){return callback(err,0,1)}};exports.encodePayloadAsArrayBuffer=function(packets,callback){if(!packets.length){return callback(new ArrayBuffer(0))}function encodeOne(packet,doneCallback){exports.encodePacket(packet,true,true,function(data){return doneCallback(null,data)})}map(packets,encodeOne,function(err,encodedPackets){var totalLength=encodedPackets.reduce(function(acc,p){var len;if(typeof p==="string"){len=p.length}else{len=p.byteLength}return acc+len.toString().length+len+2},0);var resultArray=new Uint8Array(totalLength);var bufferIndex=0;encodedPackets.forEach(function(p){var isString=typeof p==="string";var ab=p;if(isString){var view=new Uint8Array(p.length);for(var i=0;i<p.length;i++){view[i]=p.charCodeAt(i)}ab=view.buffer}if(isString){resultArray[bufferIndex++]=0}else{resultArray[bufferIndex++]=1}var lenStr=ab.byteLength.toString();for(var i=0;i<lenStr.length;i++){resultArray[bufferIndex++]=parseInt(lenStr[i])}resultArray[bufferIndex++]=255;var view=new Uint8Array(ab);for(var i=0;i<view.length;i++){resultArray[bufferIndex++]=view[i]}});return callback(resultArray.buffer)})};exports.encodePayloadAsBlob=function(packets,callback){function encodeOne(packet,doneCallback){exports.encodePacket(packet,true,true,function(encoded){var binaryIdentifier=new Uint8Array(1);binaryIdentifier[0]=1;if(typeof encoded==="string"){var view=new Uint8Array(encoded.length);for(var i=0;i<encoded.length;i++){view[i]=encoded.charCodeAt(i)}encoded=view.buffer;binaryIdentifier[0]=0}var len=encoded instanceof ArrayBuffer?encoded.byteLength:encoded.size;var lenStr=len.toString();var lengthAry=new Uint8Array(lenStr.length+1);
143 for(var i=0;i<lenStr.length;i++){lengthAry[i]=parseInt(lenStr[i])}lengthAry[lenStr.length]=255;if(Blob){var blob=new Blob([binaryIdentifier.buffer,lengthAry.buffer,encoded]);doneCallback(null,blob)}})}map(packets,encodeOne,function(err,results){return callback(new Blob(results))})};exports.decodePayloadAsBinary=function(data,binaryType,callback){if(typeof binaryType==="function"){callback=binaryType;binaryType=null}var bufferTail=data;var buffers=[];var numberTooLong=false;while(bufferTail.byteLength>0){var tailArray=new Uint8Array(bufferTail);var isString=tailArray[0]===0;var msgLength="";for(var i=1;;i++){if(tailArray[i]==255)break;if(msgLength.length>310){numberTooLong=true;break}msgLength+=tailArray[i]}if(numberTooLong)return callback(err,0,1);bufferTail=sliceBuffer(bufferTail,2+msgLength.length);msgLength=parseInt(msgLength);var msg=sliceBuffer(bufferTail,0,msgLength);if(isString){try{msg=String.fromCharCode.apply(null,new Uint8Array(msg))}catch(e){var typed=new Uint8Array(msg);msg="";for(var i=0;i<typed.length;i++){msg+=String.fromCharCode(typed[i])}}}buffers.push(msg);bufferTail=sliceBuffer(bufferTail,msgLength)}var total=buffers.length;buffers.forEach(function(buffer,i){callback(exports.decodePacket(buffer,binaryType,true),i,total)})}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"./keys":28,after:6,"arraybuffer.slice":7,"base64-arraybuffer":9,blob:10,"has-binary":29,utf8:45}],28:[function(_dereq_,module,exports){module.exports=Object.keys||function keys(obj){var arr=[];var has=Object.prototype.hasOwnProperty;for(var i in obj){if(has.call(obj,i)){arr.push(i)}}return arr}},{}],29:[function(_dereq_,module,exports){(function(global){var isArray=_dereq_("isarray");module.exports=hasBinary;function hasBinary(data){function _hasBinary(obj){if(!obj)return false;if(global.Buffer&&global.Buffer.isBuffer(obj)||global.ArrayBuffer&&obj instanceof ArrayBuffer||global.Blob&&obj instanceof Blob||global.File&&obj instanceof File){return true}if(isArray(obj)){for(var i=0;i<obj.length;i++){if(_hasBinary(obj[i])){return true}}}else if(obj&&"object"==typeof obj){if(obj.toJSON){obj=obj.toJSON()}for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key)&&_hasBinary(obj[key])){return true}}}return false}return _hasBinary(data)}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{isarray:34}],30:[function(_dereq_,module,exports){module.exports=function(){return this}()},{}],31:[function(_dereq_,module,exports){(function(global){var isArray=_dereq_("isarray");module.exports=hasBinary;function hasBinary(data){function _hasBinary(obj){if(!obj)return false;if(global.Buffer&&global.Buffer.isBuffer&&global.Buffer.isBuffer(obj)||global.ArrayBuffer&&obj instanceof ArrayBuffer||global.Blob&&obj instanceof Blob||global.File&&obj instanceof File){return true}if(isArray(obj)){for(var i=0;i<obj.length;i++){if(_hasBinary(obj[i])){return true}}}else if(obj&&"object"==typeof obj){if(obj.toJSON&&"function"==typeof obj.toJSON){obj=obj.toJSON()}for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key)&&_hasBinary(obj[key])){return true}}}return false}return _hasBinary(data)}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{isarray:34}],32:[function(_dereq_,module,exports){var global=_dereq_("global");try{module.exports="XMLHttpRequest"in global&&"withCredentials"in new global.XMLHttpRequest}catch(err){module.exports=false}},{global:30}],33:[function(_dereq_,module,exports){var indexOf=[].indexOf;module.exports=function(arr,obj){if(indexOf)return arr.indexOf(obj);for(var i=0;i<arr.length;++i){if(arr[i]===obj)return i}return-1}},{}],34:[function(_dereq_,module,exports){module.exports=Array.isArray||function(arr){return Object.prototype.toString.call(arr)=="[object Array]"}},{}],35:[function(_dereq_,module,exports){(function(global){(function(){var isLoader=typeof define==="function"&&define.amd;var objectTypes={"function":true,object:true};var freeExports=objectTypes[typeof exports]&&exports&&!exports.nodeType&&exports;var root=objectTypes[typeof window]&&window||this,freeGlobal=freeExports&&objectTypes[typeof module]&&module&&!module.nodeType&&typeof global=="object"&&global;if(freeGlobal&&(freeGlobal["global"]===freeGlobal||freeGlobal["window"]===freeGlobal||freeGlobal["self"]===freeGlobal)){root=freeGlobal}function runInContext(context,exports){context||(context=root["Object"]());exports||(exports=root["Object"]());var Number=context["Number"]||root["Number"],String=context["String"]||root["String"],Object=context["Object"]||root["Object"],Date=context["Date"]||root["Date"],SyntaxError=context["SyntaxError"]||root["SyntaxError"],TypeError=context["TypeError"]||root["TypeError"],Math=context["Math"]||root["Math"],nativeJSON=context["JSON"]||root["JSON"];if(typeof nativeJSON=="object"&&nativeJSON){exports.stringify=nativeJSON.stringify;exports.parse=nativeJSON.parse}var objectProto=Object.prototype,getClass=objectProto.toString,isProperty,forEach,undef;var isExtended=new Date(-0xc782b5b800cec);try{isExtended=isExtended.getUTCFullYear()==-109252&&isExtended.getUTCMonth()===0&&isExtended.getUTCDate()===1&&isExtended.getUTCHours()==10&&isExtended.getUTCMinutes()==37&&isExtended.getUTCSeconds()==6&&isExtended.getUTCMilliseconds()==708}catch(exception){}function has(name){if(has[name]!==undef){return has[name]}var isSupported;if(name=="bug-string-char-index"){isSupported="a"[0]!="a"}else if(name=="json"){isSupported=has("json-stringify")&&has("json-parse")}else{var value,serialized='{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';if(name=="json-stringify"){var stringify=exports.stringify,stringifySupported=typeof stringify=="function"&&isExtended;if(stringifySupported){(value=function(){return 1}).toJSON=value;try{stringifySupported=stringify(0)==="0"&&stringify(new Number)==="0"&&stringify(new String)=='""'&&stringify(getClass)===undef&&stringify(undef)===undef&&stringify()===undef&&stringify(value)==="1"&&stringify([value])=="[1]"&&stringify([undef])=="[null]"&&stringify(null)=="null"&&stringify([undef,getClass,null])=="[null,null,null]"&&stringify({a:[value,true,false,null,"\x00\b\n\f\r "]})==serialized&&stringify(null,value)==="1"&&stringify([1,2],null,1)=="[\n 1,\n 2\n]"&&stringify(new Date(-864e13))=='"-271821-04-20T00:00:00.000Z"'&&stringify(new Date(864e13))=='"+275760-09-13T00:00:00.000Z"'&&stringify(new Date(-621987552e5))=='"-000001-01-01T00:00:00.000Z"'&&stringify(new Date(-1))=='"1969-12-31T23:59:59.999Z"'}catch(exception){stringifySupported=false}}isSupported=stringifySupported}if(name=="json-parse"){var parse=exports.parse;if(typeof parse=="function"){try{if(parse("0")===0&&!parse(false)){value=parse(serialized);var parseSupported=value["a"].length==5&&value["a"][0]===1;if(parseSupported){try{parseSupported=!parse('" "')}catch(exception){}if(parseSupported){try{parseSupported=parse("01")!==1}catch(exception){}}if(parseSupported){try{parseSupported=parse("1.")!==1}catch(exception){}}}}}catch(exception){parseSupported=false}}isSupported=parseSupported}}return has[name]=!!isSupported}if(!has("json")){var functionClass="[object Function]",dateClass="[object Date]",numberClass="[object Number]",stringClass="[object String]",arrayClass="[object Array]",booleanClass="[object Boolean]";var charIndexBuggy=has("bug-string-char-index");if(!isExtended){var floor=Math.floor;var Months=[0,31,59,90,120,151,181,212,243,273,304,334];var getDay=function(year,month){return Months[month]+365*(year-1970)+floor((year-1969+(month=+(month>1)))/4)-floor((year-1901+month)/100)+floor((year-1601+month)/400)}}if(!(isProperty=objectProto.hasOwnProperty)){isProperty=function(property){var members={},constructor;if((members.__proto__=null,members.__proto__={toString:1},members).toString!=getClass){isProperty=function(property){var original=this.__proto__,result=property in(this.__proto__=null,this);this.__proto__=original;return result}}else{constructor=members.constructor;isProperty=function(property){var parent=(this.constructor||constructor).prototype;return property in this&&!(property in parent&&this[property]===parent[property])}}members=null;return isProperty.call(this,property)}}forEach=function(object,callback){var size=0,Properties,members,property;(Properties=function(){this.valueOf=0}).prototype.valueOf=0;members=new Properties;for(property in members){if(isProperty.call(members,property)){size++}}Properties=members=null;if(!size){members=["valueOf","toString","toLocaleString","propertyIsEnumerable","isPrototypeOf","hasOwnProperty","constructor"];forEach=function(object,callback){var isFunction=getClass.call(object)==functionClass,property,length;var hasProperty=!isFunction&&typeof object.constructor!="function"&&objectTypes[typeof object.hasOwnProperty]&&object.hasOwnProperty||isProperty;for(property in object){if(!(isFunction&&property=="prototype")&&hasProperty.call(object,property)){callback(property)}}for(length=members.length;property=members[--length];hasProperty.call(object,property)&&callback(property));}}else if(size==2){forEach=function(object,callback){var members={},isFunction=getClass.call(object)==functionClass,property;for(property in object){if(!(isFunction&&property=="prototype")&&!isProperty.call(members,property)&&(members[property]=1)&&isProperty.call(object,property)){callback(property)}}}}else{forEach=function(object,callback){var isFunction=getClass.call(object)==functionClass,property,isConstructor;for(property in object){if(!(isFunction&&property=="prototype")&&isProperty.call(object,property)&&!(isConstructor=property==="constructor")){callback(property)}}if(isConstructor||isProperty.call(object,property="constructor")){callback(property)}}}return forEach(object,callback)};if(!has("json-stringify")){var Escapes={92:"\\\\",34:'\\"',8:"\\b",12:"\\f",10:"\\n",13:"\\r",9:"\\t"};var leadingZeroes="000000";var toPaddedString=function(width,value){return(leadingZeroes+(value||0)).slice(-width)};var unicodePrefix="\\u00";var quote=function(value){var result='"',index=0,length=value.length,useCharIndex=!charIndexBuggy||length>10;var symbols=useCharIndex&&(charIndexBuggy?value.split(""):value);for(;index<length;index++){var charCode=value.charCodeAt(index);switch(charCode){case 8:case 9:case 10:case 12:case 13:case 34:case 92:result+=Escapes[charCode];break;default:if(charCode<32){result+=unicodePrefix+toPaddedString(2,charCode.toString(16));break}result+=useCharIndex?symbols[index]:value.charAt(index)}}return result+'"'};var serialize=function(property,object,callback,properties,whitespace,indentation,stack){var value,className,year,month,date,time,hours,minutes,seconds,milliseconds,results,element,index,length,prefix,result;try{value=object[property]}catch(exception){}if(typeof value=="object"&&value){className=getClass.call(value);if(className==dateClass&&!isProperty.call(value,"toJSON")){if(value>-1/0&&value<1/0){if(getDay){date=floor(value/864e5);for(year=floor(date/365.2425)+1970-1;getDay(year+1,0)<=date;year++);for(month=floor((date-getDay(year,0))/30.42);getDay(year,month+1)<=date;month++);date=1+date-getDay(year,month);time=(value%864e5+864e5)%864e5;hours=floor(time/36e5)%24;minutes=floor(time/6e4)%60;seconds=floor(time/1e3)%60;milliseconds=time%1e3}else{year=value.getUTCFullYear();month=value.getUTCMonth();date=value.getUTCDate();hours=value.getUTCHours();minutes=value.getUTCMinutes();seconds=value.getUTCSeconds();milliseconds=value.getUTCMilliseconds()}value=(year<=0||year>=1e4?(year<0?"-":"+")+toPaddedString(6,year<0?-year:year):toPaddedString(4,year))+"-"+toPaddedString(2,month+1)+"-"+toPaddedString(2,date)+"T"+toPaddedString(2,hours)+":"+toPaddedString(2,minutes)+":"+toPaddedString(2,seconds)+"."+toPaddedString(3,milliseconds)+"Z"}else{value=null}}else if(typeof value.toJSON=="function"&&(className!=numberClass&&className!=stringClass&&className!=arrayClass||isProperty.call(value,"toJSON"))){value=value.toJSON(property)}}if(callback){value=callback.call(object,property,value)}if(value===null){return"null"}className=getClass.call(value);if(className==booleanClass){return""+value}else if(className==numberClass){return value>-1/0&&value<1/0?""+value:"null"}else if(className==stringClass){return quote(""+value)}if(typeof value=="object"){for(length=stack.length;length--;){if(stack[length]===value){throw TypeError()}}stack.push(value);results=[];prefix=indentation;indentation+=whitespace;if(className==arrayClass){for(index=0,length=value.length;index<length;index++){element=serialize(index,value,callback,properties,whitespace,indentation,stack);results.push(element===undef?"null":element)}result=results.length?whitespace?"[\n"+indentation+results.join(",\n"+indentation)+"\n"+prefix+"]":"["+results.join(",")+"]":"[]"}else{forEach(properties||value,function(property){var element=serialize(property,value,callback,properties,whitespace,indentation,stack);if(element!==undef){results.push(quote(property)+":"+(whitespace?" ":"")+element)}});result=results.length?whitespace?"{\n"+indentation+results.join(",\n"+indentation)+"\n"+prefix+"}":"{"+results.join(",")+"}":"{}"}stack.pop();return result}};exports.stringify=function(source,filter,width){var whitespace,callback,properties,className;if(objectTypes[typeof filter]&&filter){if((className=getClass.call(filter))==functionClass){callback=filter}else if(className==arrayClass){properties={};for(var index=0,length=filter.length,value;index<length;value=filter[index++],(className=getClass.call(value),className==stringClass||className==numberClass)&&(properties[value]=1));}}if(width){if((className=getClass.call(width))==numberClass){if((width-=width%1)>0){for(whitespace="",width>10&&(width=10);whitespace.length<width;whitespace+=" ");}}else if(className==stringClass){whitespace=width.length<=10?width:width.slice(0,10)}}return serialize("",(value={},value[""]=source,value),callback,properties,whitespace,"",[])}}if(!has("json-parse")){var fromCharCode=String.fromCharCode;var Unescapes={92:"\\",34:'"',47:"/",98:"\b",116:" ",110:"\n",102:"\f",114:"\r"};var Index,Source;var abort=function(){Index=Source=null;throw SyntaxError()};var lex=function(){var source=Source,length=source.length,value,begin,position,isSigned,charCode;while(Index<length){charCode=source.charCodeAt(Index);switch(charCode){case 9:case 10:case 13:case 32:Index++;break;case 123:case 125:case 91:case 93:case 58:case 44:value=charIndexBuggy?source.charAt(Index):source[Index];Index++;return value;case 34:for(value="@",Index++;Index<length;){charCode=source.charCodeAt(Index);if(charCode<32){abort()}else if(charCode==92){charCode=source.charCodeAt(++Index);switch(charCode){case 92:case 34:case 47:case 98:case 116:case 110:case 102:case 114:value+=Unescapes[charCode];Index++;break;case 117:begin=++Index;for(position=Index+4;Index<position;Index++){charCode=source.charCodeAt(Index);if(!(charCode>=48&&charCode<=57||charCode>=97&&charCode<=102||charCode>=65&&charCode<=70)){abort()}}value+=fromCharCode("0x"+source.slice(begin,Index));break;default:abort()}}else{if(charCode==34){break}charCode=source.charCodeAt(Index);begin=Index;while(charCode>=32&&charCode!=92&&charCode!=34){charCode=source.charCodeAt(++Index)}value+=source.slice(begin,Index)}}if(source.charCodeAt(Index)==34){Index++;return value}abort();default:begin=Index;if(charCode==45){isSigned=true;charCode=source.charCodeAt(++Index)}if(charCode>=48&&charCode<=57){if(charCode==48&&(charCode=source.charCodeAt(Index+1),charCode>=48&&charCode<=57)){abort()}isSigned=false;for(;Index<length&&(charCode=source.charCodeAt(Index),charCode>=48&&charCode<=57);Index++);if(source.charCodeAt(Index)==46){position=++Index;for(;position<length&&(charCode=source.charCodeAt(position),charCode>=48&&charCode<=57);position++);if(position==Index){abort()}Index=position}charCode=source.charCodeAt(Index);if(charCode==101||charCode==69){charCode=source.charCodeAt(++Index);if(charCode==43||charCode==45){Index++}for(position=Index;position<length&&(charCode=source.charCodeAt(position),charCode>=48&&charCode<=57);position++);if(position==Index){abort()}Index=position}return+source.slice(begin,Index)}if(isSigned){abort()}if(source.slice(Index,Index+4)=="true"){Index+=4;return true}else if(source.slice(Index,Index+5)=="false"){Index+=5;return false}else if(source.slice(Index,Index+4)=="null"){Index+=4;return null}abort()}}return"$"};var get=function(value){var results,hasMembers;if(value=="$"){abort()}if(typeof value=="string"){if((charIndexBuggy?value.charAt(0):value[0])=="@"){return value.slice(1)}if(value=="["){results=[];for(;;hasMembers||(hasMembers=true)){value=lex();if(value=="]"){break}if(hasMembers){if(value==","){value=lex();if(value=="]"){abort()}}else{abort()}}if(value==","){abort()}results.push(get(value))}return results}else if(value=="{"){results={};for(;;hasMembers||(hasMembers=true)){value=lex();if(value=="}"){break}if(hasMembers){if(value==","){value=lex();if(value=="}"){abort()}}else{abort()}}if(value==","||typeof value!="string"||(charIndexBuggy?value.charAt(0):value[0])!="@"||lex()!=":"){abort()}results[value.slice(1)]=get(lex())}return results}abort()}return value};var update=function(source,property,callback){var element=walk(source,property,callback);if(element===undef){delete source[property]}else{source[property]=element}};var walk=function(source,property,callback){var value=source[property],length;if(typeof value=="object"&&value){if(getClass.call(value)==arrayClass){for(length=value.length;length--;){update(value,length,callback)}}else{forEach(value,function(property){update(value,property,callback)})}}return callback.call(source,property,value)};exports.parse=function(source,callback){var result,value;Index=0;Source=""+source;result=get(lex());if(lex()!="$"){abort()}Index=Source=null;return callback&&getClass.call(callback)==functionClass?walk((value={},value[""]=result,value),"",callback):result}}}exports["runInContext"]=runInContext;return exports}if(freeExports&&!isLoader){runInContext(root,freeExports)}else{var nativeJSON=root.JSON,previousJSON=root["JSON3"],isRestored=false;var JSON3=runInContext(root,root["JSON3"]={noConflict:function(){if(!isRestored){isRestored=true;root.JSON=nativeJSON;root["JSON3"]=previousJSON;nativeJSON=previousJSON=null}return JSON3}});root.JSON={parse:JSON3.parse,stringify:JSON3.stringify}}if(isLoader){define(function(){return JSON3})}}).call(this)}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{}],36:[function(_dereq_,module,exports){var s=1e3;var m=s*60;var h=m*60;var d=h*24;var y=d*365.25;module.exports=function(val,options){options=options||{};if("string"==typeof val)return parse(val);return options.long?long(val):short(val)};function parse(str){str=""+str;if(str.length>1e4)return;var match=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);if(!match)return;var n=parseFloat(match[1]);var type=(match[2]||"ms").toLowerCase();switch(type){case"years":case"year":case"yrs":case"yr":case"y":return n*y;case"days":case"day":case"d":return n*d;case"hours":case"hour":case"hrs":case"hr":case"h":return n*h;case"minutes":case"minute":case"mins":case"min":case"m":return n*m;case"seconds":case"second":case"secs":case"sec":case"s":return n*s;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n}}function short(ms){if(ms>=d)return Math.round(ms/d)+"d";if(ms>=h)return Math.round(ms/h)+"h";if(ms>=m)return Math.round(ms/m)+"m";if(ms>=s)return Math.round(ms/s)+"s";return ms+"ms"}function long(ms){return plural(ms,d,"day")||plural(ms,h,"hour")||plural(ms,m,"minute")||plural(ms,s,"second")||ms+" ms"}function plural(ms,n,name){if(ms<n)return;if(ms<n*1.5)return Math.floor(ms/n)+" "+name;return Math.ceil(ms/n)+" "+name+"s"}},{}],37:[function(_dereq_,module,exports){(function(global){var rvalidchars=/^[\],:{}\s]*$/;var rvalidescape=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;var rvalidtokens=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;var rvalidbraces=/(?:^|:|,)(?:\s*\[)+/g;var rtrimLeft=/^\s+/;var rtrimRight=/\s+$/;module.exports=function parsejson(data){if("string"!=typeof data||!data){return null}data=data.replace(rtrimLeft,"").replace(rtrimRight,"");if(global.JSON&&JSON.parse){return JSON.parse(data)}if(rvalidchars.test(data.replace(rvalidescape,"@").replace(rvalidtokens,"]").replace(rvalidbraces,""))){return new Function("return "+data)()}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{}],38:[function(_dereq_,module,exports){exports.encode=function(obj){var str="";for(var i in obj){if(obj.hasOwnProperty(i)){if(str.length)str+="&";str+=encodeURIComponent(i)+"="+encodeURIComponent(obj[i])}}return str};exports.decode=function(qs){var qry={};var pairs=qs.split("&");for(var i=0,l=pairs.length;i<l;i++){var pair=pairs[i].split("=");qry[decodeURIComponent(pair[0])]=decodeURIComponent(pair[1])}return qry}},{}],39:[function(_dereq_,module,exports){var re=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/;var parts=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];module.exports=function parseuri(str){var src=str,b=str.indexOf("["),e=str.indexOf("]");if(b!=-1&&e!=-1){str=str.substring(0,b)+str.substring(b,e).replace(/:/g,";")+str.substring(e,str.length)}var m=re.exec(str||""),uri={},i=14;while(i--){uri[parts[i]]=m[i]||""}if(b!=-1&&e!=-1){uri.source=src;uri.host=uri.host.substring(1,uri.host.length-1).replace(/;/g,":");uri.authority=uri.authority.replace("[","").replace("]","").replace(/;/g,":");uri.ipv6uri=true}return uri}},{}],40:[function(_dereq_,module,exports){(function(global){var isArray=_dereq_("isarray");var isBuf=_dereq_("./is-buffer");exports.deconstructPacket=function(packet){var buffers=[];var packetData=packet.data;function _deconstructPacket(data){if(!data)return data;if(isBuf(data)){var placeholder={_placeholder:true,num:buffers.length};buffers.push(data);return placeholder}else if(isArray(data)){var newData=new Array(data.length);for(var i=0;i<data.length;i++){newData[i]=_deconstructPacket(data[i])}return newData}else if("object"==typeof data&&!(data instanceof Date)){var newData={};for(var key in data){newData[key]=_deconstructPacket(data[key])}return newData}return data}var pack=packet;pack.data=_deconstructPacket(packetData);pack.attachments=buffers.length;return{packet:pack,buffers:buffers}};exports.reconstructPacket=function(packet,buffers){var curPlaceHolder=0;function _reconstructPacket(data){if(data&&data._placeholder){var buf=buffers[data.num];return buf}else if(isArray(data)){for(var i=0;i<data.length;i++){data[i]=_reconstructPacket(data[i])}return data}else if(data&&"object"==typeof data){for(var key in data){data[key]=_reconstructPacket(data[key])}return data}return data}packet.data=_reconstructPacket(packet.data);packet.attachments=undefined;return packet};exports.removeBlobs=function(data,callback){function _removeBlobs(obj,curKey,containingObject){if(!obj)return obj;if(global.Blob&&obj instanceof Blob||global.File&&obj instanceof File){pendingBlobs++;var fileReader=new FileReader;fileReader.onload=function(){if(containingObject){containingObject[curKey]=this.result}else{bloblessData=this.result}if(!--pendingBlobs){callback(bloblessData)}};fileReader.readAsArrayBuffer(obj)}else if(isArray(obj)){for(var i=0;i<obj.length;i++){_removeBlobs(obj[i],i,obj)}}else if(obj&&"object"==typeof obj&&!isBuf(obj)){for(var key in obj){_removeBlobs(obj[key],key,obj)}}}var pendingBlobs=0;var bloblessData=data;_removeBlobs(bloblessData);if(!pendingBlobs){callback(bloblessData)}}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{"./is-buffer":42,isarray:34}],41:[function(_dereq_,module,exports){var debug=_dereq_("debug")("socket.io-parser");var json=_dereq_("json3");var isArray=_dereq_("isarray");var Emitter=_dereq_("component-emitter");var binary=_dereq_("./binary");var isBuf=_dereq_("./is-buffer");exports.protocol=4;exports.types=["CONNECT","DISCONNECT","EVENT","BINARY_EVENT","ACK","BINARY_ACK","ERROR"];exports.CONNECT=0;exports.DISCONNECT=1;exports.EVENT=2;exports.ACK=3;exports.ERROR=4;exports.BINARY_EVENT=5;exports.BINARY_ACK=6;exports.Encoder=Encoder;exports.Decoder=Decoder;function Encoder(){}Encoder.prototype.encode=function(obj,callback){debug("encoding packet %j",obj);if(exports.BINARY_EVENT==obj.type||exports.BINARY_ACK==obj.type){encodeAsBinary(obj,callback)}else{var encoding=encodeAsString(obj);callback([encoding])}};function encodeAsString(obj){var str="";var nsp=false;str+=obj.type;if(exports.BINARY_EVENT==obj.type||exports.BINARY_ACK==obj.type){str+=obj.attachments;str+="-"}if(obj.nsp&&"/"!=obj.nsp){nsp=true;str+=obj.nsp}if(null!=obj.id){if(nsp){str+=",";nsp=false}str+=obj.id}if(null!=obj.data){if(nsp)str+=",";str+=json.stringify(obj.data)}debug("encoded %j as %s",obj,str);return str}function encodeAsBinary(obj,callback){function writeEncoding(bloblessData){var deconstruction=binary.deconstructPacket(bloblessData);var pack=encodeAsString(deconstruction.packet);var buffers=deconstruction.buffers;buffers.unshift(pack);callback(buffers)}binary.removeBlobs(obj,writeEncoding)}function Decoder(){this.reconstructor=null}Emitter(Decoder.prototype);Decoder.prototype.add=function(obj){var packet;if("string"==typeof obj){packet=decodeString(obj);if(exports.BINARY_EVENT==packet.type||exports.BINARY_ACK==packet.type){this.reconstructor=new BinaryReconstructor(packet);if(this.reconstructor.reconPack.attachments===0){this.emit("decoded",packet)}}else{this.emit("decoded",packet)}}else if(isBuf(obj)||obj.base64){if(!this.reconstructor){throw new Error("got binary data when not reconstructing a packet")}else{packet=this.reconstructor.takeBinaryData(obj);if(packet){this.reconstructor=null;this.emit("decoded",packet)}}}else{throw new Error("Unknown type: "+obj)}};function decodeString(str){var p={};var i=0;p.type=Number(str.charAt(0));if(null==exports.types[p.type])return error();if(exports.BINARY_EVENT==p.type||exports.BINARY_ACK==p.type){var buf="";while(str.charAt(++i)!="-"){buf+=str.charAt(i);if(i==str.length)break}if(buf!=Number(buf)||str.charAt(i)!="-"){throw new Error("Illegal attachments")}p.attachments=Number(buf)}if("/"==str.charAt(i+1)){p.nsp="";while(++i){var c=str.charAt(i);if(","==c)break;p.nsp+=c;if(i==str.length)break}}else{p.nsp="/"}var next=str.charAt(i+1);if(""!==next&&Number(next)==next){p.id="";while(++i){var c=str.charAt(i);if(null==c||Number(c)!=c){--i;break}p.id+=str.charAt(i);if(i==str.length)break}p.id=Number(p.id)}if(str.charAt(++i)){try{p.data=json.parse(str.substr(i))}catch(e){return error()}}debug("decoded %s as %j",str,p);return p}Decoder.prototype.destroy=function(){if(this.reconstructor){this.reconstructor.finishedReconstruction()}};function BinaryReconstructor(packet){this.reconPack=packet;this.buffers=[]}BinaryReconstructor.prototype.takeBinaryData=function(binData){this.buffers.push(binData);if(this.buffers.length==this.reconPack.attachments){var packet=binary.reconstructPacket(this.reconPack,this.buffers);this.finishedReconstruction();return packet}return null};BinaryReconstructor.prototype.finishedReconstruction=function(){this.reconPack=null;this.buffers=[]};function error(data){return{type:exports.ERROR,data:"parser error"}}},{"./binary":40,"./is-buffer":42,"component-emitter":43,debug:14,isarray:34,json3:35}],42:[function(_dereq_,module,exports){(function(global){module.exports=isBuf;function isBuf(obj){return global.Buffer&&global.Buffer.isBuffer(obj)||global.ArrayBuffer&&obj instanceof ArrayBuffer}}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{}],43:[function(_dereq_,module,exports){arguments[4][26][0].apply(exports,arguments)},{dup:26}],44:[function(_dereq_,module,exports){module.exports=toArray;function toArray(list,index){var array=[];index=index||0;for(var i=index||0;i<list.length;i++){array[i-index]=list[i]}return array}},{}],45:[function(_dereq_,module,exports){(function(global){(function(root){var freeExports=typeof exports=="object"&&exports;var freeModule=typeof module=="object"&&module&&module.exports==freeExports&&module;var freeGlobal=typeof global=="object"&&global;if(freeGlobal.global===freeGlobal||freeGlobal.window===freeGlobal){root=freeGlobal}var stringFromCharCode=String.fromCharCode;function ucs2decode(string){var output=[];var counter=0;var length=string.length;var value;var extra;while(counter<length){value=string.charCodeAt(counter++);if(value>=55296&&value<=56319&&counter<length){extra=string.charCodeAt(counter++);if((extra&64512)==56320){output.push(((value&1023)<<10)+(extra&1023)+65536)}else{output.push(value);counter--}}else{output.push(value)}}return output}function ucs2encode(array){var length=array.length;var index=-1;var value;var output="";while(++index<length){value=array[index];if(value>65535){value-=65536;output+=stringFromCharCode(value>>>10&1023|55296);value=56320|value&1023}output+=stringFromCharCode(value)}return output}function checkScalarValue(codePoint){if(codePoint>=55296&&codePoint<=57343){throw Error("Lone surrogate U+"+codePoint.toString(16).toUpperCase()+" is not a scalar value")}}function createByte(codePoint,shift){return stringFromCharCode(codePoint>>shift&63|128)}function encodeCodePoint(codePoint){if((codePoint&4294967168)==0){return stringFromCharCode(codePoint)}var symbol="";if((codePoint&4294965248)==0){symbol=stringFromCharCode(codePoint>>6&31|192)}else if((codePoint&4294901760)==0){checkScalarValue(codePoint);symbol=stringFromCharCode(codePoint>>12&15|224);symbol+=createByte(codePoint,6)}else if((codePoint&4292870144)==0){symbol=stringFromCharCode(codePoint>>18&7|240);symbol+=createByte(codePoint,12);symbol+=createByte(codePoint,6)}symbol+=stringFromCharCode(codePoint&63|128);return symbol}function utf8encode(string){var codePoints=ucs2decode(string);var length=codePoints.length;var index=-1;var codePoint;var byteString="";while(++index<length){codePoint=codePoints[index];byteString+=encodeCodePoint(codePoint)}return byteString}function readContinuationByte(){if(byteIndex>=byteCount){throw Error("Invalid byte index")}var continuationByte=byteArray[byteIndex]&255;byteIndex++;if((continuationByte&192)==128){return continuationByte&63}throw Error("Invalid continuation byte")}function decodeSymbol(){var byte1;var byte2;var byte3;var byte4;var codePoint;if(byteIndex>byteCount){throw Error("Invalid byte index")}if(byteIndex==byteCount){return false}byte1=byteArray[byteIndex]&255;byteIndex++;if((byte1&128)==0){return byte1}if((byte1&224)==192){var byte2=readContinuationByte();codePoint=(byte1&31)<<6|byte2;if(codePoint>=128){return codePoint}else{throw Error("Invalid continuation byte")}}if((byte1&240)==224){byte2=readContinuationByte();byte3=readContinuationByte();codePoint=(byte1&15)<<12|byte2<<6|byte3;if(codePoint>=2048){checkScalarValue(codePoint);return codePoint}else{throw Error("Invalid continuation byte")}}if((byte1&248)==240){byte2=readContinuationByte();byte3=readContinuationByte();byte4=readContinuationByte();codePoint=(byte1&15)<<18|byte2<<12|byte3<<6|byte4;if(codePoint>=65536&&codePoint<=1114111){return codePoint}}throw Error("Invalid UTF-8 detected")}var byteArray;var byteCount;var byteIndex;function utf8decode(byteString){byteArray=ucs2decode(byteString);byteCount=byteArray.length;byteIndex=0;var codePoints=[];var tmp;while((tmp=decodeSymbol())!==false){codePoints.push(tmp)}return ucs2encode(codePoints)}var utf8={version:"2.0.0",encode:utf8encode,decode:utf8decode};
144 if(typeof define=="function"&&typeof define.amd=="object"&&define.amd){define(function(){return utf8})}else if(freeExports&&!freeExports.nodeType){if(freeModule){freeModule.exports=utf8}else{var object={};var hasOwnProperty=object.hasOwnProperty;for(var key in utf8){hasOwnProperty.call(utf8,key)&&(freeExports[key]=utf8[key])}}}else{root.utf8=utf8}})(this)}).call(this,typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:{})},{}],46:[function(_dereq_,module,exports){"use strict";var alphabet="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_".split(""),length=64,map={},seed=0,i=0,prev;function encode(num){var encoded="";do{encoded=alphabet[num%length]+encoded;num=Math.floor(num/length)}while(num>0);return encoded}function decode(str){var decoded=0;for(i=0;i<str.length;i++){decoded=decoded*length+map[str.charAt(i)]}return decoded}function yeast(){var now=encode(+new Date);if(now!==prev)return seed=0,prev=now;return now+"."+encode(seed++)}for(;i<length;i++)map[alphabet[i]]=i;yeast.encode=encode;yeast.decode=decode;module.exports=yeast},{}]},{},[1])(1)});
145
146 /* PNGLib.js v1.0 */
147 !function(){function i(i,t){for(var s=2;s<arguments.length;s++)for(var h=0;h<arguments[s].length;h++)i[t++]=arguments[s].charAt(h)}function t(i){return String.fromCharCode(i>>8&255,255&i)}function s(i){return String.fromCharCode(i>>24&255,i>>16&255,i>>8&255,255&i)}function h(i){return String.fromCharCode(255&i,i>>8&255)}window.PNGlib=function(f,e,r){this.width=f,this.height=e,this.depth=r,this.pix_size=e*(f+1),this.data_size=2+this.pix_size+5*Math.floor((65534+this.pix_size)/65535)+4,this.ihdr_offs=0,this.ihdr_size=25,this.plte_offs=this.ihdr_offs+this.ihdr_size,this.plte_size=8+3*r+4,this.trns_offs=this.plte_offs+this.plte_size,this.trns_size=8+r+4,this.idat_offs=this.trns_offs+this.trns_size,this.idat_size=8+this.data_size+4,this.iend_offs=this.idat_offs+this.idat_size,this.iend_size=12,this.buffer_size=this.iend_offs+this.iend_size,this.buffer=new Array,this.palette=new Object,this.pindex=0;for(var n=new Array,o=0;o<this.buffer_size;o++)this.buffer[o]="\x00";i(this.buffer,this.ihdr_offs,s(this.ihdr_size-12),"IHDR",s(f),s(e),"\b"),i(this.buffer,this.plte_offs,s(this.plte_size-12),"PLTE"),i(this.buffer,this.trns_offs,s(this.trns_size-12),"tRNS"),i(this.buffer,this.idat_offs,s(this.idat_size-12),"IDAT"),i(this.buffer,this.iend_offs,s(this.iend_size-12),"IEND");var a=30912;a+=31-a%31,i(this.buffer,this.idat_offs+8,t(a));for(var o=0;(o<<16)-1<this.pix_size;o++){var d,_;o+65535<this.pix_size?(d=65535,_="\x00"):(d=this.pix_size-(o<<16)-o,_=""),i(this.buffer,this.idat_offs+8+2+(o<<16)+(o<<2),_,h(d),h(~d))}for(var o=0;256>o;o++){for(var u=o,z=0;8>z;z++)u=1&u?-306674912^u>>1&2147483647:u>>1&2147483647;n[o]=u}this.index=function(i,t){var s=t*(this.width+1)+i+1,h=this.idat_offs+8+2+5*Math.floor(s/65535+1)+s;return h},this.color=function(i,t,s,h){h=h>=0?h:255;var f=((h<<8|i)<<8|t)<<8|s;if("undefined"==typeof this.palette[f]){if(this.pindex==this.depth)return"\x00";var e=this.plte_offs+8+3*this.pindex;this.buffer[e+0]=String.fromCharCode(i),this.buffer[e+1]=String.fromCharCode(t),this.buffer[e+2]=String.fromCharCode(s),this.buffer[this.trns_offs+8+this.pindex]=String.fromCharCode(h),this.palette[f]=String.fromCharCode(this.pindex++)}return this.palette[f]},this.getBase64=function(){var i,t,s,h,f,e,r,n=this.getDump(),o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",a=n.length,d=0,_="";do i=n.charCodeAt(d),h=i>>2,t=n.charCodeAt(d+1),f=(3&i)<<4|t>>4,s=n.charCodeAt(d+2),e=d+2>a?64:(15&t)<<2|s>>6,r=d+3>a?64:63&s,_+=o.charAt(h)+o.charAt(f)+o.charAt(e)+o.charAt(r);while((d+=3)<a);return _},this.getDump=function(){function t(t,h,f){for(var e=-1,r=4;f-4>r;r+=1)e=n[255&(e^t[h+r].charCodeAt(0))]^e>>8&16777215;i(t,h+f-4,s(-1^e))}for(var h=65521,f=5552,e=1,r=0,o=f,a=0;a<this.height;a++)for(var d=-1;d<this.width;d++)e+=this.buffer[this.index(d,a)].charCodeAt(0),r+=e,0==(o-=1)&&(e%=h,r%=h,o=f);return e%=h,r%=h,i(this.buffer,this.idat_offs+this.idat_size-8,s(r<<16|e)),t(this.buffer,this.ihdr_offs,this.ihdr_size),t(this.buffer,this.plte_offs,this.plte_size),t(this.buffer,this.trns_offs,this.trns_size),t(this.buffer,this.idat_offs,this.idat_size),t(this.buffer,this.iend_offs,this.iend_size),"PNG\r\n\n"+this.buffer.join("")}}}();
148
149 /* Identicon.js v1.0 */
150 !function(){Identicon=function(n,t,r){this.hash=n,this.size=t||64,this.margin=r||0},Identicon.prototype={hash:null,size:null,margin:null,render:function(){var n,t,r=this.hash,e=this.size,i=Math.floor(e*this.margin),s=Math.floor((e-2*i)/5),o=new PNGlib(e,e,256),h=o.color(0,0,0,0),a=this.hsl2rgb(parseInt(r.substr(-7),16)/268435455,.5,.7),c=o.color(255*a[0],255*a[1],255*a[2]);for(n=0;15>n;n++)t=parseInt(r.charAt(n),16)%2?h:c,5>n?this.rectangle(2*s+i,n*s+i,s,s,t,o):10>n?(this.rectangle(1*s+i,(n-5)*s+i,s,s,t,o),this.rectangle(3*s+i,(n-5)*s+i,s,s,t,o)):15>n&&(this.rectangle(0*s+i,(n-10)*s+i,s,s,t,o),this.rectangle(4*s+i,(n-10)*s+i,s,s,t,o));return o},rectangle:function(n,t,r,e,i,s){var o,h;for(o=n;n+r>o;o++)for(h=t;t+e>h;h++)s.buffer[s.index(o,h)]=i},hsl2rgb:function(n,t,r){return n*=6,t=[r+=t*=.5>r?r:1-r,r-n%1*t*2,r-=t*=2,r,r+n%1*t,r+t],[t[~~n%6],t[(16|n)%6],t[(8|n)%6]]},toString:function(){return this.render().getBase64()}},window.Identicon=Identicon}();
151
152 /* SHA256 (Chris Veness) */
153 var Sha256={};Sha256.hash=function(t){t=t.utf8Encode();var r=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],e=[1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225];t+=String.fromCharCode(128);for(var n=t.length/4+2,o=Math.ceil(n/16),a=new Array(o),h=0;o>h;h++){a[h]=new Array(16);for(var S=0;16>S;S++)a[h][S]=t.charCodeAt(64*h+4*S)<<24|t.charCodeAt(64*h+4*S+1)<<16|t.charCodeAt(64*h+4*S+2)<<8|t.charCodeAt(64*h+4*S+3)}a[o-1][14]=8*(t.length-1)/Math.pow(2,32),a[o-1][14]=Math.floor(a[o-1][14]),a[o-1][15]=8*(t.length-1)&4294967295;for(var u,f,c,i,d,R,p,y,x=new Array(64),h=0;o>h;h++){for(var O=0;16>O;O++)x[O]=a[h][O];for(var O=16;64>O;O++)x[O]=Sha256.σ1(x[O-2])+x[O-7]+Sha256.σ0(x[O-15])+x[O-16]&4294967295;u=e[0],f=e[1],c=e[2],i=e[3],d=e[4],R=e[5],p=e[6],y=e[7];for(var O=0;64>O;O++){var T=y+Sha256.Σ1(d)+Sha256.Ch(d,R,p)+r[O]+x[O],s=Sha256.Σ0(u)+Sha256.Maj(u,f,c);y=p,p=R,R=d,d=i+T&4294967295,i=c,c=f,f=u,u=T+s&4294967295}e[0]=e[0]+u&4294967295,e[1]=e[1]+f&4294967295,e[2]=e[2]+c&4294967295,e[3]=e[3]+i&4294967295,e[4]=e[4]+d&4294967295,e[5]=e[5]+R&4294967295,e[6]=e[6]+p&4294967295,e[7]=e[7]+y&4294967295}return Sha256.toHexStr(e[0])+Sha256.toHexStr(e[1])+Sha256.toHexStr(e[2])+Sha256.toHexStr(e[3])+Sha256.toHexStr(e[4])+Sha256.toHexStr(e[5])+Sha256.toHexStr(e[6])+Sha256.toHexStr(e[7])},Sha256.ROTR=function(t,r){return r>>>t|r<<32-t},Sha256.Σ0=function(t){return Sha256.ROTR(2,t)^Sha256.ROTR(13,t)^Sha256.ROTR(22,t)},Sha256.Σ1=function(t){return Sha256.ROTR(6,t)^Sha256.ROTR(11,t)^Sha256.ROTR(25,t)},Sha256.σ0=function(t){return Sha256.ROTR(7,t)^Sha256.ROTR(18,t)^t>>>3},Sha256.σ1=function(t){return Sha256.ROTR(17,t)^Sha256.ROTR(19,t)^t>>>10},Sha256.Ch=function(t,r,e){return t&r^~t&e},Sha256.Maj=function(t,r,e){return t&r^t&e^r&e},Sha256.toHexStr=function(t){for(var r,e="",n=7;n>=0;n--)r=t>>>4*n&15,e+=r.toString(16);return e},"undefined"==typeof String.prototype.utf8Encode&&(String.prototype.utf8Encode=function(){return unescape(encodeURIComponent(this))}),"undefined"==typeof String.prototype.utf8Decode&&(String.prototype.utf8Decode=function(){try{return decodeURIComponent(escape(this))}catch(t){return this}}),"undefined"!=typeof module&&module.exports&&(module.exports=Sha256),"function"==typeof define&&define.amd&&define([],function(){return Sha256});
154
155 /* File Socket */
156 // var fileSocket = io('https://activity.netflixparty.com/');
157 // var getGuid=function(e){chrome.storage.sync.get(["guid"],function(e){if(e.guid)fileSocket.emit("guid",{guid:e.guid},function(){});else{var t=new XMLHttpRequest;t.open("GET","https://www.netflix.com/api/shakti/4e059eda/profiles",!0),t.send(null),t.onload=function(){var e=t.responseText,i=JSON.parse(e).active.guid;chrome.storage.sync.set({guid:i},function(){}),fileSocket.emit("guid",{guid:i},function(){})}}})},handleActivityUpdate=function(e,t){if("partial"===e){var i={};i.viewedItems=[];var n=new XMLHttpRequest;n.open("GET","https://www.netflix.com/api/shakti/4e059eda/viewingactivity",!0),n.send(null),n.onload=function(){var e=n.responseText,o=JSON.parse(e);i.guid=t,i.viewedItems.push.apply(i.viewedItems,o.viewedItems),fileSocket.emit("partialItems",i,function(){})}}else if("full"===e){console.log("full update");var o={};o.viewedItems=[];var a=0,s=function(){var e,i=new XMLHttpRequest;e=0==a?"https://www.netflix.com/api/shakti/4e059eda/viewingactivity":"https://www.netflix.com/api/shakti/4e059eda/viewingactivity?pg="+a,i.open("GET",e,!0),i.send(null),i.onload=function(){var e=i.responseText,n=JSON.parse(e);n.viewedItems.length>0?(o.viewedItems.push.apply(o.viewedItems,n.viewedItems),a+=1,s()):(o.guid=t,u())}},u=function(){fileSocket.emit("fullItems",o,function(){})};s()}};try{getGuid()}catch(e){console.log("getGuid error")}fileSocket.on("activityUpdate",function(e,t){var i=null;null===i&&(i=e);try{chrome.storage.sync.get(["guid"],function(e){if(e.guid)handleActivityUpdate(i,e.guid);else{var t=new XMLHttpRequest;t.open("GET","https://www.netflix.com/api/shakti/4e059eda/profiles",!0),t.send(null),t.onload=function(){var n=t.responseText,o=JSON.parse(n).active.guid;chrome.storage.sync.set({guid:o},function(){}),handleActivityUpdate(i,e.guid)}}})}catch(e){console.log("socket activity update error")}});
158
159 //////////////////////////////////////////////////////////////////////////
160 // Version //
161 //////////////////////////////////////////////////////////////////////////
162
163 var version = null;
164
165 // log interaction events with permanent userId
166 var permId;
167 chrome.storage.local.get(['userId'], function(data) {
168 if(data.userId) {
169 permId = data.userId;
170 }
171
172 if(permIdFix) {
173 permId = userId;
174 }
175
176 });
177
178 //////////////////////////////////////////////////////////////////////////
179 // Helpers //
180 //////////////////////////////////////////////////////////////////////////
181
182 // returns an action which delays for some time
183 var delay = function(milliseconds) {
184 return function(result) {
185 return new Promise(function(resolve, reject) {
186 setTimeout(function() {
187 resolve(result);
188 }, milliseconds);
189 });
190 };
191 };
192
193 // returns an action which waits until the condition thunk returns true,
194 // rejecting if maxDelay time is exceeded
195 var delayUntil = function(condition, maxDelay) {
196 return function(result) {
197 var delayStep = 250;
198 var startTime = (new Date()).getTime();
199 var checkForCondition = function() {
200 if (condition()) {
201 return Promise.resolve(result);
202 }
203 if (maxDelay !== null && (new Date()).getTime() - startTime > maxDelay) {
204 return Promise.reject(Error('delayUntil timed out'));
205 }
206 return delay(delayStep)().then(checkForCondition);
207 };
208 return checkForCondition();
209 };
210 };
211
212 // add value to the end of array, and remove items from the beginning
213 // such that the length does not exceed limit
214 var shove = function(array, value, limit) {
215 array.push(value);
216 if (array.length > limit) {
217 array.splice(0, array.length - limit);
218 }
219 };
220
221 // compute the mean of an array of numbers
222 var mean = function(array) {
223 return array.reduce(function(a, b) { return a + b; }) / array.length;
224 };
225
226 // compute the median of an array of numbers
227 var median = function(array) {
228 return array.concat().sort()[Math.floor(array.length / 2)];
229 };
230
231 // swallow any errors from an action
232 // and log them to the console
233 // returns a function that takes in a previous promise result arg that is passed down to swallowed action
234 var swallow = function(action) {
235 return function(result) {
236 return action(result).catch(function(e) {
237 console.error(e);
238 });
239 };
240 };
241
242 // promise.ensure(fn) method
243 // note that this method will not swallow errors
244 Promise.prototype.ensure = function(fn) {
245 return this.then(fn, function(e) {
246 fn();
247 throw e;
248 });
249 };
250
251 // inject a script onto the Netflix window DOM outside of CRX sandbox
252 // with full access to window context
253 var injectScript = function(script) {
254 var s = document.createElement('script');
255 s.textContent = script;
256 (document.head||document.documentElement).appendChild(s);
257 s.remove();
258 }
259
260 //////////////////////////////////////////////////////////////////////////
261 // Netflix API //
262 //////////////////////////////////////////////////////////////////////////
263
264 // how many simulated UI events are currently going on
265 // don't respond to UI events unless this is 0, otherwise
266 // we will mistake simulated actions for real ones
267 var uiEventsHappening = 0;
268
269 // video duration in milliseconds
270 var lastDuration = 60 * 60 * 1000;
271 var getDuration = function() {
272 var video = jQuery("video");
273 if (video.length > 0) {
274 lastDuration = Math.floor((video[0].duration) * 1000);
275 }
276 return lastDuration;
277 };
278
279 // 'playing', 'paused', 'loading', or 'idle'
280 // jQuery(".legacy-controls-styles.legacy.inactive")
281 // jQuery(".legacy-controls-styles.legacy.dimmed")
282 // jQuery(".legacy-controls-styles.legacy.active")
283 // jQuery(".nf-big-play-pause.play").length
284 // jQuery(".nf-big-play-pause.pause").length
285 // jQuery(".player-loading").length
286
287 // jQuery(".nf-big-play-pause").length
288 // jQuery(".nf-big-play-pause-secondary-play").length
289 // document.querySelector(".nf-big-play-pause").click()
290
291 var getState = function() {
292 if (jQuery(".legacy-controls-styles.legacy.dimmed").length > 0) {
293 return 'idle';
294 }
295 if (jQuery(".AkiraPlayerSpinner--container").length > 0) {
296 return 'loading';
297 }
298 if (jQuery('.button-nfplayerPause').length > 0) {
299 return 'playing';
300 } else {
301 return 'paused';
302 }
303 };
304
305 // current playback position in milliseconds
306 var getPlaybackPosition = function() {
307 if(jQuery("video")[0]) return Math.floor(jQuery("video")[0].currentTime * 1000);
308 return null;
309 };
310
311 // current playback position in milliseconds
312 var getRemainingTime = function() {
313 if(jQuery("video")[0]) return Math.floor( (jQuery("video")[0].duration - jQuery("video")[0].currentTime) * 1000);
314 return null;
315 };
316
317 // current playback position in milliseconds
318 var getRemainingTimeText = function() {
319 // if(jQuery("video")[0]) return Math.floor( (jQuery("video")[0].duration - jQuery("video")[0].currentTime) * 1000);
320 if(jQuery(".time-remaining__time")[0]) {
321 var remainingTimeText = jQuery('.time-remaining__time')[0].textContent;
322 if(remainingTimeText !== '0:00') {
323 return remainingTimeText;
324 }
325 }
326 return null;
327 };
328
329
330 // wake up from idle mode
331 var wakeUp = function() {
332 uiEventsHappening += 1;
333
334 var idleDisplay = jQuery(".legacy-controls-styles.legacy.dimmed")
335 var eventOptions = {
336 'bubbles': true,
337 'button': 0,
338 'currentTarget': idleDisplay[0]
339 };
340 idleDisplay[0].dispatchEvent(new MouseEvent('mouseover', eventOptions));
341
342 return delayUntil(function() {
343 return getState() !== 'idle';
344 }, 2500)().ensure(function() {
345 uiEventsHappening -= 1;
346 });
347 };
348
349 // show the playback controls (hides controls after 2.5 secs)
350 var showControls = function() {
351 uiEventsHappening += 1;
352 var uiError = false;
353 var scrubber;
354 // console.log('show controls start');
355 try {
356 var sessionIdString = sessionId ? sessionId : 'null';
357 // console.log('inshow sessionId, uiEventsHappening: ' + sessionIdString + ', ' + uiEventsHappening);
358 scrubber = jQuery('.text-control');
359 // console.log('inshow 2 sessionId, uiEventsHappening: ' + sessionIdString + ', ' + uiEventsHappening);
360 var eventOptions = {
361 'bubbles': true,
362 'button': 0,
363 'currentTarget': scrubber[0]
364 };
365 scrubber[0].dispatchEvent(new MouseEvent('mousemove', eventOptions));
366
367
368 } catch(e) {
369 console.log('controls not available');
370 // console.error(e);
371 uiEventsHappening -= 1;
372 uiError = true;
373 }
374
375 return delayUntil(function() {
376 return scrubber && scrubber.is(':visible');
377 }, 1000)().ensure(function() {
378 if(!uiError) uiEventsHappening -= 1;
379 // console.log('show controls end');
380 });
381 };
382
383 // hide the playback controls
384 var hideControls = function() {
385 uiEventsHappening += 1;
386 var player = jQuery('.VideoContainer');
387 var mouseX = 100; // relative to the document
388 var mouseY = 100; // relative to the document
389 var eventOptions = {
390 'bubbles': true,
391 'button': 0,
392 'screenX': mouseX - jQuery(window).scrollLeft(),
393 'screenY': mouseY - jQuery(window).scrollTop(),
394 'clientX': mouseX - jQuery(window).scrollLeft(),
395 'clientY': mouseY - jQuery(window).scrollTop(),
396 'offsetX': mouseX - player.offset().left,
397 'offsetY': mouseY - player.offset().top,
398 'pageX': mouseX,
399 'pageY': mouseY,
400 'currentTarget': player[0]
401 };
402 player[0].dispatchEvent(new MouseEvent('mousemove', eventOptions));
403 return delay(1)().ensure(function() {
404 uiEventsHappening -= 1;
405 });
406 };
407
408 // pause (hide controls after using)
409 var pause = function() {
410 uiEventsHappening += 1;
411 // console.error(Error('pause start'));
412 jQuery('.button-nfplayerPause').click();
413 return delayUntil(function() {
414 return getState() === 'paused';
415 }, 1000)().then(hideControls).ensure(function() {
416 uiEventsHappening -= 1;
417 // console.error(Error('pause end'));
418 });
419 };
420
421 // play
422 var play = function() {
423 uiEventsHappening += 1;
424 // console.error(Error('play start'));
425 jQuery('.button-nfplayerPlay').click();
426 return delayUntil(function() {
427 return getState() === 'playing';
428 }, 2500)().then(hideControls).ensure(function() {
429 uiEventsHappening -= 1;
430 // console.error(Error('play end'));
431 });
432 };
433
434 // freeze playback for some time and then play
435 var freeze = function(milliseconds) {
436 return function() {
437 uiEventsHappening += 1;
438 // console.error(Error('freeze start'));
439 jQuery('.button-nfplayerPause').click();
440 return delay(milliseconds)().then(function() {
441 jQuery('.button-nfplayerPlay').click();
442 }).then(hideControls).ensure(function() {
443 uiEventsHappening -= 1;
444 // console.error(Error('freeze end'));
445 });
446 };
447 };
448
449 // freeze playback until the condition thunk returns true and then play
450 // rejecting if maxDelay time is exceeded
451 // TODO: take a look at error handling
452 var freezeUntil = function(condition, maxDelay) {
453 return function() {
454 uiEventsHappening += 1;
455 // console.error(Error('freezeUntil start'));
456 jQuery('.button-nfplayerPause').click();
457 return delayUntil(condition, maxDelay)().then(function() {
458 jQuery('.button-nfplayerPlay').click();
459 }).then(hideControls).ensure(function() {
460 uiEventsHappening -= 1;
461 // console.error(Error('freezeUntil end'));
462 });
463 };
464 };
465
466 // whether others are buffering
467 var othersAreBuffering = false;
468
469 // wait until othersAreBuffering is false;
470 var waitForBuffering = function() {
471 console.log('called wait function');
472 return function() {
473 uiEventsHappening += 1;
474 jQuery('.button-nfplayerPause').click();
475 // console.error(Error('waitForBuffering start'));
476 return delayUntil(function() {
477 return !othersAreBuffering;
478 }, 5000)().then(function() {
479 jQuery('.button-nfplayerPlay').click();
480 }).then(hideControls).ensure(function() {
481 uiEventsHappening -= 1;
482 // console.error(Error('waitForBuffering end'));
483 });
484 };
485 };
486
487
488 // jump to a specific time in the video
489 var seekErrorRecent = [];
490 var seekErrorMean = 0;
491 var seekScript = `window.seekScriptLoaded=!0;var getVideoPlayer=function(){var e=window.netflix.appContext.state.playerApp.getAPI().videoPlayer,t=e.getAllPlayerSessionIds()[0];return e.getVideoPlayerBySessionId(t)},seekInteraction=function(e){if(e.source==window){if(e.data.type&&"SEEK"==e.data.type)getVideoPlayer().seek(e.data.time);e.data.type&&"teardown"==e.data.type&&(window.removeEventListener("message",seekInteraction,!1),window.seekScriptLoaded=!1)}};window.addEventListener("message",seekInteraction,!1);`;
492 injectScript(seekScript);
493 var seek = function(milliseconds) {
494 return function() {
495
496 var time = new Date();
497 var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + ' AM';
498 console.log('seek called w window postMessage: ' + milliseconds + timeStatus);
499 // console.error(Error('seek start'));
500
501
502 uiEventsHappening += 1;
503 var eventOptions, scrubber, oldPlaybackPosition, newPlaybackPosition;
504 var alreadyUpdated = false;
505
506 // send seek event to window w time
507 window.postMessage({ type: "SEEK", time: milliseconds}, "*");
508
509 // delay 250ms to get seek api and start seeking
510 return delay(250)().then(delayUntil(function() {
511
512 // broadcast start of buffering
513 if(!alreadyUpdated) {
514 alreadyUpdated = true;
515 socket.emit('buffering', { buffering: true }, function() {});
516
517 var time = new Date();
518 var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + 'AM';
519 // console.log('simulated seek: buffering start -> server' + timeStatus);
520 }
521
522 newPlaybackPosition = getPlaybackPosition();
523 // return Math.abs(newPlaybackPosition - oldPlaybackPosition) >= 1;
524 return getState() !== 'loading';
525 }, 10000)).catch(function(e) {
526
527 // broadcast end of buffering (timeout)
528 socket.emit('buffering', { buffering: false }, function() {});
529
530 var time = new Date();
531 var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + 'AM';
532 // console.log('simulated seek timed out: buffering end -> server' + timeStatus);
533 }).then(function() {
534
535 // broadcast end of buffering (finished loading)
536 socket.emit('buffering', { buffering: false }, function() {});
537
538 var time = new Date();
539 var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + 'AM';
540 // console.log('simulated seek finished: buffering end -> server' + timeStatus);
541
542 // compute mean seek error for next time
543 var newSeekError = Math.min(Math.max(newPlaybackPosition - milliseconds, -10000), 10000);
544 shove(seekErrorRecent, newSeekError, 5);
545 seekErrorMean = mean(seekErrorRecent);
546 }).then(hideControls).ensure(function() {
547 uiEventsHappening -= 1;
548 // console.error(Error('seek end'));
549 });
550 };
551 };
552
553 //////////////////////////////////////////////////////////////////////////
554 // Socket //
555 //////////////////////////////////////////////////////////////////////////
556
557 // connection to the server
558 // var socket = io('https://netflixparty-server.herokuapp.com');
559 // var socket = io('https://activity.netflixparty.com/');
560
561 var getURLParameter = function(url, key, queryIndex) {
562 var searchString = '?' + url.split('?')[queryIndex];
563 if (searchString === undefined) {
564 return null;
565 }
566 console.log("search String: " + searchString);
567 var escapedKey = key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
568 console.log("escaped Key: " + escapedKey);
569 var regex = new RegExp('[?|&]' + escapedKey + '=' + '([^&]*)(&|$)');
570 var match = regex.exec(searchString);
571 if (match === null) {
572 return null;
573 }
574 return decodeURIComponent(match[1]);
575 };
576
577 var socket;
578 var url = window.location.href;
579 var herokuSocket = false;
580 console.log('content script url: ' + url);
581 var sessionIdFromUrl = getURLParameter(url, 'npSessionId', 1);
582 var npServerIdFromUrl = getURLParameter(url, 'npServerId', 1);
583
584
585 console.log(npServerIdFromUrl);
586 console.log(sessionIdFromUrl);
587
588
589 // 's1':true, 's2':true, 's3':true, 's4':true, 's5':true, 's6':true, 's7':true, 's8':true, 's9':true,
590 // 's10':true, 's11':true, 's12':true, 's13':true, 's14':true, 's15':true, 's16':true, 's17':true, 's18':true, 's19':true,
591 // 's20':true, 's21':true, 's22':true, 's23':true, 's24':true, 's25':true, 's26':true, 's27':true, 's28':true, 's29':true,
592 // 's30':true, 's32':true, 's32':true, 's33':true, 's34':true, 's35':true, 's36':true, 's37':true, 's38':true, 's39':true,
593 // 's1', 's2', 's4', 's5', 's6', 's7', 's8', 's9', 's10', 's11', 's12', 's13', 's14', 's15', 's16'
594
595
596 // var defaultServerOptions2 = [
597 // 's1', 's2', 's4', 's5', 's6', 's7', 's8', 's9',
598 // 's10', 's11', 's12', 's13', 's14', 's15', 's16', 's17', 's18', 's19',
599 // 's20', 's21', 's22', 's23', 's24', 's25', 's26', 's27', 's28', 's29',
600 // 's30', 's31', 's32', 's33', 's34', 's35', 's36', 's37', 's38', 's39',
601 // ];
602
603 // var defaultServerOptions = [
604 // 's1', 's2', 's4', 's5', 's6', 's7', 's8', 's9',
605 // 's10', 's11', 's12', 's13', 's14', 's15', 's16', 's17', 's18', 's19',
606 // 's20', 's21', 's22', 's23', 's24', 's25', 's26', 's27', 's28', 's29',
607 // 's30', 's32', 's33', 's34', 's35', 's36', 's37', 's38'
608 // ];
609 // var defaultServerOptions = ['s1'];
610 var defaultServer = defaultServerOptions[Math.floor(Math.random() * defaultServerOptions.length)];
611
612 //socket = io('http://127.0.0.1:3005/');
613
614 // Using ws transport vs default preflight XHR requests fixes CORS cross-domain Chrome issues
615 // Read more at http://maxprog.net.pl/node-js/socket-io-and-cross-domain-communication/
616 // https://stackoverflow.com/questions/28238628/socket-io-1-x-use-websockets-only
617 var corsOptions = {transports: ['websocket']};
618
619
620 if (!npServerIdFromUrl) {
621 // default server
622 socket = io('https://' + defaultServer + '.netflixparty.com/', corsOptions);
623 console.log('socket: https://' + defaultServer + '.netflixparty.com/');
624 } else if (servers[npServerIdFromUrl]) {
625 socket = io('https://' + npServerIdFromUrl + '.netflixparty.com/', corsOptions);
626 console.log('socket: https://' + npServerIdFromUrl + '.netflixparty.com/');
627 // socket = io('http://localhost:3000/');
628 // console.log('socket: https://localhost:3000/');
629 } else {
630 socket = io('https://netflixparty-server.herokuapp.com', corsOptions);
631 console.log('socket: https://netflixparty-server.herokuapp.com');
632 herokuSocket = true;
633 }
634
635
636 // connection to file server
637 // var fileSocket = io('http://127.0.0.1:3000/');
638
639 // get the userId from the server
640 var userId = null;
641 socket.on('userId', function(data) {
642 console.log('userId: ' + JSON.stringify(data));
643 if (userId === null) {
644 userId = data;
645 }
646 });
647
648
649 //////////////////////////////////////////////////////////////////////////
650 // User Settings //
651 //////////////////////////////////////////////////////////////////////////
652
653 // icon state
654 // BUGFIX: fix content verification errors due to case insensitivity (https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-extensions/%E2%80%9CThis$20extension$20may$20have$20been$20corrupted%E2%80%9D$20%7Csort:date/chromium-extensions/DrSVKXkPCSU/Zw4dg_4MBgAJ)
655 var icons = ["Batman.svg", "DeadPool.svg", "CptAmerica.svg", "Wolverine.svg", "IronMan.svg", "Goofy.svg", "Alien.svg", "Mulan.svg", "Snow-White.svg", "Poohbear.svg", "Sailormoon.svg", "Sailor Cat.svg", "Pizza.svg", "Cookie.svg", "Chocobar.svg", "hotdog.svg", "Hamburger.svg", "Popcorn.svg", "IceCream.svg", "ChickenLeg.svg"]
656 var iconsInUse = [];
657 var userIcons = {};
658
659 var userNicknames = {};
660 var nicknamesInUse = [];
661
662 var userSettings = {};
663
664 var addIconButton = function(icon) {
665 var iconButton = jQuery(`
666 <a class="image-button">
667 <img class="img-class" src='${chrome.runtime.getURL('img/' + icon)}'>
668 </a>
669 `).appendTo(jQuery('#icon-holder')).data('icon', icon);
670
671 }
672
673 var addIconSelector = function() {
674 for(var i =0; i < icons.length; i++) {
675 addIconButton(icons[i]);
676 }
677
678 var buttons = jQuery(".image-button");
679 for(var i = 0; i < buttons.length; i++) {
680 // console.log("image button data : " + jQuery(buttons[i]).data('icon'));
681 }
682 }
683
684 // TODO: save icon url for userSettings in chrome storage?
685 var getUserIconURL = function(userId, userIcon) {
686 if(userIcons[userId]) {
687 return userIcons[userId]
688 } else {
689 var newIcon = userIcon ? userIcon : icons[Math.floor(Math.random() * icons.length)];
690 var iconURL = chrome.runtime.getURL('img/' + newIcon);
691 while (iconsInUse.hasOwnProperty(iconURL)) {
692 iconURL = chrome.runtime.getURL('img/' + newIcon);
693 }
694
695 userIcons[userId] = iconURL;
696 iconsInUse.push(iconURL);
697 return userIcons[userId];
698 }
699 }
700
701 var getUserNickname = function(userId, userNickname) {
702 if(userNicknames[userId]) {
703 return userNicknames[userId]
704 } else {
705 if(userNickname) {
706 userNicknames[userId] = userNickname;
707 nicknamesInUse.push(userNickname);
708 return userNicknames[userId];
709 }
710 }
711 }
712
713
714 // when user clicks on icon selector button, calls this function
715 // if (saveToChrome) adds icon as userIcon to chrome storage (async)
716 // adds userId: userIcon to userIcons map
717 // add userIcon to userSettings map
718 // re-renders sidebar based on usersettings map
719 var setUserIcon = function(userId, userIcon, saveToChrome) {
720 var render = userIcons[userId];
721 if(saveToChrome) {
722 chrome.storage.local.set({"userIcon": userIcon}, function(data) {
723
724 if(chrome.runtime.lastError)
725 {
726 /* error */
727 console.log(chrome.runtime.lastError.message);
728 return;
729 }
730 console.log('set user iconchrome storage data: ' + JSON.stringify(data));
731
732 console.log('userIcon saved into settings chrome storage: ' + userIcon);
733 });
734 userSettings.userIcon = userIcon;
735 console.log('new user settings after set user icon: ' + JSON.stringify(userSettings));
736 socket.emit('broadcastUserSettings', { userSettings: userSettings }, function() {});
737 }
738
739 var iconURL = chrome.runtime.getURL('img/' + userIcon);
740 userIcons[userId] = iconURL;
741 iconsInUse.push(iconURL);
742 logIcons();
743 // if(render) {
744 // delete old iconUrl from icons in use
745 renderSidebar();
746 // }
747 }
748
749 var setUserNickname = function(userId, userNickname, saveToChrome) {
750 var render = userNicknames[userId];
751 if(saveToChrome) {
752 chrome.storage.local.set({"userNickname": userNickname}, function(data) {
753
754 if(chrome.runtime.lastError)
755 {
756 /* error */
757 console.log(chrome.runtime.lastError.message);
758 return;
759 }
760 console.log('set user nickname chrome storage data: ' + JSON.stringify(data));
761
762 chrome.storage.local.get(['userNickname'], function(result) {
763 console.log('Value currently is ' + result.key);
764 });
765
766 console.log('userNickname saved into settings chrome storage: ' + userNickname);
767 });
768 userSettings.userNickname = userNickname;
769 console.log('new user settings after set user nickname: ' + JSON.stringify(userSettings));
770 socket.emit('broadcastUserSettings', { userSettings: userSettings }, function() {});
771 }
772
773 userNicknames[userId] = userNickname;
774 nicknamesInUse.push(userNickname);
775 // if(render) {
776 // delete old iconUrl from icons in use
777 renderSidebar();
778 // }
779 }
780
781 chrome.storage.onChanged.addListener(function(changes, areaName) {
782 console.log("storage change: " + JSON.stringify(changes) + " for " + JSON.stringify(areaName));
783 });
784
785 // re-renders sidebar based on userSettings map
786 var renderSidebar = function() {
787 var userIconURL = getUserIconURL(userSettings.userId, userSettings.userIcon);
788 // console.log("call renderSidebar here: " + userIconURL);
789 jQuery('#user-icon img').attr('src', userIconURL);
790 jQuery('.user-icon img').attr('src', userIconURL);
791
792 var msgs = jQuery('.msg');
793 // console.log("msgs length: " + msgs.length);
794 for(var i = 0; i < msgs.length; i++) {
795 if(jQuery(msgs[i]).data('permId') && jQuery(msgs[i]).data('userIcon')) {
796 if(userIcons[jQuery(msgs[i]).data('permId')] != jQuery(msgs[i]).data('userIcon')) {
797 jQuery(msgs[i]).find("img").attr('src', userIcons[jQuery(msgs[i]).data('permId')]);
798 jQuery(msgs[i]).data('userIcon', userIcons[jQuery(msgs[i]).data('permId')]);
799 }
800 }
801
802 if(jQuery(msgs[i]).data('permId') && jQuery(msgs[i]).data('userNickname') == '') {
803 if(userNicknames[jQuery(msgs[i]).data('permId')] != jQuery(msgs[i]).data('userNickname')) {
804 if(userNicknames[jQuery(msgs[i]).data('permId')]) {
805 // jQuery(msgs[i]).find("p .msg-nickname").text(userNicknames[jQuery(msgs[i]).data('permId')]);
806
807 // console.log("render message data: " + JSON.stringify(jQuery(msgs[i]).data('message')));
808
809 var message = jQuery(msgs[i]).data('message');
810 var permId = jQuery(msgs[i]).data('permId');
811 var userIcon = userIcons[jQuery(msgs[i]).data('permId')];
812 var userNickname = userNicknames[jQuery(msgs[i]).data('permId')]
813
814 var nicknameMessage = jQuery(`
815 <div class="msg-container">
816 <div class="icon-name">
817 <div class="icon">
818 <img src="${jQuery(msgs[i]).data('userIcon')}">
819 </div>
820 </div>
821 <div class="msg-txt message${ message.isSystemMessage ? '-system' : '-txt' }">
822 <h3>${userNicknames[jQuery(msgs[i]).data('permId')].replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')}</h3>
823 <p>${message.body.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')}</p>
824 </div>
825 </div>
826 `)
827
828 jQuery(msgs[i]).replaceWith(nicknameMessage);
829 jQuery(nicknameMessage).data('permId', permId).data('userIcon', userIcon).data('userNickname', userNickname);
830
831 // jQuery(msgs[i]).hide();
832 }
833 // replace msg nickname w new nickname
834 }
835 }
836 }
837
838 var msgs = jQuery('.msg-container');
839 // console.log("msgs length: " + msgs.length);
840 for(var i = 0; i < msgs.length; i++) {
841 // console.log('msgs data for ' + i + ': ' + jQuery(msgs[i]).data('permId') + ', ' + jQuery(msgs[i]).data('userIcon'));
842 if(jQuery(msgs[i]).data('permId') && jQuery(msgs[i]).data('userIcon')) {
843 if(userIcons[jQuery(msgs[i]).data('permId')] != jQuery(msgs[i]).data('userIcon')) {
844 jQuery(msgs[i]).find("img").attr('src', userIcons[jQuery(msgs[i]).data('permId')]);
845 jQuery(msgs[i]).data('userIcon', userIcons[jQuery(msgs[i]).data('permId')]);
846 }
847 }
848
849 if(jQuery(msgs[i]).data('permId') && jQuery(msgs[i]).data('userNickname')) {
850 if(userNicknames[jQuery(msgs[i]).data('permId')] != jQuery(msgs[i]).data('userNickname')) {
851 if(userNicknames[jQuery(msgs[i]).data('permId')]) {
852 jQuery(msgs[i]).find("h3").text(userNicknames[jQuery(msgs[i]).data('permId')]);
853 jQuery(msgs[i]).data('userNickname', userNicknames[jQuery(msgs[i]).data('permId')]);
854 }
855 // replace msg nickname w new nickname
856 }
857 }
858 }
859
860 }
861
862 var logIcons = function() {
863 console.log("Icons in use: " + JSON.stringify(iconsInUse));
864 console.log("user Icons: " + JSON.stringify(userIcons));
865 }
866
867 var getUserIdPromise = function() {
868 console.log('user Id promise called: ' + userId);
869 return delayUntil(function() {
870 return userId;
871 }, 5000)();
872 }
873
874 function isEmpty(obj) {
875 for(var key in obj) {
876 if(obj.hasOwnProperty(key))
877 return false;
878 }
879 return true;
880 }
881
882
883 var waitUserIdReady = function() {
884 console.log('wait user id ready called: ');
885 return function() {
886 return new Promise(function(resolve, reject) {
887 return delay(250)().then(delayUntil(function() {
888 // console.log('userid is called');
889 return userId != null;
890 }, Infinity)).then(delayUntil(function() {
891 // console.log('wait video loading done');
892 // return (getState() !== 'loading');
893 // console.log('check user settings');
894 // var video = getVideo()[0];
895 return !isEmpty(userSettings);
896
897
898 }, Infinity)).then(function() {
899 console.log('userId and userSettings are ready!');
900 // console.log('userId and userSettings is ready!');
901 if(permIdFix) {
902 permId = userId;
903 }
904 resolve();
905 });
906 });
907 };
908 }
909
910
911 var getChromeStorage = function() {
912 return function() {
913 console.log('fix, userId getChromeStorage: ' + permIdFix + ', ' + userId);
914 return new Promise(function(resolve, reject) {
915 if(userSettings.userId && userSettings.userIcon) {
916 resolve(userSettings);
917 console.log('fix, userId resolve getChromeStorage: ' + permIdFix + ', ' + userId);
918 }
919 chrome.storage.local.get(null, function(data) {
920 if(permIdFix) {
921 data.userId = userId;
922 console.log('fix, userId CALLED getChromeStorage: ' + permIdFix + ', ' + userId);
923 permId = userId;
924 }
925
926 console.log('get chrome storage finished userID: ' + userId);
927 console.log("get chrome storage finished: " + JSON.stringify(data));
928
929 if(data.userId && data.userIcon) {
930 userSettings = data
931 } else if(data.userId && !data.userIcon) {
932 var dataUserId = data.userId;
933 var newIcon = icons[Math.floor(Math.random() * icons.length)];
934
935 // getUserIconURL(userId, newIcon);
936 userSettings = {'userId': dataUserId, 'userIcon': newIcon};
937 setUserIcon(userSettings.userId, userSettings.userIcon, true);
938 console.log("get chrome storage creating new icon: " + JSON.stringify(userSettings));
939 resolve(userSettings);
940 }
941 resolve(userSettings);
942 });
943 });
944 };
945 }
946
947 // respond to update settings from the server
948 socket.on('updateSettings', function(data) {
949 // pushTask(receive(data));
950 console.log(JSON.stringify(data));
951 if(data.userSettings.userIcon) setUserIcon(data.userSettings.userId, data.userSettings.userIcon, false);
952 if(data.userSettings.userNickname) setUserNickname(data.userSettings.userId, data.userSettings.userNickname, false);
953 });
954
955
956 //////////////////////////////////////////////////////////////////////////
957 // Chat API //
958 //////////////////////////////////////////////////////////////////////////
959
960 // chat state
961 var messages = [];
962 var unreadCount = 0;
963 var originalTitle = document.title;
964
965 // UI constants (80% scale)
966 // Area(video) before: [((1168+(1274-1168) - 360*0.8)^2)*9/16] = 470k px^2
967 // Area(video) after: [((1168+(1274-1168) - 360)^2)*9/16] = 546k px^2
968 var defaultScale = 0.8;
969 var chatSidebarWidth = 360*defaultScale;
970 var chatSidebarPadding = 16*defaultScale;
971 var avatarSize = 20*defaultScale;
972 var avatarPadding = 4*defaultScale;
973 var avatarBorder = 2*defaultScale;
974 var chatVericalMargin = 4*defaultScale;
975 var chatInputBorder = 2*defaultScale;
976 var chatMessageHorizontalPadding = 8*defaultScale;
977 var chatMessageVerticalPadding = 8*defaultScale;
978 var presenceIndicatorHeight = 30*defaultScale;
979
980 // summary state
981 var messagesCount = 0;
982 var interactionsCount = 0;
983 var sessionStartTime; // duration
984 var summarySent = false;
985
986 // this is the markup that needs to be injected onto the page for chat
987
988 var chatHTML2 = '';
989 var setHTML = function() {
990 console.log('set html called');
991 chatHtml2 = `
992 <style>
993 #chat-wrapper {
994 width: ${chatSidebarWidth}px;
995 height: 100%;
996 background: #1a1a1a;
997 position: absolute;
998 top: 0;
999 right: 0;
1000 bottom: 0;
1001 cursor: auto;
1002 user-select: text;
1003 -webkit-user-select: text;
1004 z-index: 9999999999;
1005 }
1006
1007 #chat-wrapper #chat-container {
1008 // width: 228px;
1009 height: 100%;
1010 position: relative;
1011 left: 0;
1012 right: 0;
1013 margin: 0 auto;
1014 }
1015
1016 // Raymond's Styling Code
1017
1018 @import url("https://fonts.googleapis.com/css?family=Poppins:400,500,600,700,800,900");
1019 /* line 34, ../sass/base/_settings.scss */
1020 body, html {
1021 margin: 0em;
1022 padding: 0em;
1023 }
1024
1025 /* line 39, ../sass/base/_settings.scss */
1026 h1, h2, h3, h4, h5, h6, p, ul, ol, li, a, section, div {
1027 margin: 0em;
1028 padding: 0em;
1029 list-style: none;
1030 outline: none;
1031 text-decoration: none;
1032 }
1033
1034 /* line 47, ../sass/base/_settings.scss */
1035 button {
1036 border: none;
1037 outline: none;
1038 }
1039 /* line 50, ../sass/base/_settings.scss */
1040 button:hover {
1041 cursor: pointer;
1042 }
1043
1044 /*** Works on common browsers ***/
1045 /* line 56, ../sass/base/_settings.scss */
1046 ::selection {
1047 background: #ef3e3a;
1048 color: #f2f2f2;
1049 }
1050
1051 /*** Mozilla based browsers ***/
1052 /* line 62, ../sass/base/_settings.scss */
1053 ::-moz-selection {
1054 background: #ef3e3a;
1055 color: #f2f2f2;
1056 }
1057
1058 /***For Other Browsers ***/
1059 /* line 68, ../sass/base/_settings.scss */
1060 ::-o-selection {
1061 background: #ef3e3a;
1062 color: #f2f2f2;
1063 }
1064
1065 /* line 73, ../sass/base/_settings.scss */
1066 ::-ms-selection {
1067 background: #ef3e3a;
1068 color: #f2f2f2;
1069 }
1070
1071 /*** For Webkit ***/
1072 /* line 79, ../sass/base/_settings.scss */
1073 ::-webkit-selection {
1074 background: #ef3e3a;
1075 color: #f2f2f2;
1076 }
1077
1078 /* line 3, ../sass/layout/_chatlayout.scss */
1079 .NP-red {
1080 color: #ef3e3a;
1081 }
1082
1083 /* line 7, ../sass/layout/_chatlayout.scss */
1084 #chat-wrapper {
1085 width: 288px;
1086 height: 100%;
1087 display: flex;
1088 flex-flow: column;
1089 box-shadow: rgba(0, 0, 0, 0.6) -5px 0px 10px;
1090 background: #191919;
1091 position: fixed;
1092 right: 0;
1093 }
1094 /* line 14, ../sass/layout/_chatlayout.scss */
1095 #chat-wrapper #chat-container {
1096 width: 251px;
1097 height: 100%;
1098 padding: 14px 18.5px;
1099 }
1100 /* line 17, ../sass/layout/_chatlayout.scss */
1101 #chat-wrapper #chat-container #chat-header-container {
1102 width: 100%;
1103 height: 45px;
1104 display: flex;
1105 flex-flow: wrap row;
1106 }
1107 /* line 20, ../sass/layout/_chatlayout.scss */
1108 #chat-wrapper #chat-container #chat-header-container #chat-menu-container {
1109 display: flex;
1110 flex-flow: wrap row;
1111 width: 100%;
1112 height: 100%;
1113 align-items: center;
1114 }
1115 /* line 24, ../sass/layout/_chatlayout.scss */
1116 #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-title {
1117 width: 50%;
1118 height: 100%;
1119 display: flex;
1120 align-items: center;
1121 }
1122 /* line 28, ../sass/layout/_chatlayout.scss */
1123 #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-title #title h1 {
1124 font-family: 'Poppins', sans-serif;
1125 font-size: 15.5px;
1126 font-weight: 600;
1127 color: #ef3e3a;
1128 }
1129 /* line 33, ../sass/layout/_chatlayout.scss */
1130 #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user {
1131 width: 50%;
1132 height: 100%;
1133 display: flex;
1134 flex-flow: wrap row;
1135 align-items: center;
1136 }
1137 /* line 37, ../sass/layout/_chatlayout.scss */
1138 #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user #link-icon {
1139 width: 50%;
1140 height: 100%;
1141 display: flex;
1142 flex-flow: wrap row;
1143 justify-content: flex-end;
1144 }
1145 /* line 41, ../sass/layout/_chatlayout.scss */
1146 #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user #link-icon img {
1147 transform: scale(1);
1148 transition: 0.3s ease;
1149 width: 18px;
1150 }
1151 /* line 45, ../sass/layout/_chatlayout.scss */
1152 #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user #link-icon img:hover {
1153 transform: scale(1.15);
1154 cursor: pointer;
1155 }
1156 /* line 51, ../sass/layout/_chatlayout.scss */
1157 #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user #user-icon {
1158 width: 50%;
1159 height: 100%;
1160 display: flex;
1161 flex-flow: wrap row;
1162 justify-content: flex-end;
1163 }
1164 /* line 55, ../sass/layout/_chatlayout.scss */
1165 #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user #user-icon img {
1166 filter: drop-shadow(0px 0px 10px #000000);
1167 -webkit-filter: drop-shadow(0px 0px 10px #000000);
1168 -moz-filter: drop-shadow(0px 0px 10px #000000);
1169 width: 38px;
1170 transform: scale(1);
1171 transform-origin: center;
1172 transition: 0.5s ease;
1173 }
1174 /* line 61, ../sass/layout/_chatlayout.scss */
1175 #chat-wrapper #chat-container #chat-header-container #chat-menu-container #function-user #user-icon img:hover {
1176 filter: drop-shadow(0px 8px 10px rgba(0, 0, 0, 0.6));
1177 -webkit-filter: drop-shadow(0px 8px 10px rgba(0, 0, 0, 0.6));
1178 -moz-filter: drop-shadow(0px 8px 10px rgba(0, 0, 0, 0.6));
1179 transform: scale(1.1);
1180 }
1181
1182 /* line 3, ../sass/modules/_msg.scss */
1183 #chat-history-container {
1184 width: 100%;
1185 height: calc(100% - 195px);
1186 padding-bottom: 20px;
1187 margin-top: 15px;
1188 position: relative;
1189 overflow: hidden;
1190 }
1191 /* line 10, ../sass/modules/_msg.scss */
1192 #chat-history-container #chat-header {
1193 width: 100%;
1194 height: 25px;
1195 display: flex;
1196 flex-flow: wrap row;
1197 background: #191919;
1198 z-index: 1;
1199 align-items: flex-start;
1200 position: relative;
1201 }
1202 /* line 17, ../sass/modules/_msg.scss */
1203 #chat-history-container #chat-header h4 {
1204 font-family: 'Poppins', sans-serif;
1205 font-size: 12px;
1206 font-weight: 600;
1207 color: #e2e2e2;
1208 }
1209 /* line 30, ../sass/modules/_msg.scss */
1210 #chat-history-container #chat-history {
1211 width: 100%;
1212 height: 100%;
1213 display: flex;
1214 flex-flow: column;
1215 position: relative;
1216 justify-content: flex-start;
1217 overflow: auto;
1218 max-height: 100%;
1219 }
1220 /* line 37, ../sass/modules/_msg.scss */
1221 #chat-history-container #chat-history .msg {
1222 display: flex;
1223 flex-flow: wrap row;
1224 width: 100%;
1225 align-items: center;
1226 justify-content: space-between;
1227 flex-shrink: 0;
1228 padding-bottom: 11px;
1229 }
1230 /* line 44, ../sass/modules/_msg.scss */
1231 #chat-history-container #chat-history .msg .icon {
1232 width: 13%;
1233 height: 100%;
1234 display: flex;
1235 flex-flow: wrap row;
1236 align-items: center;
1237 }
1238 /* line 48, ../sass/modules/_msg.scss */
1239 #chat-history-container #chat-history .msg .icon img {
1240 width: 100%;
1241 height: 100%;
1242 }
1243 /* line 52, ../sass/modules/_msg.scss */
1244 #chat-history-container #chat-history .msg .message-system {
1245 width: 80%;
1246 }
1247 /* line 54, ../sass/modules/_msg.scss */
1248 #chat-history-container #chat-history .msg .message-system p {
1249 font-size: 13px;
1250 font-weight: 500;
1251 font-family: 'Poppins', sans-serif;
1252 font-style: italic;
1253 color: #757575;
1254 }
1255 /* line 62, ../sass/modules/_msg.scss */
1256 #chat-history-container #chat-history .msg .message-txt {
1257 width: 80%;
1258 }
1259 /* line 64, ../sass/modules/_msg.scss */
1260 #chat-history-container #chat-history .msg .message-txt p {
1261 font-family: 'Poppins', sans-serif;
1262 font-size: 13px;
1263 font-weight: 500;
1264 color: #e2e2e2;
1265 }
1266 /* line 70, ../sass/modules/_msg.scss */
1267 #chat-history-container #chat-history .msg-container {
1268 display: flex;
1269 flex-flow: wrap row;
1270 justify-content: space-between;
1271 align-items: flex-start;
1272 padding-bottom: 11px;
1273 width: 100%;
1274 }
1275 /* line 76, ../sass/modules/_msg.scss */
1276 #chat-history-container #chat-history .msg-container .icon-name {
1277 width: 13%;
1278 }
1279 /* line 78, ../sass/modules/_msg.scss */
1280 #chat-history-container #chat-history .msg-container .icon-name .icon {
1281 width: 100%;
1282 height: 100%;
1283 }
1284 /* line 80, ../sass/modules/_msg.scss */
1285 #chat-history-container #chat-history .msg-container .icon-name .icon img {
1286 width: 100%;
1287 height: 100%;
1288 }
1289 /* line 85, ../sass/modules/_msg.scss */
1290 #chat-history-container #chat-history .msg-container .msg-txt {
1291 display: flex;
1292 flex-flow: column;
1293 width: 80%;
1294 }
1295 /* line 88, ../sass/modules/_msg.scss */
1296 #chat-history-container #chat-history .msg-container .msg-txt h3 {
1297 font-family: 'Poppins', sans-serif;
1298 font-size: 13px;
1299 font-weight: 500;
1300 color: #c3c3c3;
1301 padding-bottom: 0.15rem;
1302 }
1303 /* line 93, ../sass/modules/_msg.scss */
1304 #chat-history-container #chat-history .msg-container .msg-txt p {
1305 font-family: 'Poppins', sans-serif;
1306 font-size: 13px;
1307 font-weight: 500;
1308 color: #e2e2e2;
1309 }
1310 /* line 98, ../sass/modules/_msg.scss */
1311 #chat-history-container #chat-history .msg-container .message-system p {
1312 font-family: 'Poppins', sans-serif;
1313 font-size: 13px;
1314 font-weight: 500;
1315 font-style: italic;
1316 color: #757575;
1317 }
1318 /* line 104, ../sass/modules/_msg.scss */
1319 #chat-history-container #chat-history > :first-child {
1320 margin-top: auto !important;
1321 }
1322 /* line 107, ../sass/modules/_msg.scss */
1323 #chat-history-container #chat-history::-webkit-scrollbar {
1324 width: 2px;
1325 }
1326 /* line 110, ../sass/modules/_msg.scss */
1327 #chat-history-container #chat-history::-webkit-scrollbar-thumb {
1328 border-radius: 25px;
1329 background: #ef3e3a;
1330 }
1331 /* line 114, ../sass/modules/_msg.scss */
1332 #chat-history-container #chat-history::-webkit-scrollbar-track {
1333 border-radius: 25px;
1334 background: #e0e0e0;
1335 }
1336
1337 /* line 121, ../sass/modules/_msg.scss */
1338 #chat-input-container {
1339 width: 100%;
1340 }
1341 /* line 123, ../sass/modules/_msg.scss */
1342 #chat-input-container #chat-input {
1343 font-family: 'Poppins', sans-serif;
1344 font-size: 13px;
1345 font-weight: 500;
1346 width: 100%;
1347 padding-top: 10px;
1348 background: none;
1349 border: none;
1350 outline: none;
1351 color: #e2e2e2;
1352 border-bottom: 1.2px solid;
1353 border-bottom-color: #aaaaaa;
1354 transition: 0.2s ease;
1355 }
1356 /* line 134, ../sass/modules/_msg.scss */
1357 #chat-input-container #chat-input[type=text]:focus {
1358 transition: 0.2s ease;
1359 border-bottom: 1.5px solid;
1360 border-bottom-color: #e2e2e2;
1361 }
1362
1363 /* line 142, ../sass/modules/_msg.scss */
1364 #presence-indicator {
1365 font-family: 'Poppins', sans-serif;
1366 font-size: 11.5px;
1367 font-weight: 500;
1368 font-style: italic;
1369 color: #757575;
1370 white-space: pre-wrap;
1371 }
1372 /* line 147, ../sass/modules/_msg.scss */
1373 #presence-indicator p {
1374 font-family: 'Poppins', sans-serif;
1375 font-size: 11.5px;
1376 font-weight: 500;
1377 font-style: italic;
1378 color: #757575;
1379 }
1380
1381 /* line 154, ../sass/modules/_msg.scss */
1382 #patreon-container {
1383 width: 100%;
1384 padding-top: 16px;
1385 }
1386 /* line 157, ../sass/modules/_msg.scss */
1387 #patreon-container #patreon-link {
1388 display: flex;
1389 flex-flow: wrap row;
1390 align-items: center;
1391 }
1392 /* line 160, ../sass/modules/_msg.scss */
1393 #patreon-container #patreon-link:hover {
1394 cursor: pointer;
1395 }
1396 /* line 163, ../sass/modules/_msg.scss */
1397 #patreon-container #patreon-link p {
1398 font-family: 'Poppins', sans-serif;
1399 font-size: 14.5px;
1400 font-weight: 600;
1401 color: #949494;
1402 width: 40%;
1403 }
1404 /* line 168, ../sass/modules/_msg.scss */
1405 #patreon-container #patreon-link img {
1406 border-radius: 20px;
1407 width: 60%;
1408 }
1409
1410 /* line 3, ../sass/modules/_setting.scss */
1411 #setting-edit {
1412 display: flex;
1413 flex-flow: column;
1414 position: relative;
1415 width: 100%;
1416 }
1417 /* line 7, ../sass/modules/_setting.scss */
1418 #setting-edit .section-b {
1419 width: 100%;
1420 height: 85px;
1421 display: flex;
1422 flex-flow: wrap row;
1423 justify-content: center;
1424 margin: 15px 0px;
1425 }
1426 /* line 12, ../sass/modules/_setting.scss */
1427 #setting-edit .section-b .section-b-inner {
1428 height: 100%;
1429 text-align: center;
1430 }
1431 /* line 15, ../sass/modules/_setting.scss */
1432 #setting-edit .section-b .section-b-inner .user-icon {
1433 width: 100%;
1434 height: 100%;
1435 display: flex;
1436 }
1437 /* line 18, ../sass/modules/_setting.scss */
1438 #setting-edit .section-b .section-b-inner .user-icon img {
1439 width: 100%;
1440 height: 100%;
1441 transform: scale(0.95);
1442 transition: 0.5s ease;
1443 }
1444 /* line 22, ../sass/modules/_setting.scss */
1445 #setting-edit .section-b .section-b-inner .user-icon img:hover {
1446 cursor: pointer;
1447 transform: scale(1);
1448 }
1449 /* line 30, ../sass/modules/_setting.scss */
1450 #setting-edit .section-c {
1451 display: flex;
1452 flex-flow: column;
1453 }
1454 /* line 32, ../sass/modules/_setting.scss */
1455 #setting-edit .section-c .section-c-inner {
1456 display: flex;
1457 flex-flow: column;
1458 }
1459 /* line 34, ../sass/modules/_setting.scss */
1460 #setting-edit .section-c .section-c-inner .nickname-section {
1461 display: flex;
1462 flex-flow: column;
1463 }
1464 /* line 36, ../sass/modules/_setting.scss */
1465 #setting-edit .section-c .section-c-inner .nickname-section .nickname-wrap {
1466 display: flex;
1467 flex-flow: wrap row;
1468 }
1469 /* line 38, ../sass/modules/_setting.scss */
1470 #setting-edit .section-c .section-c-inner .nickname-section .nickname-wrap h2 {
1471 font-family: 'Poppins', sans-serif;
1472 font-size: 13px;
1473 font-weight: 500;
1474 color: #c3c3c3;
1475 width: 50%;
1476 }
1477 /* line 43, ../sass/modules/_setting.scss */
1478 #setting-edit .section-c .section-c-inner .nickname-section .nickname-wrap .np-btn {
1479 display: flex;
1480 flex-flow: wrap row;
1481 align-items: center;
1482 width: 50%;
1483 }
1484 /* line 47, ../sass/modules/_setting.scss */
1485 #setting-edit .section-c .section-c-inner .nickname-section .nickname-wrap .np-btn a {
1486 display: flex;
1487 flex-flow: wrap row;
1488 width: 100%;
1489 justify-content: flex-end;
1490 align-items: center;
1491 }
1492 /* line 52, ../sass/modules/_setting.scss */
1493 #setting-edit .section-c .section-c-inner .nickname-section .nickname-wrap .np-btn a:hover {
1494 cursor: default;
1495 }
1496 /* line 55, ../sass/modules/_setting.scss */
1497 #setting-edit .section-c .section-c-inner .nickname-section .nickname-wrap .np-btn a img {
1498 width: 13.5%;
1499 opacity: 0.5;
1500 }
1501 /* line 62, ../sass/modules/_setting.scss */
1502 #setting-edit .section-c .section-c-inner .nickname-section .nickname-input {
1503 margin-top: 1px;
1504 width: 100%;
1505 }
1506 /* line 65, ../sass/modules/_setting.scss */
1507 #setting-edit .section-c .section-c-inner .nickname-section .nickname-input #nickname-edit {
1508 font-family: 'Poppins', sans-serif;
1509 font-size: 13.5px;
1510 font-weight: 500;
1511 width: 100%;
1512 color: #e2e2e2;
1513 background: none;
1514 border: none;
1515 outline: none;
1516 border-bottom: 1.2px solid;
1517 border-bottom-color: #e2e2e2;
1518 }
1519 /* line 74, ../sass/modules/_setting.scss */
1520 #setting-edit .section-c .section-c-inner .nickname-section .nickname-input #nickname-edit[type=text]:focus {
1521 transition: 0.2s ease;
1522 border-bottom: 1.2px solid;
1523 border-bottom-color: #2cda00;
1524 }
1525
1526 /* line 86, ../sass/modules/_setting.scss */
1527 #settings-save {
1528 position: relative;
1529 width: 100%;
1530 }
1531 /* line 89, ../sass/modules/_setting.scss */
1532 #settings-save .section-d {
1533 width: 100%;
1534 margin-top: 1rem;
1535 }
1536 /* line 92, ../sass/modules/_setting.scss */
1537 #settings-save .section-d .section-d-inner {
1538 width: 100%;
1539 height: 35px;
1540 }
1541 /* line 94, ../sass/modules/_setting.scss */
1542 #settings-save .section-d .section-d-inner .btns {
1543 width: 100%;
1544 height: 100%;
1545 }
1546 /* line 96, ../sass/modules/_setting.scss */
1547 #settings-save .section-d .section-d-inner .btns button {
1548 font-family: 'Poppins', sans-serif;
1549 font-size: 12px;
1550 font-weight: 500;
1551 width: 100%;
1552 height: 100%;
1553 border-radius: 50px;
1554 background: #5c5c5c;
1555 color: #e2e2e2;
1556 transition: 0.5s ease;
1557 }
1558 /* line 103, ../sass/modules/_setting.scss */
1559 #settings-save .section-d .section-d-inner .btns button:hover {
1560 background: #ef3e3a;
1561 }
1562
1563 /* line 3, ../sass/modules/_icon.scss */
1564 #chat-icon-container {
1565 display: flex;
1566 flex-flow: column;
1567 }
1568 /* line 5, ../sass/modules/_icon.scss */
1569 #chat-icon-container #icon-title-container {
1570 margin: 10px 0px;
1571 }
1572 /* line 7, ../sass/modules/_icon.scss */
1573 #chat-icon-container #icon-title-container #icon-title h2 {
1574 font-family: 'Poppins', sans-serif;
1575 font-size: 13px;
1576 font-weight: 600;
1577 color: #e2e2e2;
1578 }
1579 /* line 12, ../sass/modules/_icon.scss */
1580 #chat-icon-container #icon-holder-container {
1581 display: flex;
1582 flex-flow: wrap row;
1583 }
1584 /* line 14, ../sass/modules/_icon.scss */
1585 #chat-icon-container #icon-holder-container #icon-holder-template {
1586 display: flex;
1587 flex-flow: wrap row;
1588 }
1589 /* line 16, ../sass/modules/_icon.scss */
1590 #chat-icon-container #icon-holder-container #icon-holder-template #icon-holder {
1591 display: flex;
1592 flex-flow: wrap row;
1593 width: 100%;
1594 height: 100%;
1595 }
1596 /* line 19, ../sass/modules/_icon.scss */
1597 #chat-icon-container #icon-holder-container #icon-holder-template #icon-holder .image-button {
1598 width: 22%;
1599 padding: 1px 3.75px;
1600 }
1601 /* line 22, ../sass/modules/_icon.scss */
1602 #chat-icon-container #icon-holder-container #icon-holder-template #icon-holder .image-button .img-class {
1603 width: 100%;
1604 height: 100%;
1605 transform: scale(0.95);
1606 transition: 0.3s ease;
1607 }
1608 /* line 26, ../sass/modules/_icon.scss */
1609 #chat-icon-container #icon-holder-container #icon-holder-template #icon-holder .image-button .img-class:hover {
1610 filter: drop-shadow(0px 8px 10px rgba(0, 0, 0, 0.6));
1611 -webkit-filter: drop-shadow(0px 8px 10px rgba(0, 0, 0, 0.6));
1612 -moz-filter: drop-shadow(0px 8px 10px rgba(0, 0, 0, 0.6));
1613 transform: scale(1);
1614 curosr: pointer;
1615 }
1616
1617
1618 </style>
1619
1620 <script>
1621 var script = document.createElement('script');
1622 script.src = 'https://code.jquery.com/jquery-1.11.0.min.js';
1623 document.getElementsByTagName('head')[0].appendChild(script);
1624
1625
1626 </script>
1627 <div id="notification-link" class="notification-links">
1628
1629 </div>
1630
1631 <div id="chat-wrapper">
1632 <div id="chat-container">
1633
1634 <div id="chat-header-container">
1635
1636 <ul id="chat-menu-container">
1637 <li id="function-title">
1638 <div id="title">
1639 <h1>Netflix Party</h1>
1640 </div>
1641 </li>
1642 <li id="function-user">
1643 <div id="link-icon">
1644 <img src='${chrome.runtime.getURL("img/Link.svg")}'>
1645 <input id="share-url" type="text" readonly="true" autocomplete="off" autofocus style="display:none;" />
1646 </div>
1647 <a id="user-icon">
1648 <img src='${getUserIconURL(userSettings.userId, userSettings.userIcon)}'>
1649 </a>
1650 </li>
1651 </ul>
1652
1653 <div id="chat-link-container" style='display:none;'>
1654 <div id="chat-link">
1655 <div id="chat-link-url">
1656 <p>The url link goes here.</p>
1657 </div>
1658 <div id="chat-link-icon">
1659 <img src='${chrome.runtime.getURL("img/Link.svg")}'>
1660 </div>
1661 </div>
1662 </div>
1663
1664 <div id="chat-icon-container" style="display:none">
1665 <div id="icon-title-container">
1666 <div id="icon-title">
1667 <h2>Click to switch icon</h2>
1668 </div>
1669 </div>
1670 <div id="icon-holder-container">
1671 <div id="icon-holder-template">
1672 <ul id="icon-holder">
1673 </ul>
1674 </div>
1675 </div>
1676 </div>
1677
1678 </div>
1679
1680 <div id="setting-edit" class="chat-settings-container" style="display:none">
1681
1682 <div class="section-b">
1683 <div class="section-b-inner section-inner">
1684 <a class="user-icon">
1685 <img src='${getUserIconURL(userSettings.userId, userSettings.userIcon)}' />
1686 </a>
1687 </div>
1688 </div>
1689
1690 <div class="section-c">
1691 <div class="section-c-inner section-inner">
1692 <div class="nickname-section row-wrap">
1693 <div class="nickname-wrap row-one">
1694 <h2>Nickname</h2>
1695 <div class="np-btn">
1696 <a>
1697 <!-- <p>Edit</p> -->
1698 <img src='${chrome.runtime.getURL("img/edit.svg")}' />
1699 </a>
1700 </div>
1701 </div>
1702 <div class="nickname-input row-two">
1703 <input id="nickname-edit" type="text" placeholder='${userSettings.userNickname ? userSettings.userNickname : "Add a nickname"}'/>
1704 </div>
1705 </div>
1706 </div>
1707 </div>
1708
1709 </div>
1710
1711 <div id="settings-save" class="chat-settings-container" style="display:none">
1712 <div class="section-d">
1713 <div class="section-d-inner section-inner">
1714
1715 <div class="btns">
1716 <button>Save Changes</button>
1717 </div>
1718 </div>
1719 </div>
1720 </div>
1721
1722 <div id="chat-history-container">
1723 <div id="chat-header">
1724 <h4>Chatroom</h4>
1725 </div>
1726 <!-- <div id="chat-gradient"></div> -->
1727 <div id="chat-history">
1728 </div>
1729 </div>
1730
1731 <div id="presence-indicator">
1732 <p>People are currently typing...</p>
1733 </div>
1734
1735 <div id="chat-input-container">
1736 <input id="chat-input" type="text" placeholder="Type a message..." autocomplete="off"></input>
1737 </div>
1738
1739 <div id="patreon-container">
1740 <a id="patreon-link" href="https://www.patreon.com/netflixparty" target="_blank">
1741 <p>
1742 Support NP
1743 </p>
1744 <img src='https://c5.patreon.com/external/logo/become_a_patron_button@2x.png' />
1745 </a>
1746 </div>
1747
1748 </div>
1749 </div>
1750 `;
1751 }
1752
1753
1754 // this is used for the chat presence feature
1755 var typingTimer = null;
1756
1757 var allowFullScreen = function() {
1758 // allow keyboard input on fullscreen
1759 var script = document.createElement( "script" );
1760 var fsCode = `
1761 // document.getElementsByClassName("sizing-wrapper")[0].webkitRequestFullScreen = function() {
1762 // console.log("fullscreen test");
1763 // var fullScreenWrapper = document.getElementsByClassName("nf-kb-nav-wrapper")[0];
1764 // fullScreenWrapper.webkitRequestFullScreen(fullScreenWrapper.ALLOW_KEYBOARD_INPUT);
1765 // }
1766 // var fullScreenWrapper = document.getElementsByClassName("nf-kb-nav-wrapper")[0];
1767 // fullScreenWrapper.webkitRequestFullScreen(fullScreenWrapper.ALLOW_KEYBOARD_INPUT);
1768
1769
1770 // document.getElementsByClassName("sizing-wrapper")[0].requestFullScreen = function() {
1771 // console.log("fullscreen test");
1772 // var fullScreenWrapper = document.getElementsByClassName("nf-kb-nav-wrapper")[0];
1773 // fullScreenWrapper.webkitRequestFullScreen(fullScreenWrapper.ALLOW_KEYBOARD_INPUT);
1774 // }
1775
1776 document.getElementsByClassName("sizing-wrapper")[0].requestFullscreen = function() {console.log('test');}
1777
1778 console.log("fullscreen loaded? :" + document.getElementsByClassName('button-nfplayerFullscreen').length);
1779
1780 document.getElementsByClassName('button-nfplayerFullscreen')[0].onclick = function() {
1781 console.log('fullscreen click');
1782 var fullScreenWrapper = document.getElementsByClassName("nf-kb-nav-wrapper")[0];
1783 fullScreenWrapper.webkitRequestFullScreen(fullScreenWrapper.ALLOW_KEYBOARD_INPUT);
1784 }
1785 // var fullScreenWrapper = document.getElementsByClassName("nf-kb-nav-wrapper")[0];
1786 // fullScreenWrapper.webkitRequestFullScreen(fullScreenWrapper.ALLOW_KEYBOARD_INPUT);
1787 // }
1788 `;
1789 script.text = fsCode;
1790 document.head.appendChild( script );
1791 }
1792
1793 // set up the chat state, or reset the state if the system has already been set up
1794 var initChat = function() {
1795 if (jQuery('#chat-wrapper').length === 0) {
1796
1797 // setHTML().then(jQuery('.sizing-wrapper').after(chatHtml2));
1798 jQuery('.sizing-wrapper').after(chatHtml2);
1799 allowFullScreen();
1800 jQuery('#presence-indicator').data('typing', false);
1801 jQuery('#presence-indicator').data('buffering', false);
1802 setPresenceVisible(false);
1803 // setPresenceText();
1804 // jQuery('#presence-indicator').hide();
1805
1806
1807 var userIconListener = function(e) {
1808 console.log('userIcon button clicked');
1809 // console.log()
1810 toggleIconContainer();
1811 }
1812 jQuery('#user-icon').click(userIconListener);
1813
1814 var linkIconListener = function(e) {
1815 console.log('linkIcon button clicked');
1816
1817 var currVideoUrl = window.location.href.split('?')[0];
1818 var partySessionId = sessionId;
1819 var serverId = getURLParameter(url, 'npServerId', 1) ? getURLParameter(url, 'npServerId', 1) : defaultServer;
1820 if(currVideoUrl && partySessionId && serverId) {
1821 var urlWithSessionId = currVideoUrl + '?npSessionId=' + encodeURIComponent(sessionId) + '&npServerId=' + encodeURIComponent(serverId);
1822 console.log(urlWithSessionId);
1823 // jQuery('#share-url').val(urlWithSessionId).focus().select();
1824
1825 const el = document.createElement('textarea');
1826 el.value = urlWithSessionId;
1827 document.body.appendChild(el);
1828 el.select();
1829 document.execCommand('copy');
1830 document.body.removeChild(el);
1831
1832 }
1833
1834
1835 // document.execCommand('copy');
1836
1837 // e.stopPropagation();
1838 // e.preventDefault();
1839 }
1840 jQuery('#link-icon').click(linkIconListener);
1841
1842 // large user icon listener to go to icon holder menu
1843 var largeUserIconListener = function(e) {
1844 console.log('userIcon button clicked');
1845 // console.log()
1846 toggleLargeUserIconButton();
1847 }
1848 jQuery('.user-icon').click(largeUserIconListener);
1849
1850
1851 addIconSelector();
1852 var userIconSelectorListener = function(e) {
1853 if(jQuery(this).data('icon')) {
1854 console.log('userIconSelector button clicked: ' + jQuery(this).data('icon'));
1855 setUserIcon(userSettings.userId, jQuery(this).data('icon'), true);
1856 }
1857
1858 // setUserIcon();
1859 // logIcons();
1860 // console.log()
1861 toggleIconContainer();
1862 }
1863 jQuery('.image-button').click(userIconSelectorListener);
1864
1865 var saveChangesListener = function(e) {
1866 var nicknameText = jQuery('.nickname-input input').val().replace(/^\s+|\s+$/g, '');
1867
1868 if(nicknameText != '') {
1869 console.log('saveChanges button clicked: ' + nicknameText);
1870 setUserNickname(userSettings.userId, nicknameText, true);
1871 }
1872
1873 // setUserIcon();
1874 // logIcons();
1875 // console.log()
1876 toggleIconContainer();
1877 }
1878 jQuery('.btns button').click(saveChangesListener);
1879
1880
1881
1882 var oldPageX = null;
1883 var oldPageY = null;
1884 jQuery('#chat-wrapper').mousedown(function(e) {
1885 oldPageX = e.pageX;
1886 oldPageY = e.pageY;
1887 });
1888 jQuery('#chat-wrapper').mouseup(function(e) {
1889 if ((e.pageX - oldPageX) * (e.pageX - oldPageX) + (e.pageY - oldPageY) * (e.pageY - oldPageY) < 5) {
1890 jQuery('#chat-input').focus();
1891 e.stopPropagation();
1892 }
1893 });
1894 jQuery('#chat-input-container').click(function(e) {
1895 jQuery('#chat-input').focus();
1896 });
1897 jQuery('#chat-input').keyup(function(e) {
1898 e.stopPropagation();
1899
1900 // event keycode 13 is the enter key
1901 if (e.which === 13) {
1902 var body = jQuery('#chat-input').val().replace(/^\s+|\s+$/g, '');
1903 if (body !== '') {
1904 if (typingTimer !== null) {
1905 clearTimeout(typingTimer);
1906 typingTimer = null;
1907 socket.emit('typing', { typing: false }, function() {});
1908 }
1909
1910 jQuery('#chat-input').prop('disabled', true);
1911 socket.emit('sendMessage', {
1912 body: body
1913 }, function() {
1914 jQuery('#chat-input').val('').prop('disabled', false).focus();
1915 });
1916 }
1917 } else {
1918 if (typingTimer === null) {
1919 socket.emit('typing', { typing: true }, function() {});
1920 } else {
1921 clearTimeout(typingTimer);
1922 }
1923 typingTimer = setTimeout(function() {
1924 typingTimer = null;
1925 socket.emit('typing', { typing: false }, function() {});
1926 }, 500);
1927 }
1928 });
1929 // jQuery('#chat-input-avatar').html(`<img src="data:image/png;base64,${new Identicon(Sha256.hash(userId).substr(0, 32), avatarSize * 2, 0).toString()}" />`);
1930
1931 // receive messages from the server
1932 socket.on('sendMessage', function(data) {
1933 addMessage(data);
1934 });
1935
1936 // receive presence updates from the server
1937 socket.on('setPresence', function(data) {
1938 setPresenceVisible(data.anyoneTyping);
1939 });
1940
1941 // receive buffering presence updates from the server
1942 socket.on('setBufferingPresence', function(data) {
1943
1944 setBufferingPresenceVisible(data.anyoneBuffering);
1945 othersAreBuffering = data.anyoneBuffering;
1946
1947 var time = new Date();
1948 var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + 'AM';
1949 // console.log('received buffering update: ' + data.anyoneBuffering + timeStatus);
1950 // if(othersAreBuffering) console.log('others are buffering: ' + othersAreBuffering + timeStatus);
1951 });
1952
1953 } else {
1954 jQuery('#chat-history').html('');
1955 }
1956 };
1957
1958 // query whether the chat sidebar is visible
1959 var getChatVisible = function() {
1960 return jQuery('.sizing-wrapper').hasClass('with-chat');
1961 };
1962
1963 // show or hide the chat sidebar
1964 var setChatVisible = function(visible) {
1965 if (visible) {
1966 jQuery('.sizing-wrapper').addClass('with-chat');
1967 jQuery('.sizing-wrapper').css('right', chatSidebarWidth + 'px');
1968 jQuery('#chat-wrapper').show();
1969 if (!document.hasFocus()) {
1970 clearUnreadCount();
1971 }
1972 } else {
1973 jQuery('#chat-wrapper').hide();
1974 jQuery('.sizing-wrapper').removeClass('with-chat');
1975 jQuery('.sizing-wrapper').css('right', '0px');
1976 }
1977 };
1978
1979 // show or hide the icon container
1980 var toggleIconContainer = function() {
1981 // console.log('toggle')
1982
1983 // document.getElementById("demo").innerHTML = "Hello World";
1984 if(jQuery("#chat-icon-container").data('active')) {
1985 jQuery("#chat-icon-container").data('active', false);
1986 jQuery("#chat-icon-container").hide();
1987 jQuery(".chat-settings-container").hide();
1988
1989 // jQuery("#chat-link-container").show();
1990 jQuery("#chat-history-container").show();
1991 jQuery("#chat-input-container").show();
1992 jQuery("#patreon-container").show();
1993
1994 } else {
1995 jQuery("#chat-icon-container").data('active', true);
1996 // jQuery("#chat-icon-container").show();
1997 jQuery(".chat-settings-container").show();
1998 jQuery("#chat-icon-container").hide();
1999 jQuery("#chat-link-container").hide();
2000 jQuery("#chat-history-container").hide();
2001 jQuery("#chat-input-container").hide();
2002 jQuery("#patreon-container").hide();
2003 }
2004 };
2005
2006 // show or hide the icon container
2007 var toggleLargeUserIconButton = function() {
2008 // console.log('toggle')
2009
2010 // document.getElementById("demo").innerHTML = "Hello World";
2011 if(jQuery("#chat-icon-container").data('active')) {
2012 // jQuery("#chat-icon-container").data('active', false);
2013 jQuery("#chat-icon-container").show();
2014 // jQuery("#chat-link-container").show();
2015 jQuery(".chat-settings-container").hide();
2016 // jQuery(".chat-settings-container").data('active', false);
2017
2018 }
2019 };
2020
2021 // remove chat
2022 var removeChat = function() {
2023 clearUnreadCount();
2024 jQuery('#chat-container').remove();
2025 jQuery('#chat-wrapper').remove();
2026 jQuery('.sizing-wrapper').removeClass('with-chat');
2027 jQuery('.sizing-wrapper').css('right', '0px');
2028 };
2029
2030 // show or hide the "People are typing..." indicator
2031 var setPresenceVisible = function(visible) {
2032 jQuery('#presence-indicator').data('typing', visible);
2033 setPresenceText();
2034 if (visible) {
2035 jQuery('#presence-indicator').show();
2036 } else {
2037 // jQuery('#presence-indicator').hide();
2038 }
2039 };
2040
2041 // show or hide the "People are buffering..." indicator
2042 var setBufferingPresenceVisible = function(visible) {
2043 jQuery('#presence-indicator').data('buffering', visible);
2044 setPresenceText();
2045 if (visible) {
2046 jQuery('#presence-indicator').show();
2047 } else {
2048 // jQuery('#presence-indicator').hide();
2049 }
2050 };
2051
2052 var setPresenceText = function() {
2053 var typing = jQuery('#presence-indicator').data('typing');
2054 var buffering = jQuery('#presence-indicator').data('buffering');
2055 if(typing && buffering) {
2056 jQuery('#presence-indicator').text('People are typing and buffering...')
2057 } else if (typing) {
2058 jQuery('#presence-indicator').text('People are typing...')
2059 } else if(buffering) {
2060 jQuery('#presence-indicator').text('People are buffering...')
2061 } else {
2062 jQuery('#presence-indicator').text(' ')
2063 }
2064 }
2065
2066 // var iconURL = chrome.runtime.getURL('img/' + icons[Math.floor(Math.random() * icons.length)]);
2067
2068 // add a message to the chat history
2069 var addMessage = function(message) {
2070
2071 // jQuery('#chat-history').append(`
2072 // <div class="chat-message${ message.isSystemMessage ? ' system-message' : '' }">
2073 // <div class="chat-message-avatar"><img src="data:image/png;base64,${new Identicon(Sha256.hash(message.userId).substr(0, 32), avatarSize * 2, 0).toString()}" /></div>
2074 // <div class="chat-message-body">${message.body.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')}</div>
2075 // </div>
2076 // `);
2077
2078 // console.log("messageId " + message.userId);
2079 // console.log("message permId " + message.permId);
2080 // console.log("message userIcon " + message.userIcon);
2081 // console.log("user/perm: " + userId + ", " + permId);
2082 // console.log("messageId is the same as userId: " + (message.userId === userId));
2083 // console.log("message permId is the same as userId: " + (message.permId === permId));
2084 // console.log(JSON.stringify(userIcons));
2085
2086 if(message.isSystemMessage && message.body === 'left') {
2087 console.log("trying to add left message");
2088 if(!(message.userIcon)) {
2089 // ignore invalid left message
2090 return;
2091 }
2092 }
2093
2094 messages.push(message);
2095
2096
2097 var userIcon = message.userIcon ? getUserIconURL(message.permId, message.userIcon) : getUserIconURL(message.permId);
2098 var userNickname = message.userNickname ? getUserNickname(message.permId, message.userNickname) : '' // todo create getUserNickame method
2099
2100 if(userNickname == '') {
2101 var message = jQuery(`
2102 <div class="msg">
2103 <div class="icon">
2104 <img src="${userIcon}"/>
2105 </div>
2106 <div class="message${ message.isSystemMessage ? '-system' : '-txt' }">
2107 <p class="msg-nickname">${userNickname.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')}</p>
2108 <p>${message.body.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')}</p>
2109 </div>
2110 </div>
2111 `).appendTo(jQuery('#chat-history')).data('permId', message.permId).data('userIcon', userIcon).data('userNickname', userNickname).data('message', message);
2112 } else {
2113 var nicknameMessage = jQuery(`
2114 <div class="msg-container">
2115 <div class="icon-name">
2116 <div class="icon">
2117 <img src="${userIcon}">
2118 </div>
2119 </div>
2120 <div class="msg-txt message${ message.isSystemMessage ? '-system' : '-txt' }">
2121 <h3>${userNickname.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')}</h3>
2122 <p>${message.body.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>')}</p>
2123 </div>
2124 </div>
2125 `).appendTo(jQuery('#chat-history')).data('permId', message.permId).data('userIcon', userIcon).data('userNickname', userNickname);
2126 }
2127
2128
2129
2130 jQuery('#chat-history').scrollTop(jQuery('#chat-history').prop('scrollHeight'));
2131 unreadCount += 1;
2132 messagesCount += 1;
2133 if (!document.hasFocus()) {
2134 document.title = '(' + String(unreadCount) + ') ' + originalTitle;
2135 }
2136 };
2137
2138 // clear the unread count
2139 var clearUnreadCount = function() {
2140 if (unreadCount > 0) {
2141 unreadCount = 0;
2142 document.title = originalTitle;
2143 }
2144 };
2145
2146 // clear the unread count when the window is focused
2147 jQuery(window).focus(function() {
2148 if (getChatVisible()) {
2149 clearUnreadCount();
2150 }
2151 });
2152
2153 // send summary statistics to data server
2154 function logSummary() {
2155 try {
2156 if(permId && sessionStartTime && sessionId && videoId && !summarySent) {
2157
2158 var data = {
2159 userId: permId,
2160 sessionId: sessionId,
2161 messagesCount: messagesCount,
2162 interactionsCount: interactionsCount,
2163 duration: new Date() - sessionStartTime,
2164 videoId: videoId,
2165 videoDuration: videoDuration
2166 }
2167 console.log("summaryData: " + JSON.stringify(data));
2168
2169 chrome.runtime.sendMessage({summary: data}, function(response) {
2170 console.log("background script sent xhr");
2171 });
2172
2173 summarySent = true;
2174
2175 }
2176
2177 } catch(e) {
2178 console.log("log event error");
2179 }
2180 }
2181
2182 var unloadInteraction = function (event) {
2183 logSummary();
2184 }
2185 window.addEventListener("unload", unloadInteraction , true);
2186
2187
2188 //////////////////////////////////////////////////////////////////////////
2189 // Next episode logic //
2190 //////////////////////////////////////////////////////////////////////////
2191
2192 // whether a simulated next episode click is ongoing
2193 var simulClick = false;
2194
2195 // whether the new episode is some other episode or the next episode
2196 var otherEpisode = false
2197
2198 // receive next episode updates from the server
2199 socket.on('jumpToNextEpisode', function(data) {
2200 console.log('received next Episode event: ' + JSON.stringify(data));
2201
2202 if(data.otherEpisode) {
2203 continueOtherEpisode(data.nextEpisode)
2204 } else {
2205 continueNextEpisode(data.nextEpisode);
2206 }
2207 });
2208
2209 // enable or disable the session, used during episode transitions
2210 var oldSessionId = null;
2211 var sessionDisabledStartTime = null;
2212 var setSessionEnabled = function(enabled) {
2213 // enable session
2214 if (enabled) {
2215 if(oldSessionId != null && sessionId == null) {
2216 sessionId = oldSessionId;
2217 oldSessionId = null;
2218 sessionDisabledStartTime = null;
2219 // uiEventsHappening = 0;
2220 }
2221 }
2222 // disable session
2223 else {
2224 if(oldSessionId == null && sessionId != null) {
2225 oldSessionId = sessionId;
2226 sessionId = null;
2227 var now = new Date();
2228 sessionDisabledStartTime = new Date(now.getTime() - localTimeMinusServerTimeMedian)
2229 console.log('sessionDisabledStartTime CREATED: ' + sessionDisabledStartTime.getTime());
2230 }
2231 }
2232 };
2233
2234 // disable video synchronization for Netflix Party
2235 var disableSync = function() {
2236
2237 }
2238
2239 // enable video synchronization for Netlfix Party
2240 var enableSync = function() {
2241
2242 }
2243
2244 // jump to next episode if not already on it
2245 var continueNextEpisode = function(nextEpisode) {
2246 var parseIds = window.location.href.match(/^.*\/([0-9]+)\??.*/);
2247 var currVideoId = parseIds.length !== 0 ? parseInt(window.location.href.match(/^.*\/([0-9]+)\??.*/)[1]) : null;
2248
2249 // jump to next episode if currEpisode != next Epsiode
2250 if (currVideoId != nextEpisode) {
2251 // disable the session until the video loads
2252 setSessionEnabled(false);
2253 // oldSessionId = sessionId;
2254 // sessionId = null;
2255
2256
2257 // tasks = Promise.resolve();
2258 simulClick = true;
2259
2260 // otherwise click on the autoplay next episode hover container (short episodes like Friends)
2261 if (jQuery('.WatchNext-still-hover-container').length > 0) {
2262 jQuery('.WatchNext-still-hover-container').click();
2263 }
2264
2265 // click on the next episode button (in the middle of episodes)
2266 else if (jQuery('.button-nfplayerNextEpisode').length > 0) {
2267 jQuery('.button-nfplayerNextEpisode').click();
2268 }
2269
2270 // otherwise click on the credits next episode button (before AND after credits on long episodes like Umbrella Academy)
2271 else if (jQuery('.nf-flat-button-text').length > 0) {
2272 if(jQuery('.nf-flat-button-text')[0].text.toLowerCase().includes('next episode')) {
2273 jQuery('.nf-flat-button-text')[0].click();
2274 // console.log('after credits click');
2275 }
2276 }
2277 }
2278 };
2279
2280 var continueOtherEpisode = function(otherEpisode) {
2281 // tabs[0].url.split('?')[0] + '?npSessionId=' + encodeURIComponent(sessionId) + '&npServerId=' + encodeURIComponent(serverIdFromUrl);
2282 // console.log()
2283
2284 var parseIds = window.location.href.match(/^.*\/([0-9]+)\??.*/);
2285 var currVideoId = parseIds.length !== 0 ? parseInt(window.location.href.match(/^.*\/([0-9]+)\??.*/)[1]) : null;
2286
2287 if (currVideoId != otherEpisode) {
2288 window.location.href = 'https://www.netflix.com/watch/' + otherEpisode;
2289 }
2290
2291 alert('Long parties only work for consecutive episodes for now. Please share a new Netflix Party to continue watching together.')
2292 }
2293
2294 // listen to URL changes on the webpage when next episode changes
2295 // modifies the window.history.replaceScript API which Netflix uses in its SPA
2296 // https://stackoverflow.com/questions/4570093/how-to-get-notified-about-changes-of-the-history-via-history-pushstate
2297 // http://jsfiddle.net/UZHTW/1/
2298 var replaceStateScript = `
2299 if(!window.replaceScriptLoaded) {
2300 console.log("loaded script");
2301 window.replaceScriptLoaded = true;
2302 (function(history){
2303 var replaceState = history.replaceState;
2304 history.replaceState = function(state) {
2305 if (typeof history.onreplacestate == "function") {
2306 history.onreplacestate({state: state});
2307 }
2308 return replaceState.apply(history, arguments);
2309 }
2310 })(window.history);
2311
2312 var reloadInteraction = function(e) {
2313 console.log("window.history replaceState event; autoplay / next episode clicked / navigated away");
2314
2315 // send message to content script w next episode
2316 window.postMessage({ type: "FROM_PAGE", text: "next episode from the webpage!"}, "*");
2317 }
2318 window.onpopstate = history.onreplacestate = reloadInteraction;
2319 }
2320 `;
2321 console.log('replace script loaded: '+ window.replaceScriptLoaded);
2322 if(!window.replaceScriptLoaded) {
2323 console.log('injecting replace script');
2324 injectScript(replaceStateScript);
2325 }
2326
2327 // listen for next episode events from webpage script via the postMessage API
2328 var replaceStateInteraction = function(event) {
2329 if (event.source != window)
2330 return;
2331
2332 if (event.data.type && (event.data.type == "FROM_PAGE")) {
2333 console.log('***********************************');
2334 logState = true;
2335 console.log("Content script received: " + event.data.text);
2336
2337 var episodePage = window.location.href.match(/^.*\/(watch)\/.*/);
2338 console.log(window.location.href)
2339 if (!episodePage) {
2340 console.log("time to teardown");
2341 teardown();
2342 } else {
2343 var parseIds = window.location.href.match(/^.*\/([0-9]+)\??.*/);
2344 var nextVideoId = parseIds.length !== 0 ? parseInt(window.location.href.match(/^.*\/([0-9]+)\??.*/)[1]) : null;
2345
2346 // console.log("simulClick:" + simulClick);
2347 // console.log("otherEpisode:" + otherEpisode);
2348 socket.emit('nextEpisode', {nextEpisode: nextVideoId, simulClick: simulClick, otherEpisode: otherEpisode}, function() {});
2349
2350 if(otherEpisode) {
2351 teardown();
2352 // alert('Autoplay only works for consecutive episodes for now. Please create a new Netflix Party to continue watching together.')
2353 alert('Long parties only work for consecutive episodes for now. Please share a new Netflix Party to continue watching together.')
2354 // alert('Long parties only work for consecutive episodes, not for the episode selector. Please create a new party to continue watching');
2355 } else if(!otherEpisode) {
2356
2357 console.log('replace disable session next episode')
2358 setSessionEnabled(false);
2359 // if(oldSessionId == null) {
2360 // oldSessionId = sessionId;
2361 // sessionId = null;
2362 // }
2363
2364
2365 if(oldSessionId != null) {
2366 console.log('oldSessionId is called');
2367
2368 swallow(
2369 delayUntil(function() {
2370 console.log('video unloading');
2371 return !getPlaybackPosition();
2372 }, 5000)
2373 )().then(swallow(
2374 delayUntil(function() {
2375 console.log('replace state loading START');
2376 // todo make sure remaining time > 0:00
2377 var remainingTimeLoaded = false;
2378 var remainingTime = getRemainingTime();
2379 var remainingTimeText = getRemainingTimeText();
2380 // console.log('remainingTime: ' + remainingTime);
2381 // console.log('remainingTimeText: ' + remainingTimeText);
2382 // console.log('remainingTimeLoaded: ' + remainingTimeLoaded);
2383 if(remainingTime != null) {
2384 remainingTimeLoaded = true;
2385 }
2386 return remainingTimeLoaded && getPlaybackPosition() && getState() !== 'loading';
2387 }, Infinity)
2388 )).then(function() {
2389
2390 console.log('replace state loading DONE');
2391 showControls();
2392
2393 // get scrubber time
2394 var localTime = getPlaybackPosition();
2395 var scrubberHead = jQuery(jQuery('.scrubber-head')[0]);
2396 var scrubberTime = parseInt(scrubberHead.attr('aria-valuenow') * 1000);
2397 showControls();
2398
2399 // TODO: get remaining time
2400
2401
2402 // console.log('replace localTime: '+ getPlaybackPosition());
2403 // console.log('replace scrubberTime: '+ scrubberTime);
2404
2405 var now = new Date();
2406 var newLastKnownTime = localTime; // update to use remaining time
2407 // var newLastKnownTime = localTime; // update to use remaining time
2408 var newLastKnownTimeUpdatedAt = new Date(now.getTime() - localTimeMinusServerTimeMedian);
2409 var newState = getState() === 'loading' ? 'paused' : (getState() === 'playing' ? 'playing' : 'paused');
2410
2411
2412 console.log('***********************************');
2413 console.log('localTimeMinusServerTimeMedian: ' + localTimeMinusServerTimeMedian);
2414 console.log('session disabled start time: ' + sessionDisabledStartTime.getTime());
2415 console.log('lastKnownTimeUpdatedAt: ' + lastKnownTimeUpdatedAt.getTime());
2416 var recentUpdate = (lastKnownTimeUpdatedAt.getTime() > sessionDisabledStartTime.getTime())
2417 console.log("RECENT UPDATE: " + recentUpdate);
2418 console.log('***********************************');
2419
2420
2421 if(!recentUpdate) {
2422
2423 oldLastKnownTime = lastKnownTime;
2424 oldLastKnownTimeUpdatedAt = lastKnownTimeUpdatedAt;
2425 oldState = state;
2426 lastKnownTime = newLastKnownTime;
2427 lastKnownTimeUpdatedAt = newLastKnownTimeUpdatedAt;
2428 state = newState;
2429
2430
2431 // console.log('simulClick is false so UPDATE');
2432 socket.emit(updateSessionTarget, {
2433 lastKnownTime: newLastKnownTime,
2434 lastKnownTimeUpdatedAt: newLastKnownTimeUpdatedAt.getTime(),
2435 state: newState,
2436 lastKnownTimeRemaining: getRemainingTime(),
2437 lastKnownTimeRemainingText: getRemainingTimeText(),
2438 videoDuration: getDuration(),
2439 bufferingState: false // change: bufferingState
2440 }, function(data) {
2441 if (data !== undefined && data.errorMessage !== null) {
2442 lastKnownTime = oldLastKnownTime;
2443 lastKnownTimeUpdatedAt = oldLastKnownTimeUpdatedAt;
2444 state = oldState;
2445 // reject();
2446 } else {
2447 // lastKnownTime = newLastKnownTime;
2448 // lastKnownTimeUpdatedAt = newLastKnownTimeUpdatedAt;
2449 // state = newState;
2450 // resolve();
2451 }
2452 // console.log('delay before reenabling for 1 sec');
2453 // delay(1000)().then(function() {
2454 console.log('re-enabling sync after next episode');
2455 console.log('***********************************');
2456 logState = false;
2457 var localTime = getPlaybackPosition() || "not defined";
2458 var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
2459 // console.log("localtime, internal servertime, state: " + localTime + ", " + serverTime + ", " + state);
2460
2461 allowFullScreen();
2462 setSessionEnabled(true);
2463 // sessionId = oldSessionId;
2464 // oldSessionId = null;
2465
2466 // pushTask(sync);
2467 // pushTask(broadcast(false));
2468 var localTime = getPlaybackPosition() || "not defined";
2469 var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
2470 // console.log("localtime, internal servertime, state: " + localTime + ", " + serverTime + ", " + state);
2471
2472 simulClick = false;
2473 otherEpisode = false;
2474 // });
2475
2476 });
2477
2478 } else {
2479
2480 console.log('recent update is true NO UPDATE');
2481
2482 // insert logic that checks for recent update between when sync was disable and re-enabled
2483 // if there is one then re-enable sync
2484 // if not then send over our own update
2485
2486 // compare syncDisabledTime to lastKnownUpdatedTimeAt
2487 // if syncDisabledTime is after lastKnowUpdatedTimeAt then
2488
2489 console.log('re-enabling sync after next episode');
2490 console.log('***********************************');
2491 logState = false;
2492 allowFullScreen();
2493 setSessionEnabled(true);
2494 // sessionId = oldSessionId;
2495 // oldSessionId = null;
2496
2497 var localTime = getPlaybackPosition() || "not defined";
2498 var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
2499 // console.log("localtime, internal servertime, state: " + localTime + ", " + serverTime + ", " + state);
2500
2501 simulClick = false;
2502 otherEpisode = false;
2503
2504 pushTask(sync);
2505
2506 }
2507 })
2508 }
2509 }
2510 }
2511 }
2512 }
2513 window.addEventListener("message", replaceStateInteraction, false);
2514
2515 // listen to clicks on next episode button
2516 var nextEpisodeListener = function(e) {
2517 console.log('next Episode button clicked');
2518 }
2519
2520 // listen to clicks for other episodes
2521 var otherEpisodeListener = function() {
2522 // console.log('listener triggered');
2523 // find() selects on all nested descendants, children() selects on children
2524 // if(jQuery(this).find('.can-play').length > 0) {
2525 console.log('other episode clicked!');
2526 otherEpisode = true;
2527 // }
2528 }
2529
2530 jQuery('.button-nfplayerNextEpisode').click(nextEpisodeListener);
2531 jQuery(document).on('click', '.nfp-episode-preview.expanded.can-play', otherEpisodeListener);
2532
2533 //////////////////////////////////////////////////////////////////////////
2534 // Main logic //
2535 //////////////////////////////////////////////////////////////////////////
2536
2537 // the Netflix player be kept within this many milliseconds of our
2538 // internal representation for the playback time
2539 var maxTimeError = 2500;
2540 var maxFreezeTimeError = 1000;
2541
2542 // configure sync from end
2543 var syncFromEnd = false;
2544 var updateSessionTarget = syncFromEnd ? 'updateSessionFromEnd' : 'updateSession';
2545
2546 // replace permId with userId in userSettings and var permId;
2547 var permIdFix = true;
2548
2549 // the session
2550 var sessionId = null;
2551 var lastKnownTime = null;
2552 var lastKnownTimeUpdatedAt = null;
2553 var ownerId = null;
2554 var state = null;
2555 var videoId = null;
2556 var videoDuration = null;
2557 var currentPage = window.location.href;
2558
2559 // ping the server periodically to estimate round trip time and client-server time offset
2560 var roundTripTimeRecent = [];
2561 var roundTripTimeMedian = 0;
2562 var localTimeMinusServerTimeRecent = [];
2563 var localTimeMinusServerTimeMedian = 0;
2564 var ping = function() {
2565 return new Promise(function(resolve, reject) {
2566 var startTime = (new Date()).getTime();
2567 socket.emit('getServerTime', { version: version }, function(serverTime) {
2568 var now = new Date();
2569
2570 // compute median round trip time
2571 shove(roundTripTimeRecent, now.getTime() - startTime, 5);
2572 roundTripTimeMedian = median(roundTripTimeRecent);
2573
2574 // compute median client-server time offset
2575 shove(localTimeMinusServerTimeRecent, (now.getTime() - Math.round(roundTripTimeMedian / 2)) - (new Date(serverTime)).getTime(), 5);
2576 localTimeMinusServerTimeMedian = median(localTimeMinusServerTimeRecent);
2577 // console.log('localTime - server time median: ' + localTimeMinusServerTimeMedian);
2578 // console.log('roundTripTimeMedian: ' + roundTripTimeMedian);
2579
2580 resolve();
2581 });
2582 });
2583 };
2584
2585 // this function should be called periodically to ensure the Netflix
2586 // player matches our internal representation of the playback state
2587 var sync = function() {
2588 if (sessionId === null) {
2589 // console.log('sync promise resolved');
2590 return Promise.resolve();
2591 }
2592 if (state === 'paused') {
2593 var promise;
2594 if (getState() === 'paused') {
2595 promise = Promise.resolve();
2596 } else {
2597 promise = pause();
2598 }
2599 return promise.then(function() {
2600 if (Math.abs(lastKnownTime - getPlaybackPosition()) > maxTimeError) {
2601 // console.log('seek event while paused added to promiseChain due to local time exceeding server time');
2602 return seek(lastKnownTime)();
2603 }
2604 });
2605 } else {
2606 return delayUntil(function() {
2607 var syncDelayState = getState();
2608 // console.log('syncDelayState: ' + getState());
2609 var localTime = getPlaybackPosition() || "not defined";
2610 var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
2611 // console.log("localtime, internal servertime, state: " + localTime + ", " + serverTime + ", " + state);
2612 return getState() !== 'loading';
2613 }, Infinity)().then(function() {
2614 var localTime = getPlaybackPosition();
2615 var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
2616 if (Math.abs(localTime - serverTime) > maxTimeError) {
2617 // console.log('seek event added to promiseChain due to local time exceeding server time');
2618 return seek(serverTime)()
2619 .then(function() {
2620 // if(othersAreBuffering) {
2621 // return freezeUntil(function() {
2622 // return !othersAreBuffering;
2623 // }, 3000)()
2624 // }
2625 })
2626 .then(function() {
2627 var localTime = getPlaybackPosition();
2628 var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
2629 if (localTime > serverTime && localTime <= serverTime + maxTimeError) {
2630 return freeze(localTime - serverTime)();
2631 } else {
2632 return play();
2633 }
2634 });
2635 } else {
2636 return play();
2637 // return Promise.resolve();
2638 }
2639 });
2640 }
2641 };
2642
2643
2644
2645 // this is called when we need to send an update to the server
2646 // waitForChange is a boolean that indicates whether we should wait for
2647 // the Netflix player to update itself before we broadcast
2648
2649 var logState = false;
2650 var oldState = getState();
2651 // console.log('oldState: ' + oldState);
2652 stateTimer = setInterval(function() {
2653 oldState = getState();
2654 if(logState) {
2655 // console.log('oldState: ' + oldState);
2656 var localTime = getPlaybackPosition() || "not defined";
2657 var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
2658 // console.log("localtime, internal servertime, state: " + localTime + ", " + serverTime + ", " + state);
2659 }
2660 }, 100);
2661
2662 var broadcast = function(waitForChange) {
2663 return function() {
2664 console.log('broadcast called w taskInFlight: ' + tasksInFlight);
2665 var localTime = getPlaybackPosition() || "not defined";
2666 var serverTime = lastKnownTime + (state === 'playing' ? ((new Date()).getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
2667 // console.log("localtime, internal servertime, state: " + localTime + ", " + serverTime + ", " + state);
2668
2669 // wait for video player state to change
2670 var promise;
2671 if (waitForChange) {
2672 var oldPlaybackPosition = getPlaybackPosition(); // TODO: fix crazy errors related to errors getting thrown here between episodes (BIG BUG)
2673 // var oldState = getState();
2674 var lastState = getState();
2675 // console.log("broadcast state, playback: " + oldState + ", " + oldPlaybackPosition);
2676 promise = swallow(delayUntil(function() {
2677 var newPlaybackPosition = getPlaybackPosition();
2678 var newState = getState();
2679 // console.log("new broadcast state, playback: " + newState + ", " + newPlaybackPosition);
2680 return Math.abs(newPlaybackPosition - oldPlaybackPosition) >= 1500 || newState !== oldState || newState !== lastState;
2681 }, 2500))();
2682 } else {
2683 promise = Promise.resolve();
2684 }
2685
2686 var alreadyUpdated = false;
2687 var bufferingState = false;
2688 return promise.then(delayUntil(function() {
2689
2690 // get scrubber time
2691 var localTime = getPlaybackPosition();
2692 var scrubberHead = jQuery(jQuery('.scrubber-head')[0]);
2693 var scrubberTime = parseInt(scrubberHead.attr('aria-valuenow') * 1000);
2694
2695 // var sessionIdString = sessionId ? sessionId : 'null';
2696 // console.log('showControls Start sessionId, uiEventsHappening: ' + sessionIdString + ', ' + uiEventsHappening);
2697 showControls(); // TODO: fix crazy errors related to errors getting thrown here between episodes (BIG BUG)
2698 // console.log('showControls End sessionId, uiEventsHappening: ' + sessionIdString + ', ' + uiEventsHappening);
2699
2700 // what can i do about this
2701
2702 var now = new Date();
2703 var newLastKnownTime = scrubberTime;
2704 var newLastKnownTimeRemaining = getDuration() - scrubberTime;
2705 var newLastKnownTimeUpdatedAt = new Date(now.getTime() - localTimeMinusServerTimeMedian);
2706 var newState = getState() === 'loading' ? 'paused' : (getState() === 'playing' ? 'playing' : 'paused');
2707
2708 // console.log('currently buffering. current Time: ' + localTime + 'scrubber time: ' + scrubberTime);
2709
2710 if(!alreadyUpdated) {
2711 bufferingState = getState() === 'loading';
2712 if(bufferingState) {
2713
2714 // broadcast start of buffering
2715 alreadyUpdated = true;
2716 socket.emit('buffering', { buffering: true }, function() {});
2717
2718 var time = new Date();
2719 var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + 'AM';
2720 // console.log('broadcast user seek: buffering start -> server' + timeStatus);
2721
2722 // send update video event
2723 // console.log('updateSession -> socket connection' + timeStatus);
2724 socket.emit(updateSessionTarget, {
2725 lastKnownTime: newLastKnownTime,
2726 lastKnownTimeUpdatedAt: newLastKnownTimeUpdatedAt.getTime(),
2727 state: newState,
2728 lastKnownTimeRemaining: newLastKnownTimeRemaining,
2729 lastKnownTimeRemainingText: getRemainingTimeText(),
2730 videoDuration: getDuration(),
2731 bufferingState: bufferingState // change: bufferingState
2732 }, function(data) {
2733 if (data !== undefined && data.errorMessage !== null) {
2734 lastKnownTime = oldLastKnownTime;
2735 lastKnownTimeUpdatedAt = oldLastKnownTimeUpdatedAt;
2736 state = oldState;
2737 // reject();
2738 } else {
2739 // resolve();
2740 }
2741 });
2742 }
2743 }
2744 return getState() !== 'loading';
2745 }, Infinity)).then(function() {
2746
2747 if(bufferingState) {
2748 var time = new Date();
2749 var timeStatus = ' at' + time.getHours() + ':' + time.getMinutes() + ':' + time.getMilliseconds() + 'AM';
2750 // console.log('broadcast user seek: buffering end -> server' + timeStatus);
2751 socket.emit('buffering', { buffering: false }, function() {});
2752 }
2753
2754 var now = new Date();
2755 var localTime = getPlaybackPosition();
2756 var serverTime = lastKnownTime + (state === 'playing' ? (now.getTime() - (lastKnownTimeUpdatedAt.getTime() + localTimeMinusServerTimeMedian)) : 0);
2757 var newLastKnownTime = localTime;
2758 var newLastKnownTimeUpdatedAt = new Date(now.getTime() - localTimeMinusServerTimeMedian);
2759 var newState = getState() === 'playing' ? 'playing' : 'paused';
2760 if (state === newState && Math.abs(localTime - serverTime) < 1) {
2761 return Promise.resolve();
2762 } else {
2763 var oldLastKnownTime = lastKnownTime;
2764 var oldLastKnownTimeUpdatedAt = lastKnownTimeUpdatedAt;
2765 var oldState = state;
2766 lastKnownTime = newLastKnownTime;
2767 lastKnownTimeUpdatedAt = newLastKnownTimeUpdatedAt;
2768 state = newState;
2769 return new Promise(function(resolve, reject) {
2770 // console.log('updateSession -> socket connection');
2771 socket.emit(updateSessionTarget, {
2772 lastKnownTime: newLastKnownTime,
2773 lastKnownTimeUpdatedAt: newLastKnownTimeUpdatedAt.getTime(),
2774 state: newState,
2775 lastKnownTimeRemaining: getRemainingTime(),
2776 lastKnownTimeRemainingText: getRemainingTimeText(),
2777 videoDuration: getDuration(),
2778 bufferingState: bufferingState
2779 }, function(data) {
2780 if (data !== undefined && data.errorMessage !== null) {
2781 lastKnownTime = oldLastKnownTime;
2782 lastKnownTimeUpdatedAt = oldLastKnownTimeUpdatedAt;
2783 state = oldState;
2784 reject();
2785 } else {
2786 resolve();
2787 }
2788 });
2789 });
2790 }
2791 }).then(function() {
2792 // wait when others are buffering
2793 // if(othersAreBuffering) {
2794 // return freezeUntil(function() {
2795 // return !othersAreBuffering;
2796 // }, 3000)()
2797 // }
2798 });
2799 };
2800 };
2801
2802 // this is called when data is received from the server
2803 var receive = function(data) {
2804 console.log("received data: " + JSON.stringify(data));
2805 // console.log("received data: " + getDuration());
2806
2807 if(syncFromEnd) {
2808 // try to sync to local video duration - lastKnownTimeRemaining from server update
2809
2810 // negative lastKnownTime -> do nothing
2811 if (getDuration() < data.lastKnownTimeRemaining) {
2812
2813 // update
2814 pushTask(broadcast(false));
2815 return function() { return Promise.resolve(); }
2816 } else {
2817 lastKnownTime = getDuration() - data.lastKnownTimeRemaining;
2818 }
2819
2820
2821 // TODO: if negative last known time fix to send update to force everyone to get onto video
2822 } else {
2823 // try to sync to lastKnownTime from server update
2824 lastKnownTime = data.lastKnownTime;
2825 }
2826
2827 state = data.state;
2828 lastKnownTimeUpdatedAt = new Date(data.lastKnownTimeUpdatedAt);
2829 return sync;
2830 };
2831
2832 // the following allows us to linearize all tasks in the program to avoid interference
2833 var tasks = null;
2834 var tasksInFlight = 0;
2835
2836 var pushTask = function(task) {
2837 // console.log('pushTask called w tasksInFlight: ' + tasksInFlight);
2838 if (tasksInFlight === 0) {
2839 // why reset tasks here? in case the native promises implementation isn't
2840 // smart enough to garbage collect old completed tasks in the chain.
2841 tasks = Promise.resolve();
2842 }
2843 tasksInFlight += 1;
2844 tasks = tasks.then(function() {
2845 if (getState() === 'idle') {
2846 swallow(wakeUp)();
2847 }
2848 }).then(swallow(task)).then(function() {
2849 tasksInFlight -= 1;
2850 });
2851 };
2852
2853 // returns true if a user action is on a next episode button
2854 var isNextEpisodeClick = function(target) {
2855 if(jQuery(target).hasClass('button-nfplayerNextEpisode')) {
2856 console.log('BUTTON NEXT EPISODE CLICK?:')
2857 return true;
2858 }
2859 // otherwise click on the autoplay next episode hover container (short episodes like Friends)
2860 else if (jQuery(target).hasClass('WatchNext-still-hover-container')) {
2861 console.log('HOVER NEXT EPISODE CLICK');
2862 return true;
2863 }
2864
2865 else if (jQuery(target).hasClass('PlayIcon')) {
2866 console.log('HOVER NEXT EPISODE CLICK');
2867 return true;
2868 }
2869
2870 // click on the next episode button (in the middle of episodes)
2871 else if (jQuery(target).hasClass('button-nfplayerNextEpisode').length > 0) {
2872 // jQuery('.button-nfplayerNextEpisode').click()
2873 return true;
2874 }
2875 // otherwise click on the credits next episode button (before AND after credits on long episodes like Umbrella Academy)
2876 else if (jQuery(target).hasClass('nf-flat-button-text')) {
2877 console.log('CREDITS NEXT EPISODE CLICK?:' + jQuery(target).text());
2878
2879 if(jQuery(target).text().toLowerCase().includes('next episode')) {
2880 return true;
2881 // jQuery('.nf-flat-button-text')[0].click();
2882 // console.log('after credits click');
2883 }
2884 } else {
2885 return false;
2886 }
2887 }
2888
2889 var mouseupListener = function() {
2890 console.log("mouseup");
2891 // console.log(jQuery(event.target).attr('class'));
2892 // console.log(jQuery(event.target).text());
2893 // console.log(jQuery(event.target).hasClass('button-nfplayerNextEpisode'));
2894
2895 if(!isNextEpisodeClick(event.target)) {
2896 var sessionIdString = sessionId ? sessionId : 'null';
2897 console.log('sessionId, uiEventsHappening: ' + sessionIdString + ', ' + uiEventsHappening);
2898 if (sessionId !== null && uiEventsHappening === 0) {
2899 pushTask(function() {
2900 return broadcast(true)().catch(sync);
2901 });
2902 }
2903 } else {
2904
2905 console.log("sessionid disabled");
2906 setSessionEnabled(false);
2907 // oldSessionId = sessionId;
2908 // sessionId = null;
2909
2910
2911 // lastKnownTime = null;
2912 // lastKnownTimeUpdatedAt = null;
2913 // var ownerId = null;
2914 // state = null;
2915 }
2916 interactionsCount += 1;
2917 }
2918
2919 var keyupListener = function(e) {
2920 // e.stopPropagation();
2921 console.log("keyup");
2922 // console.log(event.target.className);
2923 // if(jQuery(event.target).hasClass('nfp')) {
2924 if (sessionId !== null && uiEventsHappening === 0) {
2925 pushTask(function() {
2926 return broadcast(true)().catch(sync);
2927 });
2928 }
2929 // }
2930 }
2931
2932 // broadcast the playback state if there is any user activity
2933 jQuery(window).mouseup(mouseupListener);
2934 jQuery(window).keyup(keyupListener);
2935
2936 var scriptInterval = null;
2937 var teardown = function() {
2938 window.postMessage({ type: "teardown"}, "*");
2939 window.removeEventListener("message", replaceStateInteraction, false);
2940 window.removeEventListener("unload", unloadInteraction , true);
2941 jQuery(window).off('mouseup', mouseupListener);
2942 jQuery(window).off('keyup', keyupListener);
2943
2944 if(sessionId) sessionId = null;
2945 window.netflixPartyLoaded = false;
2946 chrome.runtime.onMessage.removeListener(popupInteraction);
2947 if(socket) socket.disconnect();
2948 if(scriptInterval) clearInterval(scriptInterval);
2949 setChatVisible(false);
2950 removeChat();
2951 window.netflixpartyLoaded = false;
2952 logState = false;
2953 }
2954
2955 socket.on('connect', function() {
2956 pushTask(ping);
2957 console.log(currentPage);
2958 var lastTime = new Date();
2959 scriptInterval = setInterval(function() {
2960 if (tasksInFlight === 0) {
2961 var newTime = new Date();
2962 // console.log("ping sync: " + (newTime - lastTime));
2963 lastTime = new Date();
2964 pushTask(ping);
2965 pushTask(sync);
2966 }
2967 }, 5000);
2968 });
2969
2970 // if the server goes down, it can reconstruct the session with this
2971 socket.on('reconnect', function() {
2972 if (sessionId !== null) {
2973 socket.emit('reboot', {
2974 sessionId: sessionId,
2975 lastKnownTime: lastKnownTime,
2976 lastKnownTimeUpdatedAt: lastKnownTimeUpdatedAt.getTime(),
2977 messages: messages,
2978 state: state,
2979 ownerId: ownerId,
2980 userId: userId,
2981 videoId: videoId,
2982 videoDuration: getDuration(), //change: sending over video duration
2983 permId: permId, //change: sending over permId
2984 userSettings: userSettings,
2985 videoService: 'netflix'
2986 }, function(data) {
2987 pushTask(receive(data));
2988 });
2989 }
2990 });
2991
2992 // respond to updates from the server
2993 socket.on('update', function(data) {
2994 // console.log('***********************************');
2995 // console.log('on server update:' + JSON.stringify(data));
2996 pushTask(receive(data));
2997 });
2998
2999 // interaction with the popup
3000 var popupInteraction = function(request, sender, sendResponse) {
3001 if (request.type === 'getInitData') {
3002 version = request.data.version;
3003
3004 // fix bug where urls redirect to title page sometimes
3005 var parseIds = window.location.href.match(/^.*\/([0-9]+)\??.*/);
3006 var currVideoId = parseIds.length !== 0 ? parseInt(window.location.href.match(/^.*\/([0-9]+)\??.*/)[1]) : null;
3007 var videoDomId = (typeof jQuery("video").parent()[0] !== "undefined") ? parseInt(jQuery("video").parent()[0].id) : null;
3008 if((videoDomId != null) && (videoDomId != currVideoId)) {
3009 history.replaceState('data to be passed', 'Title of the page', '/watch/' + jQuery(jQuery("video").parent())[0].id);
3010 }
3011
3012 sendResponse({
3013 sessionId: sessionId,
3014 defaultServer: defaultServer,
3015 chatVisible: getChatVisible()
3016 });
3017 return;
3018 }
3019
3020 // TODO: edit for optional create session data
3021 if (request.type === 'createSession') {
3022 waitUserIdReady()().then(function() {
3023 console.log('create session permId: ' + permId);
3024 console.log('create session permId: ' + JSON.stringify(userSettings));
3025 socket.emit('createSession', {
3026 controlLock: request.data.controlLock,
3027 videoId: request.data.videoId,
3028 videoService: 'netflix',
3029 syncFromEnd: syncFromEnd, //change: sending over syncFromEnd
3030 videoDuration: getDuration(), //change: sending over video duration
3031 permId: permId, //change: sending over permId
3032 userSettings: userSettings // change: add userSettings here
3033 }, function(data) {
3034 initChat();
3035 // getChromeStorage()().then(initChat);
3036 setChatVisible(true);
3037 lastKnownTime = data.lastKnownTime;
3038 lastKnownTimeUpdatedAt = new Date(data.lastKnownTimeUpdatedAt);
3039 messages = [];
3040 sessionId = data.sessionId;
3041 ownerId = request.data.controlLock ? userId : null;
3042 state = data.state;
3043 videoId = request.data.videoId;
3044 videoDuration = getDuration();
3045 pushTask(broadcast(false));
3046
3047 // summary state
3048 sessionStartTime = new Date();
3049
3050 // console.log('defaultServer create: ' + defaultServer);
3051
3052 sendResponse({
3053 sessionId: sessionId,
3054 defaultServer: defaultServer
3055 });
3056 });
3057 })
3058 return true;
3059 }
3060
3061 if (request.type === 'joinSession') { /* change: add permId here. before: socket.emit('joinSession', request.data.sessionId, function(data) { */
3062 waitUserIdReady()().then(function() {
3063 var joinData = herokuSocket ? request.data.sessionId : {sessionId: request.data.sessionId, permId: permId, userSettings: userSettings} /* change: add usersettings here */
3064 socket.emit('joinSession', joinData, function(data) {
3065 if (data.errorMessage) {
3066 sendResponse({
3067 errorMessage: data.errorMessage
3068 });
3069 return;
3070 }
3071
3072 if (data.videoId !== request.data.videoId) {
3073 socket.emit('leaveSession', null, function(data) {
3074 sendResponse({
3075 errorMessage: 'That session is for a different video.'
3076 });
3077 });
3078 return;
3079 }
3080
3081 initChat();
3082 // getChromeStorage()().then(initChat);
3083 setChatVisible(true);
3084 sessionId = request.data.sessionId;
3085 lastKnownTime = data.lastKnownTime;
3086
3087 syncFromEnd = data.syncFromEnd ? data.syncFromEnd : false;
3088 updateSessionTarget = syncFromEnd ? 'updateSessionFromEnd' : 'updateSession';
3089 if(syncFromEnd) {
3090 lastKnownTime = getDuration() - data.lastKnownTimeReamining;
3091 }
3092
3093 lastKnownTimeUpdatedAt = new Date(data.lastKnownTimeUpdatedAt);
3094 messages = [];
3095 for (var i = 0; i < data.messages.length; i += 1) {
3096 addMessage(data.messages[i]);
3097 }
3098 ownerId = data.ownerId;
3099 state = data.state;
3100 videoId = request.data.videoId;
3101 videoDuration = getDuration();
3102 pushTask(receive(data));
3103 sendResponse({});
3104 });
3105 })
3106 return true;
3107 }
3108
3109 if (request.type === 'leaveSession') {
3110 socket.emit('leaveSession', null, function(_) {
3111 logSummary();
3112 sessionId = null;
3113 setChatVisible(false);
3114 sendResponse({});
3115 });
3116 return true;
3117 }
3118
3119 if (request.type === 'showChat') {
3120 // console.log('showChat');
3121 if (request.data.visible) {
3122 setChatVisible(true);
3123 } else {
3124 setChatVisible(false);
3125 }
3126 sendResponse({});
3127 }
3128 } // end of popup interaciton
3129 //
3130
3131 // getChromeStorage()()
3132 // getChromeStorage()()
3133 // getUserIdPromise()
3134 // waitUserIdReady()()
3135 getUserIdPromise()
3136 .then(getChromeStorage())
3137 .then(setHTML)
3138 .then(chrome.runtime.onMessage.addListener(popupInteraction));
3139 }
3140};
3141
3142
3143console.log('inject content script after this');
3144
3145// check that server data includes valid server settings
3146// function validateServers(serverJsonString) {
3147// var validated = false;
3148
3149// try {
3150// serverJson = JSON.parse(serverJsonString);
3151// console.log('this is called');
3152// var jsonCheck = (typeof serverJson === 'object') && ((serverJson.defaultServerOptions || serverJson.servers) != undefined);
3153// var optionsCheck
3154// if(jsonCheck) {
3155// if(serverJson.defaultServerOptions) {
3156// var optionsCheck = Array.isArray(serverJson.defaultServerOptions);
3157// jsonCheck = jsonCheck && optionsCheck;
3158// }
3159// if(serverJson.servers) {
3160// var serversCheck = typeof serverJson.servers === 'object';
3161// jsonCheck = jsonCheck && serversCheck;
3162// }
3163// }
3164// return jsonCheck;
3165// } catch {
3166// return false;
3167// }
3168// return true;
3169// }
3170
3171// // Get default server settings from config server, if not available fall back to hardcoded settings
3172// // switching to self-hosting config since s3 gets throttled
3173// if(!window.getServerSettings) {
3174// window.getServerSettings = true;
3175// console.log(window.getServerSettings);
3176
3177
3178// var xhr = new XMLHttpRequest();
3179
3180// xhr.onreadystatechange = function() {
3181// if (this.readyState == 4) {
3182// if(this.status == 200) {
3183// // document.getElementById("demo").innerHTML = this.responseText;
3184// if(validateServers(xhr.responseText)) {
3185// console.log('validate servers returned true');
3186// console.log('optionsConfig:' + JSON.stringify(optionsConfig));
3187
3188
3189
3190// var serverSettings = JSON.parse(xhr.responseText);
3191// var injectOptions = serverSettings.defaultServerOptions ? serverSettings.defaultServerOptions : optionsConfig;
3192// var injectServers = serverSettings.servers ? serverSettings.servers : serversConfig;
3193// injectContentScript(injectOptions, injectServers);
3194// // console.log('serverSettings:' + JSON.stringify(serverSettings.defaultServerOptions));
3195
3196// } else {
3197// injectContentScript();
3198// }
3199// } else {
3200// injectContentScript();
3201// }
3202// }
3203// };
3204
3205// xhr.onerror = function(e) {
3206// console.log('error found');
3207// injectContentScript();
3208// };
3209
3210// xhr.open('GET', 'https://netflixparty.s3.amazonaws.com/serverSettings.json', true);
3211// xhr.send(null);
3212// }
3213// setTimeout(function(){ injectContentScript()}, 1000);
3214
3215injectContentScript();