2 lines
208 KiB
Plaintext
2 lines
208 KiB
Plaintext
)]}'
|
|
{"version":3,"sources":["ddp/common.js","ddp/sockjs-0.3.4.js","ddp/stream_client_sockjs.js","ddp/stream_client_common.js","ddp/heartbeat.js","ddp/livedata_common.js","ddp/random_stream.js","ddp/livedata_connection.js","ddp/client_convenience.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,G;AACA,iB;AACA,kD;AACA,G;AACA,S;AACA,kB;;;;;;;;;;;;;;;;;;;ACLA,iC;;AAEA,+D;;AAEA,oC;;AAEA,4E;AACA,6E;AACA,4E;AACA,yE;AACA,qE;AACA,wD;;AAEA,0E;AACA,mD;;AAEA,0E;AACA,wE;AACA,2E;AACA,sE;AACA,6E;AACA,yE;AACA,a;AACA,E;;AAEA,wE;AACA,yC;AACA,i5F;AACA,Y;;AAEA,iC;AACA,gB;AACA,qB;AACA,uC;AACA,mC;AACA,6B;;;AAGA,4C;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,iD;AACA,2E;AACA,G;AACA,iC;AACA,0E;AACA,0B;AACA,8B;AACA,K;AACA,yC;AACA,wC;AACA,K;AACA,yC;AACA,gD;AACA,2B;AACA,K;AACA,W;AACA,E;;AAEA,6E;AACA,8D;AACA,e;AACA,K;AACA,yC;AACA,8C;AACA,qB;AACA,4B;AACA,sF;AACA,gB;AACA,8C;AACA,S;AACA,e;AACA,K;AACA,W;AACA,E;;AAEA,yD;AACA,uB;AACA,wD;AACA,uB;AACA,uC;AACA,K;AACA,kD;AACA,0D;AACA,oD;AACA,S;AACA,K;AACA,E;AACA,yC;;;AAGA,2C;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,uC;AACA,qB;AACA,qC;AACA,2B;AACA,iD;AACA,6B;AACA,S;AACA,K;AACA,E;;AAEA,6C;AACA,e;AACA,wB;AACA,8C;AACA,wB;AACA,sD;AACA,4B;AACA,K;AACA,+C;AACA,E;AACA,wC;;;AAGA,4C;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,qC;AACA,oB;AACA,gC;AACA,yB;AACA,E;AACA,8C;AACA,oB;AACA,2B;AACA,4B;;AAEA,wD;AACA,0B;AACA,0C;AACA,K;AACA,kC;AACA,+D;AACA,uD;AACA,S;AACA,K;AACA,E;;AAEA,sD;AACA,oB;AACA,2B;AACA,4B;;AAEA,qC;AACA,mC;AACA,K;AACA,yC;AACA,E;;AAEA,qD;AACA,oB;AACA,sD;AACA,mD;AACA,iE;AACA,iC;AACA,K;AACA,E;;AAEA,0C;AACA,oB;AACA,uB;AACA,8C;AACA,qC;AACA,K;AACA,yB;AACA,E;AACA,yC;;;AAGA,qC;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,kE;AACA,6C;AACA,4C;AACA,oB;AACA,+B;AACA,kF;AACA,K;AACA,wB;AACA,E;AACA,qC;AACA,2C;AACA,E;AACA,4C;AACA,kC;AACA,iC;AACA,oD;AACA,E;;AAEA,sD;AACA,iC;AACA,e;AACA,2C;AACA,2B;AACA,E;;AAEA,gD;AACA,+D;AACA,8C;;AAEA,iD;AACA,mB;AACA,mD;AACA,E;;AAEA,W;AACA,oD;AACA,mD;AACA,8C;;AAEA,+B;AACA,mB;AACA,iC;AACA,E;AACA,Y;;;AAGA,uC;AACA,sB;AACA,0C;AACA,sB;AACA,oC;AACA,c;AACA,uC;;AAEA,wC;AACA,2B;AACA,E;;AAEA,yC;AACA,uB;AACA,oC;AACA,4B;AACA,S;AACA,K;AACA,e;AACA,E;;AAEA,oB;;AAEA,2C;AACA,gC;AACA,8B;AACA,K;AACA,E;;AAEA,4C;AACA,8C;AACA,E;;AAEA,qC;AACA,2D;AACA,E;;AAEA,yE;AACA,gB;AACA,iC;AACA,Y;AACA,oB;AACA,uC;AACA,Y;AACA,oD;AACA,K;AACA,e;AACA,C;;AAEA,wB;AACA,8D;AACA,8C;AACA,K;AACA,E;;AAEA,kC;AACA,mB;AACA,8B;AACA,Y;AACA,2B;AACA,8C;AACA,U;AACA,K;AACA,E;;AAEA,+B;AACA,8D;AACA,E;;AAEA,uE;AACA,yE;AACA,W;AACA,4C;AACA,gB;AACA,mC;AACA,mC;AACA,Y;AACA,+D;AACA,0B;AACA,sD;AACA,yD;AACA,4D;AACA,sB;AACA,kC;AACA,O;AACA,+B;AACA,8D;AACA,iB;AACA,2B;AACA,kB;AACA,Q;AACA,K;AACA,e;AACA,gD;AACA,K;AACA,8B;AACA,mE;AACA,K;;AAEA,gC;AACA,kC;AACA,qC;AACA,K;AACA,6C;AACA,iC;AACA,2D;AACA,K;AACA,gB;AACA,6B;AACA,kC;;AAEA,sE;AACA,0E;AACA,sD;AACA,+B;AACA,0D;AACA,yD;AACA,gD;AACA,E;AACA,0B;AACA,e;AACA,E;;AAEA,iC;AACA,sC;AACA,sC;AACA,2B;AACA,qB;AACA,S;AACA,K;AACA,c;AACA,E;;AAEA,oC;AACA,yC;AACA,qB;AACA,2B;AACA,Y;AACA,oC;AACA,4C;AACA,K;AACA,E;;AAEA,gF;AACA,kD;AACA,wD;AACA,E;;AAEA,gC;AACA,iC;AACA,gB;AACA,c;AACA,K;AACA,8B;AACA,E;;;AAGA,yD;AACA,4G;AACA,gJ;AACA,mB;AACA,4E;AACA,4E;AACA,0E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,8D;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,4E;AACA,0D;;AAEA,qE;AACA,8B;AACA,ghC;AACA,iB;;AAEA,8D;AACA,8D;AACA,iC;AACA,sC;AACA,6D;AACA,kC;AACA,W;AACA,K;AACA,8B;AACA,E;;AAEA,sE;AACA,c;AACA,yC;AACA,U;AACA,qB;AACA,c;AACA,4B;AACA,yC;AACA,K;AACA,4B;AACA,gD;AACA,kF;AACA,kB;AACA,O;AACA,4B;AACA,oB;AACA,E;;AAEA,qE;AACA,4D;AACA,2E;AACA,gC;AACA,mC;;AAEA,8D;AACA,kC;AACA,uC;AACA,sB;AACA,K;;AAEA,oE;;AAEA,wD;AACA,+B;AACA,O;AACA,C;;AAEA,kC;AACA,sC;AACA,sC;AACA,2C;AACA,wC;AACA,oC;AACA,oC;AACA,2C;AACA,uC;;AAEA,mC;AACA,oB;AACA,gD;AACA,yC;AACA,iD;AACA,8C;AACA,sD;AACA,K;AACA,kB;AACA,E;;AAEA,qE;AACA,gB;AACA,uB;AACA,mE;AACA,qD;AACA,8C;AACA,wC;AACA,K;AACA,uC;AACA,mC;AACA,wB;AACA,kC;AACA,gB;AACA,oC;AACA,mC;AACA,a;AACA,S;AACA,K;;AAEA,mB;AACA,mC;AACA,kC;AACA,K;;AAEA,mB;AACA,mD;AACA,wC;AACA,Y;AACA,8E;AACA,4C;AACA,gB;AACA,6C;AACA,4C;AACA,S;AACA,K;;AAEA,iB;AACA,iD;AACA,sC;AACA,Y;AACA,4E;AACA,0C;AACA,gB;AACA,6C;AACA,0C;AACA,S;AACA,K;AACA,qB;AACA,C;AACA,kC;;;AAGA,mC;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,gD;AACA,+B;AACA,+B;AACA,iD;AACA,gC;AACA,qB;AACA,gD;AACA,sC;AACA,kC;AACA,kC;AACA,4D;AACA,kB;AACA,a;AACA,kC;AACA,S;AACA,K;AACA,uC;AACA,E;;;;AAIA,0C;AACA,2C;AACA,E;AACA,+C;AACA,0D;AACA,yD;AACA,Y;AACA,qB;AACA,0E;AACA,uE;AACA,sD;AACA,kC;AACA,oD;AACA,K;AACA,E;;AAEA,0C;AACA,2C;AACA,E;AACA,+C;AACA,0D;AACA,4D;AACA,Y;AACA,sD;AACA,oD;AACA,K;AACA,E;;;AAGA,mB;AACA,qE;AACA,yB;;AAEA,2C;AACA,+B;AACA,yB;AACA,8B;AACA,M;AACA,E;;AAEA,mC;AACA,4B;AACA,wB;AACA,+B;AACA,E;;AAEA,mE;AACA,gE;AACA,8C;;AAEA,uC;AACA,qC;AACA,8B;AACA,uB;AACA,8C;AACA,K;AACA,e;AACA,E;AACA,kC;AACA,yB;AACA,8B;AACA,E;;;AAGA,4D;AACA,mD;AACA,yB;AACA,+B;AACA,2B;AACA,2C;AACA,gD;AACA,8B;AACA,M;AACA,8B;AACA,qB;AACA,uB;AACA,kE;AACA,qE;AACA,wB;AACA,mC;AACA,4B;AACA,0D;AACA,iB;AACA,8B;AACA,kB;AACA,yC;AACA,S;AACA,M;AACA,+B;AACA,qB;AACA,sB;AACA,8B;AACA,S;AACA,M;AACA,sC;AACA,a;AACA,oE;AACA,kC;AACA,iD;AACA,8D;AACA,a;AACA,uB;AACA,M;;AAEA,4B;AACA,kC;AACA,uC;AACA,qD;AACA,gC;AACA,iE;AACA,gE;AACA,2B;AACA,wE;AACA,M;AACA,uC;AACA,8D;AACA,2C;AACA,Y;AACA,mB;AACA,yB;AACA,wB;AACA,M;AACA,E;;AAEA,8D;AACA,4C;AACA,yB;AACA,e;AACA,+B;AACA,2B;AACA,M;AACA,8B;AACA,kB;AACA,uB;AACA,yC;AACA,kD;AACA,gC;AACA,6B;AACA,S;AACA,M;AACA,gC;AACA,kB;AACA,sB;AACA,8B;AACA,S;AACA,M;AACA,sC;AACA,a;AACA,oE;AACA,kC;AACA,iD;AACA,8D;AACA,a;AACA,uB;AACA,M;;AAEA,e;AACA,qC;AACA,4D;AACA,uC;AACA,gB;AACA,iD;AACA,qC;AACA,4B;AACA,yC;AACA,0B;AACA,4B;AACA,8D;AACA,2C;AACA,Y;AACA,mB;AACA,yB;AACA,wB;AACA,M;AACA,E;AACA,gC;;;AAGA,oC;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,qC;AACA,oE;;AAEA,2E;AACA,oB;;AAEA,S;AACA,wC;AACA,kB;;AAEA,oB;AACA,a;AACA,sE;AACA,sB;AACA,K;AACA,0D;AACA,gC;AACA,0E;AACA,K;;AAEA,6D;AACA,0D;AACA,yE;AACA,S;AACA,yC;AACA,gB;AACA,gD;AACA,mC;AACA,wB;AACA,e;AACA,M;;AAEA,wC;AACA,8E;AACA,mD;AACA,0C;AACA,K;AACA,+B;AACA,sC;AACA,8D;AACA,S;AACA,K;;AAEA,8C;AACA,uB;AACA,6B;AACA,mC;AACA,mB;AACA,sE;AACA,wD;AACA,qB;AACA,0C;AACA,8C;AACA,+B;AACA,8E;AACA,kD;;AAEA,kE;AACA,8C;AACA,qD;AACA,iB;AACA,sB;AACA,mB;AACA,sC;AACA,8E;AACA,kD;;AAEA,4D;AACA,qC;AACA,sB;AACA,a;AACA,S;AACA,M;AACA,2B;AACA,E;;AAEA,wD;AACA,oB;AACA,0B;AACA,sC;;AAEA,2C;AACA,+C;;AAEA,gB;AACA,a;AACA,6B;AACA,sB;AACA,K;AACA,sC;AACA,E;;AAEA,gD;AACA,oB;AACA,gB;AACA,wB;AACA,E;;AAEA,sD;AACA,sC;AACA,4D;AACA,E;AACA,kD;;AAEA,4E;AACA,oB;AACA,2B;AACA,2C;AACA,gC;AACA,W;AACA,O;AACA,E;AACA,mD;;;;AAIA,c;AACA,sD;AACA,mE;AACA,kE;AACA,oB;AACA,gE;AACA,E;AACA,4D;AACA,6D;AACA,oB;AACA,mC;AACA,2B;AACA,sE;;AAEA,4D;AACA,mC;AACA,6B;AACA,M;AACA,iC;AACA,kD;AACA,M;AACA,6B;AACA,mD;AACA,6B;AACA,M;AACA,mB;AACA,yE;AACA,S;AACA,0D;AACA,mC;AACA,+B;AACA,gB;AACA,kB;AACA,K;AACA,E;;AAEA,gD;AACA,oB;AACA,0B;AACA,sC;;AAEA,iE;AACA,+B;AACA,gB;AACA,a;AACA,6B;AACA,sB;AACA,K;AACA,sC;AACA,E;;AAEA,wC;AACA,oB;AACA,gB;AACA,wB;AACA,E;;AAEA,yB;AACA,yB;AACA,sE;AACA,kB;AACA,qC;AACA,8E;AACA,iB;AACA,K;AACA,iE;AACA,qD;AACA,iB;AACA,K;AACA,oC;AACA,iB;AACA,K;AACA,a;AACA,E;AACA,iC;;;AAGA,sC;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,8D;AACA,oC;AACA,+B;AACA,iE;AACA,K;;AAEA,yC;AACA,yE;AACA,sD;AACA,kB;AACA,mD;AACA,K;AACA,yC;AACA,4E;AACA,4C;AACA,mD;AACA,gE;AACA,Y;AACA,yB;AACA,0D;AACA,iD;AACA,4D;AACA,4D;AACA,yD;AACA,gB;AACA,uC;AACA,S;AACA,kC;AACA,6E;AACA,2E;AACA,4D;AACA,S;AACA,K;AACA,yB;AACA,yB;AACA,wC;AACA,kD;AACA,6C;AACA,wB;AACA,mB;AACA,qC;AACA,uD;AACA,oE;AACA,a;AACA,oC;AACA,wC;AACA,a;AACA,4D;AACA,6B;AACA,gB;AACA,mE;AACA,S;AACA,M;AACA,E;AACA,c;AACA,sC;;AAEA,yB;;AAEA,sB;AACA,gB;AACA,mB;AACA,kB;;AAEA,sC;AACA,4B;AACA,0C;AACA,E;;AAEA,6C;AACA,oB;AACA,gD;AACA,mC;AACA,+C;AACA,wC;AACA,S;AACA,sC;AACA,oD;AACA,Y;AACA,sE;AACA,sB;AACA,oD;AACA,K;AACA,E;;AAEA,oD;AACA,oB;AACA,wC;AACA,mB;AACA,iE;AACA,E;;AAEA,sD;AACA,oB;AACA,wC;AACA,e;AACA,yD;AACA,E;;AAEA,4D;AACA,oB;AACA,gD;AACA,0C;AACA,2C;AACA,iD;AACA,mB;AACA,wB;AACA,wB;AACA,K;;AAEA,0B;AACA,oC;AACA,+B;AACA,K;;AAEA,gD;AACA,mB;AACA,uB;AACA,4C;;AAEA,mC;AACA,0D;AACA,mD;AACA,mB;AACA,S;AACA,2D;AACA,gF;AACA,gE;AACA,0E;AACA,K;AACA,oC;;AAEA,4B;AACA,mD;AACA,mB;AACA,E;;AAEA,+C;AACA,oB;AACA,gC;AACA,kB;AACA,a;AACA,6B;AACA,c;AACA,a;AACA,wD;AACA,8C;AACA,8C;AACA,S;AACA,c;AACA,a;AACA,0D;AACA,uC;AACA,c;AACA,a;AACA,wD;AACA,+C;AACA,c;AACA,a;AACA,kC;AACA,c;AACA,K;AACA,E;;AAEA,6D;AACA,oB;AACA,wB;AACA,wE;AACA,6B;AACA,K;AACA,+B;AACA,2C;AACA,oC;AACA,K;;AAEA,c;AACA,+D;AACA,wB;AACA,yB;AACA,S;AACA,mE;AACA,sB;AACA,+B;AACA,kD;AACA,+B;AACA,yD;AACA,yD;AACA,8C;AACA,+C;AACA,iD;AACA,0C;AACA,e;AACA,wB;AACA,S;;AAEA,gC;AACA,yD;AACA,yD;AACA,gB;AACA,8D;AACA,qE;AACA,+D;AACA,4D;AACA,mE;AACA,gE;AACA,8D;AACA,gE;AACA,iB;AACA,e;;AAEA,gD;AACA,+E;AACA,0E;AACA,mD;AACA,mE;AACA,mE;AACA,wB;AACA,S;AACA,K;AACA,E;;AAEA,iD;AACA,oB;AACA,yC;AACA,8C;AACA,+C;AACA,yC;AACA,qB;AACA,K;AACA,qC;AACA,6D;AACA,gB;AACA,E;;AAEA,wC;AACA,oB;AACA,8C;AACA,6C;AACA,0C;AACA,uD;AACA,K;AACA,gB;AACA,E;;AAEA,wE;AACA,oB;AACA,8B;AACA,4B;AACA,4C;AACA,uD;AACA,gF;AACA,kD;AACA,sB;AACA,iB;AACA,qE;AACA,kB;AACA,wC;AACA,+E;AACA,W;AACA,oD;AACA,uD;AACA,2D;AACA,oD;AACA,yC;AACA,4C;AACA,K;AACA,Y;AACA,E;AACA,mC;;;AAGA,+C;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,qE;AACA,oB;AACA,uC;AACA,sC;AACA,mC;AACA,Y;AACA,kC;AACA,K;AACA,iB;AACA,mB;AACA,gE;;AAEA,wC;AACA,qC;AACA,oC;AACA,M;AACA,mE;AACA,4D;AACA,kE;AACA,oD;AACA,wD;AACA,0D;AACA,oE;AACA,kC;AACA,mF;AACA,M;AACA,E;;AAEA,sD;AACA,mC;AACA,E;;AAEA,qD;AACA,oB;AACA,qB;AACA,a;AACA,yC;AACA,mB;AACA,0C;AACA,mD;AACA,K;AACA,E;;AAEA,yC;AACA,yD;AACA,E;;AAEA,oE;AACA,mE;AACA,8D;AACA,oB;AACA,kC;AACA,4C;;;AAGA,4C;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,mC;AACA,8D;AACA,oB;AACA,0B;AACA,yB;AACA,E;AACA,qD;AACA,oB;AACA,mC;AACA,0B;AACA,6B;AACA,K;AACA,E;;AAEA,sE;AACA,mE;AACA,mE;AACA,sE;AACA,iE;AACA,mE;AACA,mE;AACA,2B;AACA,0D;AACA,oB;AACA,a;AACA,iC;AACA,8B;AACA,2B;AACA,M;AACA,uC;AACA,8B;AACA,6B;AACA,O;AACA,E;;AAEA,qD;AACA,oB;AACA,sC;AACA,6D;AACA,+F;AACA,kC;AACA,oC;AACA,yE;AACA,oB;AACA,0C;AACA,a;AACA,W;AACA,8B;AACA,K;AACA,E;;AAEA,uD;AACA,oB;AACA,0B;AACA,0B;AACA,K;AACA,2B;AACA,E;;AAEA,2D;AACA,oB;;AAEA,kC;AACA,qE;AACA,yE;AACA,wB;AACA,oC;AACA,yC;AACA,6B;AACA,2D;AACA,qC;AACA,+B;AACA,yC;AACA,K;AACA,+B;AACA,+B;AACA,0C;AACA,qB;AACA,8C;;AAEA,e;AACA,S;AACA,8E;AACA,qE;AACA,gB;AACA,mD;AACA,yB;AACA,K;AACA,mB;AACA,6B;AACA,kC;;AAEA,S;AACA,6B;AACA,gB;AACA,6E;AACA,K;AACA,kB;;AAEA,iC;AACA,oC;AACA,0E;AACA,kD;AACA,0C;AACA,qC;AACA,6D;AACA,qC;AACA,sB;AACA,wB;AACA,kE;AACA,qC;AACA,uB;AACA,M;AACA,+C;AACA,6C;AACA,yD;AACA,M;AACA,qB;AACA,E;;AAEA,6C;AACA,6C;AACA,oE;AACA,8C;AACA,sD;AACA,8C;AACA,U;AACA,uC;AACA,0C;AACA,U;AACA,M;AACA,E;AACA,yC;;;AAGA,oD;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,gC;AACA,mG;AACA,oB;AACA,qF;AACA,oD;AACA,a;AACA,mD;AACA,kD;AACA,wC;AACA,sB;AACA,oD;AACA,2B;AACA,S;AACA,qB;AACA,+B;AACA,sE;AACA,0B;AACA,kD;AACA,wD;AACA,sD;AACA,0B;AACA,4B;AACA,4B;AACA,S;AACA,M;;AAEA,qE;AACA,4B;AACA,2B;;AAEA,6C;AACA,qB;AACA,oC;AACA,6B;AACA,kC;AACA,2B;AACA,yC;AACA,iD;AACA,mC;AACA,kD;AACA,6B;AACA,qE;AACA,iB;AACA,qB;AACA,S;AACA,M;AACA,iC;AACA,wF;AACA,M;;AAEA,6C;AACA,sD;AACA,6D;AACA,mC;AACA,qB;AACA,0D;AACA,qC;AACA,8B;AACA,a;AACA,yB;AACA,4G;AACA,a;AACA,S;AACA,M;AACA,uC;AACA,yE;AACA,iE;AACA,iE;AACA,sE;AACA,kE;AACA,8B;AACA,8E;AACA,gD;AACA,mE;AACA,uE;AACA,8E;AACA,gE;AACA,+D;AACA,kD;AACA,yC;AACA,iB;AACA,2C;AACA,yC;AACA,0B;AACA,gC;AACA,gB;AACA,6C;AACA,wD;AACA,iH;AACA,iD;AACA,S;AACA,K;AACA,8C;AACA,4B;AACA,K;;AAEA,gF;AACA,kC;AACA,2G;AACA,gC;;AAEA,yD;AACA,+C;AACA,kB;AACA,oD;AACA,K;AACA,wB;AACA,E;AACA,iD;;;AAGA,mD;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,oE;AACA,iE;AACA,wE;AACA,c;AACA,qB;AACA,qC;AACA,4D;;;AAGA,wE;AACA,mC;AACA,oB;AACA,iB;AACA,+B;AACA,8C;AACA,0B;AACA,E;;AAEA,c;AACA,gD;;AAEA,sD;AACA,oB;AACA,mC;AACA,+B;AACA,mB;AACA,mC;AACA,oC;AACA,0C;AACA,a;AACA,S;AACA,2E;AACA,gC;AACA,kC;AACA,S;AACA,M;AACA,qE;AACA,2E;AACA,E;;AAEA,qC;AACA,gB;AACA,E;;AAEA,gC;;;AAGA,iD;AACA,oB;AACA,4B;AACA,0B;AACA,0B;AACA,K;AACA,qC;AACA,2B;AACA,E;;;AAGA,8D;AACA,4E;AACA,0C;AACA,0D;;AAEA,+D;AACA,2D;AACA,qB;;AAEA,4C;AACA,oC;AACA,0B;AACA,e;AACA,iE;AACA,wC;AACA,iC;AACA,kB;AACA,e;AACA,6D;AACA,iC;AACA,yB;AACA,kB;AACA,e;AACA,8E;AACA,wC;AACA,kB;AACA,S;AACA,M;;AAEA,2D;AACA,wC;AACA,2B;AACA,mC;AACA,yB;AACA,oF;AACA,S;AACA,M;AACA,gB;AACA,E;AACA,gD;;;AAGA,yC;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,uC;AACA,oD;;AAEA,0D;AACA,+E;AACA,oB;AACA,iB;AACA,+B;AACA,wD;AACA,yC;AACA,gE;AACA,E;;AAEA,qD;AACA,oB;AACA,oB;AACA,0B;AACA,yB;AACA,K;AACA,E;;AAEA,gB;AACA,+E;AACA,gF;AACA,E;;AAEA,2D;;AAEA,4C;AACA,gE;AACA,4B;AACA,qC;AACA,wD;AACA,mD;AACA,E;AACA,wD;;AAEA,gE;AACA,sE;AACA,uC;;;AAGA,gB;AACA,uG;AACA,0E;;;AAGA,gB;AACA,+E;AACA,4E;AACA,E;;AAEA,2D;;AAEA,4C;AACA,oC;AACA,E;AACA,wD;;;;AAIA,c;AACA,2E;AACA,sE;AACA,E;;AAEA,yD;;AAEA,4D;AACA,sD;;;AAGA,c;AACA,2E;AACA,kE;AACA,E;;AAEA,yD;;AAEA,4D;AACA,sD;AACA,sC;;;AAGA,4C;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,qE;AACA,iE;AACA,qE;AACA,qE;AACA,wD;AACA,oE;AACA,uD;;AAEA,oC;;AAEA,6E;AACA,oB;AACA,iB;AACA,4C;AACA,6B;AACA,+B;;AAEA,+C;AACA,iC;AACA,0C;AACA,K;AACA,4C;AACA,uC;;AAEA,iE;AACA,4G;AACA,2C;;AAEA,yD;AACA,2C;AACA,E;;AAEA,kD;AACA,oB;AACA,yB;AACA,+C;AACA,a;AACA,oE;AACA,kC;AACA,sD;AACA,sC;AACA,a;AACA,sB;AACA,iC;AACA,8B;AACA,kD;AACA,K;AACA,E;;AAEA,mD;AACA,oB;AACA,yC;AACA,uC;AACA,kC;AACA,+B;;AAEA,6C;;AAEA,kB;AACA,a;AACA,gC;AACA,8G;AACA,c;AACA,a;AACA,kC;AACA,c;AACA,K;AACA,E;;AAEA,8D;AACA,oB;AACA,2E;AACA,E;;AAEA,uD;AACA,mC;AACA,E;;AAEA,sC;AACA,kF;AACA,iC;AACA,wG;AACA,yD;AACA,sE;AACA,E;AACA,yC;;;AAGA,mD;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,mB;;AAEA,yC;AACA,4B;AACA,sE;AACA,Y;AACA,sE;AACA,K;AACA,E;;AAEA,6B;AACA,wD;AACA,qD;AACA,E;AACA,mD;AACA,4B;AACA,E;AACA,8C;AACA,iC;AACA,E;AACA,6C;AACA,gC;AACA,E;;AAEA,gC;;AAEA,sC;AACA,e;AACA,sD;AACA,iC;AACA,uC;AACA,sD;AACA,2C;AACA,qD;;AAEA,2C;AACA,sC;AACA,mC;AACA,iD;AACA,sB;AACA,iB;AACA,qC;AACA,+B;AACA,gC;AACA,iC;AACA,gC;AACA,6C;AACA,mE;AACA,+D;AACA,0D;AACA,a;AACA,wE;AACA,qE;AACA,uB;AACA,a;;AAEA,oD;AACA,mD;AACA,+E;AACA,sG;AACA,+B;AACA,uB;AACA,a;AACA,oC;AACA,oF;AACA,kB;AACA,iB;AACA,iC;AACA,kB;AACA,iB;AACA,uB;AACA,oC;AACA,0B;AACA,kB;AACA,S;AACA,M;;AAEA,4B;AACA,+B;AACA,+G;;AAEA,mC;;AAEA,Y;AACA,qB;AACA,E;AACA,gD;;;AAGA,oC;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,mD;AACA,oB;AACA,+D;AACA,E;;AAEA,sD;;AAEA,+D;AACA,oB;AACA,oC;;AAEA,W;AACA,qD;AACA,wD;;AAEA,4B;AACA,uE;AACA,mE;AACA,gC;AACA,8D;AACA,Y;;AAEA,gC;AACA,wD;;AAEA,0C;AACA,2B;AACA,oB;AACA,6B;AACA,kD;AACA,wC;AACA,oD;AACA,2C;AACA,gB;AACA,gC;AACA,S;AACA,M;AACA,+B;AACA,mB;AACA,4B;AACA,M;AACA,E;;AAEA,6C;AACA,oB;AACA,yB;AACA,wC;AACA,gD;AACA,+B;AACA,iE;AACA,gD;AACA,4C;AACA,+C;AACA,oB;AACA,oC;AACA,a;AACA,4B;AACA,uB;AACA,U;AACA,uB;AACA,yB;AACA,2B;AACA,4B;AACA,U;AACA,uD;AACA,K;AACA,yB;AACA,sC;AACA,Y;AACA,a;AACA,K;AACA,E;AACA,4D;;;AAGA,mC;AACA,qE;AACA,oE;AACA,+C;AACA,oB;AACA,4B;AACA,sC;AACA,O;AACA,E;AACA,0D;;AAEA,6C;AACA,0C;AACA,mE;AACA,iE;AACA,gE;AACA,K;AACA,uC;AACA,W;AACA,gD;AACA,gE;AACA,W;AACA,W;AACA,oD;AACA,oD;AACA,8H;AACA,+C;AACA,+D;AACA,Y;AACA,0C;AACA,Y;AACA,W;AACA,gB;AACA,gD;AACA,Y;AACA,e;AACA,sC;AACA,M;AACA,E;;;AAGA,mG;AACA,8D;AACA,uC;AACA,wD;AACA,uB;AACA,K;AACA,E;AACA,wD;AACA,iC;;;AAGA,wD;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,6E;AACA,oB;AACA,2C;AACA,8C;AACA,E;;AAEA,6D;;AAEA,kD;AACA,mE;AACA,E;;AAEA,4C;AACA,2E;;;AAGA,uB;AACA,uF;AACA,uF;AACA,C;AACA,0D;AACA,qD;;;AAGA,wD;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,4E;AACA,oB;AACA,2C;AACA,8C;AACA,E;;AAEA,4D;;AAEA,iD;AACA,+D;AACA,E;;AAEA,2C;AACA,kE;;;AAGA,uB;AACA,uF;AACA,uE;AACA,E;;AAEA,0D;AACA,qD;;;AAGA,qD;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,kE;AACA,0D;AACA,+D;AACA,0C;;AAEA,uE;AACA,oB;AACA,wC;AACA,8C;AACA,E;;AAEA,e;AACA,0D;;AAEA,8C;AACA,qC;AACA,E;;AAEA,yC;AACA,qE;;;AAGA,oB;AACA,iF;AACA,iF;AACA,E;AACA,uD;AACA,kD;;;AAGA,6C;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,4D;AACA,oB;AACA,iB;AACA,6B;AACA,6B;AACA,iC;AACA,yB;AACA,E;;AAEA,8C;AACA,oB;AACA,6E;AACA,wB;AACA,kC;AACA,yB;AACA,oC;AACA,M;AACA,gC;AACA,gE;AACA,oC;AACA,2C;AACA,4E;AACA,oB;AACA,qC;AACA,a;AACA,S;AACA,M;AACA,E;;AAEA,sC;AACA,oB;AACA,gC;AACA,oB;AACA,0B;AACA,K;AACA,E;AACA,0C;;;AAGA,0D;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,yC;AACA,oB;AACA,kC;AACA,gC;AACA,qD;AACA,wE;AACA,M;AACA,4D;AACA,sD;AACA,2C;AACA,4C;AACA,4D;AACA,yD;AACA,gD;AACA,mB;AACA,kB;AACA,iE;AACA,uC;AACA,sE;AACA,qC;AACA,uF;AACA,uB;AACA,M;AACA,E;;AAEA,mD;;AAEA,kD;AACA,oB;AACA,wB;AACA,gC;AACA,K;AACA,E;AACA,uD;;;AAGA,uD;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,4B;AACA,sC;AACA,gD;AACA,yC;AACA,iB;AACA,0E;AACA,0B;AACA,gB;AACA,4C;AACA,S;AACA,K;AACA,mC;AACA,E;;;AAGA,sC;AACA,oB;AACA,mC;;AAEA,+C;AACA,oD;AACA,+C;;AAEA,6C;AACA,kD;;AAEA,kB;AACA,iC;AACA,4B;AACA,+B;AACA,U;AACA,kC;AACA,2E;AACA,U;AACA,2B;AACA,6C;AACA,S;AACA,M;AACA,mD;AACA,4B;AACA,6C;AACA,yC;AACA,6E;AACA,M;AACA,8C;AACA,mE;AACA,+B;AACA,E;;AAEA,gD;;AAEA,+C;AACA,oB;AACA,4B;AACA,sC;AACA,K;AACA,E;AACA,oD;;;AAGA,kD;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,6C;AACA,oB;AACA,oB;;AAEA,gD;AACA,8C;AACA,mC;AACA,mB;AACA,0C;AACA,sC;AACA,gC;AACA,2B;AACA,sC;AACA,wE;AACA,S;AACA,M;AACA,+C;AACA,sC;AACA,uB;AACA,8D;AACA,uE;AACA,K;AACA,E;;AAEA,2C;;AAEA,0C;AACA,oB;AACA,kB;AACA,wB;AACA,uE;AACA,uB;AACA,K;AACA,E;AACA,+C;;;AAGA,0C;AACA,E;AACA,kC;AACA,uC;AACA,E;AACA,+B;AACA,gC;AACA,G;;AAEA,c;AACA,6B;AACA,iB;AACA,E;;AAEA,uC;AACA,2B;AACA,E;AACA,uC;;AAEA,gC;AACA,e;AACA,8D;;AAEA,iB;AACA,iD;AACA,qD;AACA,C;AACA,8B;;AAEA,wB;;;;;;;;;;;;;;;;;;;ACz5EA,wC;AACA,6C;AACA,4C;AACA,qD;AACA,kB;AACA,2B;AACA,e;AACA,c;AACA,iC;;AAEA,gB;;;AAGA,wE;AACA,sE;AACA,I;AACA,uE;AACA,oE;AACA,qE;AACA,oE;AACA,wE;AACA,mB;AACA,oC;;AAEA,oB;AACA,qB;;AAEA,6B;;AAEA,oE;AACA,4C;AACA,+D;AACA,iE;AACA,uE;;AAEA,e;AACA,2B;AACA,E;;AAEA,+C;;AAEA,uE;AACA,oE;AACA,wB;AACA,yB;AACA,oB;AACA,uC;AACA,6B;AACA,K;AACA,I;;AAEA,yC;AACA,8B;AACA,oB;AACA,sB;AACA,I;;AAEA,2B;AACA,oB;;AAEA,+B;AACA,yC;AACA,kC;AACA,K;;AAEA,uC;AACA,uE;AACA,a;AACA,K;;AAEA,oB;AACA,4C;AACA,wC;AACA,sC;AACA,yB;;AAEA,sE;AACA,kD;AACA,2E;;AAEA,I;;AAEA,mC;AACA,oB;;AAEA,8C;AACA,sB;AACA,iD;AACA,yE;AACA,0B;AACA,yB;AACA,K;;AAEA,gE;AACA,2B;AACA,O;AACA,I;;AAEA,mD;AACA,oB;AACA,+B;AACA,yC;AACA,kC;AACA,K;AACA,8B;AACA,wC;AACA,iC;AACA,K;AACA,I;;AAEA,mC;AACA,oB;AACA,uE;AACA,yE;AACA,I;;AAEA,oC;AACA,oB;AACA,yE;AACA,0D;AACA,iC;AACA,a;AACA,4B;AACA,wC;AACA,qC;AACA,4C;AACA,8B;AACA,I;;AAEA,0C;AACA,6D;AACA,yB;AACA,8B;AACA,2E;;AAEA,qE;AACA,wD;AACA,+E;AACA,M;AACA,mE;AACA,oC;AACA,mC;AACA,yD;AACA,kD;;AAEA,sB;AACA,oE;;AAEA,8B;AACA,I;;AAEA,kC;AACA,oB;AACA,iE;;AAEA,4B;AACA,0D;AACA,oC;;AAEA,+E;AACA,sE;AACA,yB;AACA,2E;AACA,0C;AACA,wB;AACA,M;AACA,6C;AACA,iC;;AAEA,uC;AACA,iE;AACA,8B;AACA,W;AACA,M;AACA,uC;AACA,6B;AACA,M;AACA,uC;AACA,iC;AACA,uF;AACA,M;;AAEA,4C;AACA,iC;AACA,M;;AAEA,6B;AACA,yC;AACA,mD;AACA,2B;AACA,6D;AACA,6B;AACA,G;AACA,G;;;;;;;;;;;;;;;;;;;ACjMA,0E;AACA,wC;AACA,uC;AACA,+C;AACA,E;AACA,oC;AACA,qC;AACA,qD;AACA,E;;AAEA,6C;AACA,6D;AACA,sD;AACA,mF;AACA,yC;AACA,sD;AACA,iD;AACA,2D;AACA,wB;AACA,2B;AACA,G;;AAEA,uD;AACA,iD;AACA,gB;AACA,oB;AACA,4C;AACA,wD;AACA,6E;AACA,4C;AACA,c;AACA,0E;AACA,mE;;AAEA,0E;AACA,4E;AACA,wD;AACA,4C;AACA,8C;AACA,O;;AAEA,2C;AACA,4B;AACA,uE;AACA,0D;AACA,2C;AACA,G;;AAEA,uC;AACA,2D;AACA,sC;AACA,G;;AAEA,8D;AACA,sE;AACA,kE;AACA,sE;AACA,+B;AACA,I;AACA,kE;AACA,sE;AACA,iE;AACA,uE;AACA,2C;;AAEA,yB;AACA,yB;AACA,M;AACA,+B;AACA,E;;AAEA,8B;AACA,6C;AACA,E;;AAEA,iC;AACA,iD;AACA,a;AACA,E;;AAEA,uC;;;AAGA,+C;;AAEA,4B;AACA,iC;AACA,oB;;AAEA,wE;AACA,qD;;AAEA,mC;AACA,qC;AACA,6C;AACA,I;;;AAGA,mC;AACA,oB;AACA,4B;;AAEA,kB;;AAEA,+D;AACA,c;AACA,6D;;AAEA,mD;;AAEA,qC;;AAEA,wB;AACA,0B;AACA,2B;AACA,uB;AACA,mB;AACA,M;;;AAGA,oF;AACA,sC;AACA,+B;AACA,uC;AACA,M;;AAEA,oB;AACA,4B;AACA,gC;;AAEA,I;;AAEA,yB;AACA,iC;AACA,oB;AACA,4B;;AAEA,sB;AACA,mC;AACA,K;;AAEA,iC;AACA,2D;AACA,K;;AAEA,uC;AACA,0C;AACA,2B;AACA,2D;AACA,sB;AACA,a;AACA,K;;AAEA,wC;AACA,qD;AACA,oC;AACA,6B;AACA,K;;AAEA,wB;AACA,qE;AACA,qB;AACA,I;;AAEA,kC;AACA,oB;AACA,4B;;AAEA,qE;AACA,uD;AACA,iC;AACA,a;;AAEA,2E;AACA,mE;AACA,mE;AACA,6B;AACA,6B;AACA,sC;AACA,K;;AAEA,oB;AACA,wB;;AAEA,0B;AACA,0D;AACA,uB;AACA,mB;AACA,M;;AAEA,6C;AACA,iD;;AAEA,yB;AACA,I;;AAEA,gE;AACA,0C;AACA,oB;;AAEA,8B;AACA,wE;AACA,I;;AAEA,kE;AACA,iB;AACA,wB;AACA,0E;AACA,+C;AACA,uB;AACA,I;;AAEA,sC;AACA,oB;;AAEA,oB;AACA,6B;AACA,8E;AACA,uC;AACA,sC;AACA,oC;AACA,Q;AACA,4C;AACA,sE;AACA,Y;AACA,2C;AACA,0C;AACA,K;;AAEA,yC;AACA,yB;AACA,I;;AAEA,0B;AACA,oB;;AAEA,iC;AACA,a;;AAEA,uC;AACA,6C;AACA,yC;AACA,wC;AACA,yB;;AAEA,6B;AACA,I;;;AAGA,kC;AACA,uB;AACA,oB;AACA,6B;AACA,oC;AACA,8B;AACA,G;AACA,G;;AAEA,2C;AACA,6C;AACA,oB;AACA,2B;AACA,G;;AAEA,gD;AACA,8C;;;;;;;;;;;;;;;;;;;ACzQA,qB;AACA,gE;AACA,uE;AACA,iC;AACA,iE;AACA,yD;;AAEA,gC;AACA,kB;;AAEA,qD;AACA,mD;AACA,oC;AACA,sC;;AAEA,uC;AACA,sC;AACA,E;;AAEA,+B;AACA,qB;AACA,oB;AACA,wC;AACA,uC;AACA,I;;AAEA,sB;AACA,oB;AACA,gB;AACA,wC;AACA,I;;AAEA,6C;AACA,oB;AACA,sD;AACA,iD;AACA,4B;AACA,M;AACA,I;;AAEA,4C;AACA,oB;AACA,qD;AACA,gD;AACA,2B;AACA,M;AACA,I;;AAEA,6C;AACA,oB;AACA,wC;AACA,yD;AACA,2C;AACA,K;AACA,I;;AAEA,4C;AACA,oB;AACA,uC;AACA,wD;AACA,0C;AACA,K;AACA,I;;AAEA,sE;AACA,wC;AACA,oB;AACA,yC;AACA,qB;AACA,uB;AACA,uC;AACA,I;;AAEA,qE;AACA,oC;AACA,uC;AACA,oB;AACA,wC;AACA,sB;AACA,I;;AAEA,6B;AACA,oB;AACA,kE;AACA,sE;AACA,wC;AACA,0C;AACA,0C;AACA,K;AACA,I;;AAEA,6B;AACA,oB;;AAEA,oE;AACA,0C;AACA,uC;AACA,yC;AACA,0C;AACA,K;AACA,G;AACA,G;;;;;;;;;;;;;;;;;;;ACrGA,8D;AACA,2D;AACA,iD;;AAEA,6D;;AAEA,2E;AACA,oB;AACA,G;AACA,6E;AACA,8B;AACA,0B;AACA,qB;AACA,G;AACA,uC;AACA,kB;;AAEA,sE;AACA,qE;AACA,iE;AACA,gE;AACA,wE;AACA,sE;AACA,yC;;AAEA,K;AACA,mG;AACA,oB;AACA,wB;AACA,+B;AACA,c;AACA,oB;AACA,K;AACA,2C;;AAEA,mE;AACA,qE;AACA,c;AACA,oD;AACA,8B;;AAEA,oB;;AAEA,K;AACA,gG;AACA,oB;AACA,kB;AACA,+B;AACA,c;AACA,K;AACA,+B;;AAEA,gE;AACA,yB;AACA,wD;;AAEA,+D;;AAEA,K;AACA,uN;AACA,kB;AACA,sB;AACA,+B;AACA,c;AACA,K;AACA,uC;;AAEA,+C;AACA,uC;;AAEA,uE;AACA,2B;AACA,E;;AAEA,sC;AACA,K;AACA,yH;AACA,kB;AACA,+B;AACA,c;AACA,K;AACA,wB;AACA,oB;AACA,+B;AACA,oB;AACA,I;;AAEA,K;AACA,qC;AACA,kB;AACA,+B;AACA,c;AACA,oG;AACA,K;AACA,+B;AACA,oB;AACA,4B;AACA,gF;AACA,yB;AACA,4B;AACA,G;AACA,G;;AAEA,qC;AACA,O;AACA,wC;AACA,e;AACA,yE;AACA,gB;AACA,G;AACA,kC;AACA,gD;AACA,sE;AACA,gB;AACA,G;;AAEA,6E;;AAEA,qE;AACA,gB;AACA,8B;AACA,8B;AACA,sB;AACA,6C;AACA,uC;AACA,O;AACA,uB;AACA,G;;AAEA,2D;AACA,0B;AACA,+D;AACA,K;;AAEA,a;AACA,E;;AAEA,+B;AACA,8B;AACA,sE;AACA,qB;AACA,6B;AACA,qB;AACA,8C;AACA,gC;AACA,0B;AACA,gC;AACA,O;AACA,O;AACA,4B;AACA,6B;AACA,+B;AACA,yB;AACA,G;AACA,0B;AACA,2D;AACA,2B;AACA,+D;AACA,K;AACA,6C;AACA,kD;AACA,G;AACA,8B;AACA,E;;AAEA,oE;AACA,qE;AACA,gE;AACA,wD;AACA,wD;;;;;;;;;;;;;;;;;;;ACzKA,2E;AACA,E;AACA,4E;AACA,6E;AACA,mE;AACA,E;AACA,4E;AACA,+E;AACA,0E;AACA,+E;AACA,4E;AACA,6E;AACA,E;AACA,+D;AACA,6D;AACA,gE;AACA,8C;AACA,E;AACA,mC;AACA,4D;AACA,2D;AACA,iF;AACA,gF;AACA,mC;AACA,kB;;AAEA,uD;;AAEA,sB;AACA,E;;AAEA,kE;AACA,gE;AACA,wE;AACA,yC;AACA,wB;AACA,8B;AACA,E;;AAEA,6E;AACA,6E;AACA,oE;AACA,mC;AACA,wE;AACA,6E;AACA,0D;AACA,2C;AACA,c;AACA,qB;AACA,G;AACA,e;AACA,oC;AACA,mD;AACA,kB;AACA,G;AACA,wC;AACA,sB;AACA,0D;AACA,4B;AACA,O;AACA,G;AACA,sC;AACA,E;;AAEA,sD;AACA,6E;AACA,+D;AACA,oC;AACA,2C;AACA,uC;AACA,E;;AAEA,qD;AACA,8C;AACA,yD;AACA,uE;AACA,oD;AACA,yE;AACA,gD;AACA,iE;AACA,8B;AACA,E;;AAEA,kC;AACA,kF;AACA,uE;AACA,qE;AACA,8B;AACA,oB;;AAEA,gD;AACA,4B;AACA,gD;AACA,qD;AACA,4C;AACA,8C;AACA,S;AACA,O;AACA,yF;AACA,K;AACA,oB;AACA,G;AACA,G;;;;;;;;;;;;;;;;;;;ACtGA,sB;AACA,iC;AACA,oC;AACA,0D;AACA,C;;AAEA,gD;AACA,2C;AACA,W;AACA,gF;AACA,qE;AACA,gC;AACA,2E;AACA,6E;AACA,E;AACA,qE;AACA,oC;AACA,E;AACA,oE;AACA,iE;AACA,qE;AACA,8D;AACA,8D;AACA,mE;AACA,oE;AACA,+B;AACA,0C;AACA,kB;AACA,sB;AACA,gC;AACA,4D;AACA,iC;AACA,M;AACA,6B;AACA,4B;AACA,0C;AACA,iC;AACA,iD;AACA,gB;AACA,wB;AACA,c;;AAEA,wE;AACA,gF;AACA,gB;AACA,0B;;AAEA,6D;AACA,gC;AACA,uB;AACA,U;AACA,uD;AACA,2B;AACA,+B;AACA,6C;AACA,mE;AACA,oE;AACA,kE;AACA,gE;AACA,gB;AACA,iD;AACA,gD;AACA,O;AACA,G;;AAEA,6B;AACA,oE;AACA,4E;AACA,mD;AACA,4C;AACA,yB;AACA,4D;;AAEA,sD;AACA,oD;;AAEA,2E;AACA,gF;AACA,6E;AACA,0B;AACA,4B;;AAEA,gF;AACA,iB;AACA,I;AACA,0E;AACA,+E;AACA,4E;AACA,+E;AACA,mB;AACA,I;AACA,uD;AACA,+C;AACA,4E;AACA,8B;AACA,I;AACA,gF;AACA,+D;AACA,I;AACA,oE;AACA,+E;AACA,+E;AACA,gF;AACA,6E;AACA,+C;AACA,I;AACA,a;AACA,kC;AACA,mC;AACA,6D;AACA,0D;AACA,4D;AACA,8E;AACA,uE;AACA,6E;AACA,+E;AACA,+E;AACA,0D;AACA,qC;;AAEA,2E;AACA,yE;AACA,gF;AACA,+B;AACA,oC;AACA,8E;AACA,4D;AACA,8E;AACA,gC;AACA,8D;AACA,8E;AACA,6D;AACA,6B;;AAEA,uE;AACA,qB;AACA,uE;AACA,qC;AACA,yE;AACA,gF;AACA,4E;AACA,gB;AACA,kC;;AAEA,gF;AACA,oC;AACA,8E;AACA,8E;AACA,6D;AACA,6E;AACA,gF;AACA,uE;AACA,mD;AACA,I;AACA,iE;;AAEA,+D;AACA,6C;AACA,yE;AACA,yE;AACA,W;AACA,uC;AACA,yE;AACA,wE;AACA,0D;AACA,uE;AACA,gB;AACA,4B;;AAEA,iE;AACA,qC;AACA,kD;AACA,4B;;AAEA,sE;AACA,W;AACA,a;AACA,e;AACA,uE;AACA,uD;AACA,gE;AACA,+E;AACA,0D;AACA,2E;AACA,+E;AACA,2B;;AAEA,qB;AACA,sB;AACA,4C;;AAEA,gE;AACA,4E;AACA,uD;AACA,oC;AACA,+B;AACA,yD;AACA,mC;AACA,qB;AACA,c;AACA,sB;AACA,O;AACA,O;AACA,G;;AAEA,sC;AACA,S;AACA,kC;AACA,iB;AACA,sD;AACA,a;AACA,K;;AAEA,mC;AACA,uE;AACA,wE;AACA,qC;AACA,mC;AACA,kE;AACA,a;AACA,K;;AAEA,kC;AACA,8C;AACA,oC;AACA,4B;AACA,K;AACA,mC;AACA,gE;AACA,8C;AACA,+C;AACA,c;AACA,yB;AACA,wF;AACA,yE;AACA,4D;AACA,O;AACA,K;AACA,kC;AACA,iC;AACA,8C;AACA,0B;AACA,uC;AACA,K;AACA,kC;AACA,4B;AACA,uC;AACA,O;AACA,K;AACA,qF;AACA,+B;AACA,iC;AACA,gC;AACA,kC;AACA,iC;AACA,iC;AACA,gC;AACA,Q;AACA,qE;AACA,I;;AAEA,6B;AACA,6D;AACA,qE;AACA,2C;AACA,+B;AACA,4B;AACA,wC;AACA,2E;AACA,0C;AACA,6C;AACA,oB;;AAEA,oE;AACA,qE;AACA,oE;AACA,4D;AACA,qE;AACA,kE;AACA,0B;;AAEA,gF;AACA,wD;AACA,qD;AACA,8D;AACA,4C;AACA,K;;AAEA,uE;AACA,kB;AACA,+C;AACA,4B;AACA,O;;AAEA,oE;AACA,oE;AACA,oE;AACA,oE;AACA,oB;AACA,yB;AACA,kE;AACA,Q;AACA,qC;;AAEA,wE;AACA,6C;AACA,oD;AACA,kB;AACA,mB;AACA,e;AACA,uB;AACA,0B;AACA,S;AACA,O;AACA,I;;AAEA,kC;AACA,0B;AACA,6B;AACA,6B;AACA,K;AACA,I;;AAEA,wB;AACA,iF;AACA,6E;AACA,uF;AACA,U;AACA,0C;AACA,sC;AACA,gD;AACA,G;AACA,E;;AAEA,gF;AACA,sE;AACA,+E;AACA,2E;AACA,+C;AACA,wC;AACA,kB;;AAEA,sC;AACA,mC;AACA,2B;;AAEA,oC;AACA,wC;AACA,kC;AACA,sE;AACA,4B;AACA,4B;AACA,4B;;AAEA,kC;AACA,yD;AACA,E;AACA,mC;AACA,8E;AACA,oE;AACA,4B;AACA,oB;AACA,8E;AACA,gF;AACA,c;AACA,yB;AACA,uE;;AAEA,8E;AACA,Y;AACA,8B;;AAEA,4B;;AAEA,+E;AACA,Y;AACA,mB;AACA,wE;;AAEA,iC;AACA,0C;AACA,I;AACA,6E;AACA,qC;AACA,qC;AACA,oB;AACA,kD;AACA,4E;AACA,0B;AACA,mE;;AAEA,kC;AACA,6D;;AAEA,+E;AACA,8C;AACA,oD;AACA,K;AACA,I;AACA,2E;AACA,oE;AACA,4E;AACA,2D;AACA,yC;AACA,oB;AACA,yB;AACA,kE;AACA,uC;AACA,wC;AACA,gC;AACA,I;AACA,8E;AACA,uE;AACA,4E;AACA,sE;AACA,4B;AACA,oB;AACA,6B;AACA,gC;AACA,I;AACA,2C;AACA,0B;AACA,oB;AACA,gC;AACA,G;AACA,G;;AAEA,gC;AACA,qE;AACA,gF;AACA,gF;AACA,gD;AACA,oB;;AAEA,6B;AACA,mB;;AAEA,0E;AACA,2C;AACA,mB;AACA,kE;AACA,qD;AACA,2C;AACA,4C;AACA,6E;AACA,qC;AACA,gB;AACA,e;;AAEA,+B;;AAEA,qD;AACA,iB;AACA,8C;AACA,qC;AACA,0B;AACA,S;AACA,wB;AACA,iD;AACA,K;;AAEA,gB;AACA,I;;AAEA,K;AACA,qB;AACA,wE;AACA,oC;AACA,kB;AACA,4E;AACA,+B;AACA,uE;AACA,wB;AACA,wE;AACA,sE;AACA,2E;AACA,6C;AACA,K;AACA,2E;AACA,oB;;AAEA,0D;AACA,uB;AACA,wB;AACA,gD;AACA,oC;AACA,yC;AACA,6B;AACA,wE;AACA,iD;AACA,uE;AACA,0B;AACA,iC;AACA,O;AACA,K;;AAEA,uE;AACA,uE;AACA,4B;AACA,M;AACA,wC;AACA,M;AACA,wC;AACA,yD;AACA,yD;AACA,c;AACA,M;AACA,sE;AACA,oE;AACA,sD;AACA,M;AACA,8E;AACA,4E;AACA,uB;AACA,+D;AACA,iD;AACA,yC;AACA,O;;AAEA,W;AACA,mB;AACA,uB;AACA,8C;;AAEA,8B;AACA,+E;AACA,+E;AACA,6E;AACA,yE;AACA,8C;AACA,4B;AACA,qD;AACA,O;;AAEA,wE;AACA,+C;AACA,8B;AACA,kE;AACA,2B;AACA,mD;AACA,O;;AAEA,6B;AACA,iD;AACA,O;AACA,Y;AACA,oE;AACA,uB;AACA,iC;AACA,e;AACA,mB;AACA,oC;AACA,wB;AACA,qB;AACA,0C;AACA,yC;AACA,iD;AACA,yC;AACA,uC;AACA,yB;AACA,4B;AACA,yD;AACA,iD;AACA,U;AACA,0B;AACA,wD;AACA,wB;;AAEA,iC;AACA,+B;AACA,W;AACA,S;AACA,Q;AACA,mE;AACA,K;;AAEA,0C;AACA,kB;AACA,yB;AACA,4C;AACA,iB;;AAEA,uC;AACA,Q;AACA,0B;AACA,8C;AACA,4C;AACA,uB;AACA,6C;AACA,kC;AACA,4B;AACA,Q;AACA,wB;AACA,M;;AAEA,yB;AACA,8E;AACA,8E;AACA,6E;AACA,uE;AACA,wE;AACA,uB;AACA,yC;AACA,2C;AACA,kD;;AAEA,wC;AACA,+C;AACA,+C;AACA,0B;AACA,W;AACA,S;AACA,K;;AAEA,kB;AACA,I;;AAEA,a;AACA,2F;AACA,mE;AACA,qD;AACA,oB;AACA,yB;AACA,sB;AACA,e;AACA,sB;AACA,e;AACA,4B;AACA,qB;AACA,sB;AACA,Q;AACA,6B;AACA,mB;AACA,wB;AACA,Y;AACA,mE;AACA,O;AACA,O;;AAEA,6D;AACA,a;AACA,kB;AACA,I;;AAEA,+B;AACA,oB;AACA,2C;AACA,qC;AACA,4E;AACA,wC;AACA,O;AACA,I;;AAEA,K;AACA,qB;AACA,+D;AACA,oB;AACA,kD;AACA,gE;AACA,uN;AACA,K;AACA,0D;AACA,oE;AACA,4C;AACA,wD;AACA,mE;AACA,gC;AACA,4C;AACA,I;;AAEA,qC;AACA,4E;AACA,4E;AACA,2D;AACA,+E;AACA,4E;AACA,2E;AACA,2E;AACA,2E;AACA,6E;AACA,6E;AACA,2E;AACA,yE;AACA,4E;AACA,8E;AACA,6E;AACA,6E;AACA,2E;AACA,6D;AACA,wC;;AAEA,K;AACA,qB;AACA,4D;AACA,oB;AACA,kD;AACA,+C;AACA,8B;AACA,wM;AACA,8Q;AACA,6G;AACA,K;AACA,mD;AACA,oB;;AAEA,2E;AACA,gC;AACA,qD;AACA,yB;AACA,mB;AACA,K;AACA,4B;;AAEA,mB;AACA,oE;AACA,oC;AACA,yD;AACA,wC;AACA,iB;AACA,sD;AACA,Q;AACA,K;;AAEA,8E;AACA,uC;AACA,6B;;AAEA,mE;AACA,iC;AACA,a;AACA,0B;AACA,6B;AACA,2C;AACA,kB;AACA,Q;AACA,S;;AAEA,iD;AACA,kE;;AAEA,yE;AACA,8E;AACA,yE;AACA,8D;AACA,+E;AACA,6E;AACA,6E;AACA,wE;AACA,4E;AACA,iD;AACA,0B;AACA,2C;AACA,gC;AACA,kD;AACA,O;AACA,wB;AACA,M;;AAEA,sE;AACA,4E;AACA,0E;AACA,8E;AACA,iD;AACA,M;AACA,yE;AACA,yE;AACA,4E;AACA,wE;AACA,a;;AAEA,0C;AACA,e;AACA,wC;AACA,+B;AACA,Q;;AAEA,6C;AACA,2B;AACA,8B;AACA,6B;AACA,iE;AACA,S;;AAEA,+B;AACA,8B;;AAEA,W;AACA,4E;AACA,8C;AACA,wF;AACA,gC;AACA,4E;AACA,0C;AACA,wD;AACA,4E;AACA,+D;AACA,e;AACA,kB;AACA,6D;AACA,W;AACA,W;AACA,O;AACA,iB;AACA,0B;AACA,O;;AAEA,+B;AACA,oD;AACA,K;;AAEA,oE;AACA,+D;AACA,wC;AACA,8B;AACA,qB;AACA,6C;AACA,yB;AACA,O;AACA,oB;AACA,wB;AACA,6B;AACA,K;;AAEA,gE;AACA,iE;AACA,sD;AACA,M;AACA,oE;AACA,iB;AACA,2C;AACA,2E;AACA,4D;AACA,K;;;AAGA,sE;AACA,iD;;AAEA,+D;AACA,oB;AACA,4B;AACA,sE;AACA,sE;AACA,uE;AACA,0B;AACA,mC;AACA,uE;AACA,4C;AACA,U;AACA,c;AACA,iE;AACA,qC;AACA,gC;AACA,qC;AACA,O;AACA,K;AACA,sE;AACA,yE;AACA,+D;AACA,mB;AACA,oB;AACA,mB;AACA,mB;AACA,oB;AACA,M;;AAEA,6C;AACA,8B;AACA,sC;AACA,K;;AAEA,2C;AACA,2B;AACA,yB;AACA,uB;AACA,iD;AACA,2B;AACA,sB;AACA,O;;AAEA,uB;AACA,gE;AACA,yC;AACA,gD;AACA,Y;AACA,8E;AACA,wD;AACA,qD;AACA,qD;AACA,uE;AACA,wE;AACA,K;;AAEA,0D;AACA,mD;AACA,kC;;AAEA,yD;AACA,oC;AACA,iB;AACA,2B;AACA,K;AACA,iE;AACA,I;;AAEA,gF;AACA,uE;AACA,e;AACA,+B;AACA,oB;AACA,uC;AACA,wB;AACA,O;AACA,I;AACA,8E;AACA,gF;AACA,mE;AACA,mD;AACA,oB;AACA,+C;AACA,0E;;AAEA,yB;AACA,mD;AACA,4C;AACA,gD;AACA,qB;AACA,e;AACA,4C;AACA,2D;AACA,sD;AACA,yE;AACA,6E;AACA,uC;AACA,+E;AACA,2B;AACA,oD;AACA,gB;AACA,mE;AACA,mC;AACA,wC;AACA,wC;AACA,oD;AACA,S;AACA,S;AACA,O;AACA,kC;AACA,2D;AACA,K;AACA,I;;AAEA,kE;AACA,wD;AACA,gC;AACA,oB;AACA,6D;AACA,qE;AACA,sD;AACA,Q;AACA,mE;AACA,mE;AACA,oD;AACA,4D;AACA,uC;AACA,O;AACA,O;AACA,I;;AAEA,8D;AACA,yB;AACA,oB;AACA,yC;AACA,I;;AAEA,6D;AACA,mE;AACA,mC;AACA,qC;AACA,oB;AACA,wC;AACA,I;;AAEA,K;AACA,wE;AACA,kB;AACA,qB;AACA,K;AACA,2C;AACA,oB;AACA,8D;AACA,I;;AAEA,K;AACA,mG;;AAEA,8D;AACA,kB;AACA,qB;AACA,K;AACA,8C;AACA,oB;AACA,iE;AACA,I;;AAEA,K;AACA,oD;AACA,kB;AACA,qB;AACA,K;AACA,+C;AACA,oB;AACA,kE;AACA,I;;AAEA,sB;AACA,oB;AACA,uD;AACA,I;;AAEA,K;AACA,0B;AACA,K;AACA,uB;AACA,oB;AACA,yB;AACA,gC;AACA,wB;AACA,I;;AAEA,gC;AACA,oB;AACA,+E;AACA,gC;AACA,a;AACA,0B;AACA,yB;AACA,iC;AACA,I;;AAEA,gF;AACA,2E;AACA,6B;AACA,sC;AACA,oB;AACA,kD;AACA,0D;AACA,I;;AAEA,6E;AACA,uC;AACA,0C;AACA,oB;AACA,+D;AACA,I;;AAEA,uC;AACA,oB;;AAEA,oE;AACA,uC;AACA,mD;AACA,iD;AACA,gC;AACA,+B;AACA,gE;AACA,U;AACA,+B;AACA,oC;AACA,S;AACA,S;AACA,8B;AACA,K;;AAEA,8D;AACA,4B;AACA,+B;;AAEA,4C;AACA,+E;AACA,wC;AACA,K;;AAEA,uC;AACA,+E;AACA,4E;AACA,gF;AACA,+E;AACA,0E;AACA,a;AACA,K;;AAEA,oE;;AAEA,+E;AACA,mC;AACA,uC;;AAEA,4B;AACA,8E;AACA,gB;AACA,wC;AACA,iC;AACA,K;;AAEA,mC;AACA,oC;;AAEA,8E;AACA,gD;AACA,gF;AACA,qE;AACA,gC;AACA,oD;AACA,oB;AACA,0C;AACA,O;;AAEA,2E;AACA,uE;AACA,uC;AACA,M;AACA,wE;AACA,gF;AACA,4D;AACA,yC;AACA,4B;AACA,uD;AACA,kC;AACA,gF;AACA,0E;AACA,4E;AACA,0E;AACA,gF;AACA,yC;AACA,4E;AACA,8E;AACA,8D;AACA,Y;AACA,6E;AACA,uE;AACA,+E;AACA,2E;AACA,+B;AACA,mE;AACA,S;AACA,S;AACA,K;;AAEA,+C;;AAEA,+E;AACA,sC;AACA,wC;AACA,8B;AACA,2C;AACA,iC;AACA,wB;AACA,W;AACA,kC;AACA,O;AACA,sC;AACA,K;AACA,I;;;AAGA,mD;AACA,oB;AACA,6D;AACA,8C;AACA,I;;;AAGA,kC;AACA,oB;;AAEA,2C;AACA,qB;;AAEA,uC;AACA,sD;;AAEA,8B;AACA,8C;;AAEA,+C;AACA,6C;AACA,S;AACA,qD;AACA,yD;AACA,S;;AAEA,uC;AACA,e;;AAEA,oD;AACA,8E;AACA,oC;AACA,4E;AACA,0D;AACA,S;AACA,iD;AACA,Y;AACA,gD;AACA,K;;AAEA,mD;AACA,oD;AACA,oD;AACA,gF;AACA,yC;AACA,S;AACA,gC;;AAEA,4D;AACA,4C;AACA,oB;AACA,2D;AACA,wC;AACA,a;AACA,gB;AACA,gE;AACA,8B;AACA,oE;AACA,qE;AACA,gD;AACA,+D;AACA,0D;AACA,8E;AACA,qD;AACA,S;AACA,S;;AAEA,gC;AACA,4D;AACA,K;;AAEA,oC;AACA,I;;AAEA,2E;AACA,yE;AACA,+B;AACA,yC;AACA,oB;AACA,+C;AACA,oC;AACA,oC;AACA,U;AACA,O;AACA,I;;AAEA,oD;AACA,oB;AACA,sC;AACA,+B;AACA,K;AACA,kC;AACA,I;;AAEA,4C;AACA,oB;AACA,kD;AACA,kB;AACA,oE;AACA,mD;AACA,I;;AAEA,2C;AACA,oB;AACA,8C;AACA,2D;AACA,oB;AACA,0C;AACA,2C;AACA,sE;AACA,4C;AACA,kC;AACA,Y;AACA,qD;AACA,K;AACA,I;;AAEA,6C;AACA,oB;AACA,uC;AACA,wD;AACA,oB;AACA,2C;AACA,6E;AACA,oE;AACA,Y;AACA,qD;AACA,K;AACA,I;;AAEA,6C;AACA,oB;AACA,uC;AACA,wD;AACA,oB;AACA,0C;AACA,2C;AACA,4E;AACA,qC;AACA,Y;AACA,iD;AACA,uB;AACA,mC;AACA,kB;AACA,S;AACA,K;AACA,I;;AAEA,6C;AACA,oB;AACA,sC;AACA,6C;AACA,yE;AACA,2E;AACA,uB;AACA,2E;AACA,gD;AACA,4D;AACA,iE;AACA,kD;AACA,kD;AACA,6E;AACA,8E;AACA,+E;AACA,wC;;AAEA,yE;AACA,+E;AACA,uE;AACA,yD;AACA,2B;AACA,yD;AACA,uC;AACA,a;AACA,sC;AACA,yD;AACA,gB;AACA,a;;AAEA,2E;AACA,6E;AACA,gE;AACA,uE;AACA,S;AACA,S;AACA,oD;;AAEA,gF;AACA,iD;AACA,2D;AACA,2B;AACA,sE;AACA,2C;AACA,8D;AACA,O;AACA,I;;AAEA,2C;AACA,oB;AACA,2E;AACA,wE;AACA,4D;AACA,uC;AACA,wD;AACA,mD;AACA,sC;AACA,uB;AACA,iB;AACA,0D;AACA,4B;AACA,iB;AACA,6D;AACA,+B;AACA,sC;AACA,S;AACA,O;AACA,I;;AAEA,qE;AACA,gF;AACA,2C;AACA,iD;AACA,oB;AACA,wC;AACA,yC;AACA,M;AACA,oC;AACA,wC;AACA,gC;AACA,0C;AACA,6E;AACA,6B;AACA,2B;AACA,O;AACA,M;AACA,6D;AACA,mD;AACA,2D;AACA,gE;AACA,yD;AACA,kD;AACA,a;AACA,qD;AACA,oC;AACA,0D;AACA,S;AACA,S;AACA,O;AACA,wC;AACA,gF;AACA,qC;AACA,yB;AACA,K;AACA,I;;AAEA,mC;AACA,oB;;AAEA,2E;AACA,0B;AACA,6B;;AAEA,yD;AACA,kC;;AAEA,2D;AACA,4C;AACA,a;;AAEA,6C;AACA,kE;AACA,gE;;AAEA,yC;;AAEA,gD;AACA,wD;AACA,uE;AACA,K;;AAEA,6C;AACA,qC;AACA,6C;AACA,K;;AAEA,uB;AACA,4C;AACA,K;AACA,I;;AAEA,+B;AACA,2E;AACA,4E;AACA,sE;AACA,yE;AACA,e;AACA,I;;AAEA,oC;AACA,mE;;AAEA,oB;;AAEA,mC;AACA,uD;AACA,mD;AACA,yE;AACA,a;AACA,K;AACA,sE;AACA,U;AACA,yD;AACA,gC;AACA,gC;AACA,c;AACA,K;;AAEA,a;AACA,gF;AACA,a;AACA,K;;AAEA,+E;AACA,gF;AACA,kC;AACA,oC;;AAEA,8B;AACA,uC;AACA,0C;AACA,4B;AACA,Y;AACA,kE;AACA,c;AACA,6C;AACA,K;AACA,I;;AAEA,+E;AACA,8E;AACA,mE;AACA,2C;AACA,oB;AACA,yC;AACA,a;;AAEA,2E;AACA,0E;AACA,kD;AACA,qD;AACA,6D;AACA,0C;AACA,uE;AACA,oD;;AAEA,6D;AACA,oD;AACA,uC;AACA,K;;AAEA,oC;AACA,yB;AACA,I;;AAEA,6D;AACA,8B;AACA,uC;AACA,oB;AACA,iD;AACA,a;AACA,mE;AACA,sB;AACA,O;AACA,I;;AAEA,mC;AACA,8D;AACA,6B;AACA,mD;AACA,I;;AAEA,oE;AACA,oB;AACA,mE;AACA,uC;;AAEA,uB;;AAEA,8C;AACA,a;;AAEA,yE;AACA,4E;AACA,+D;AACA,mD;AACA,iE;AACA,qC;AACA,a;AACA,K;;AAEA,gF;AACA,6E;AACA,yC;AACA,sD;AACA,8C;AACA,kE;AACA,8D;;AAEA,0E;AACA,uD;AACA,0B;AACA,S;;AAEA,yC;AACA,K;;AAEA,kD;AACA,yD;AACA,gD;AACA,O;AACA,I;;AAEA,qE;AACA,+B;AACA,oB;AACA,2C;AACA,I;;AAEA,2E;AACA,kE;AACA,8B;AACA,oB;AACA,uD;AACA,2B;AACA,gC;AACA,K;AACA,G;AACA,G;;AAEA,qC;;AAEA,yC;AACA,Y;AACA,8B;AACA,qC;AACA,W;AACA,qD;;AAEA,G;AACA,oI;AACA,kB;AACA,6D;AACA,G;AACA,uC;AACA,yC;AACA,+C;AACA,a;AACA,E;;AAEA,kE;AACA,iC;AACA,E;AACA,oB;AACA,0C;AACA,gD;AACA,sD;AACA,uB;AACA,O;AACA,K;AACA,E;;;;;;;;;;;;;;;;;;;AClmDA,+E;AACA,oC;AACA,0C;AACA,E;;AAEA,sB;AACA,qE;AACA,qB;AACA,I;AACA,oE;AACA,kE;AACA,4C;AACA,+D;AACA,gE;AACA,kE;AACA,kE;AACA,sE;AACA,4D;AACA,sE;AACA,gD;AACA,0D;AACA,mB;AACA,yD;AACA,6D;AACA,oE;AACA,G;;AAEA,0B;;AAEA,+D;AACA,+B;AACA,yB;AACA,iF;AACA,sE;AACA,iB;AACA,gE;AACA,iE;AACA,S;AACA,8C;AACA,wC;AACA,S;AACA,K;AACA,I;;AAEA,qB;AACA,yB;AACA,oE;AACA,O;;AAEA,8D;AACA,kC;AACA,yE;AACA,wB;AACA,0B;AACA,6E;AACA,Y;AACA,Q;AACA,oE;AACA,oC;AACA,2B;AACA,C;;AAEA,sC;AACA,mE;AACA,kC;AACA,wB;AACA,8C;;AAEA,2D;AACA,wB;AACA,6B","file":"/packages/ddp.js","sourcesContent":["/**\n * @namespace DDP\n * @summary The namespace for DDP-related methods.\n */\nDDP = {};\nLivedataTest = {};\n","// XXX METEOR changes in <METEOR>\n\n/* SockJS client, version 0.3.4, http://sockjs.org, MIT License\n\nCopyright (c) 2011-2012 VMware, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n*/\n\n// <METEOR> Commented out JSO implementation (use json package instead).\n// JSON2 by Douglas Crockford (minified).\n// var JSON;JSON||(JSON={}),function(){function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i==\"object\"&&typeof i.toJSON==\"function\"&&(i=i.toJSON(a)),typeof rep==\"function\"&&(i=rep.call(b,a,i));switch(typeof i){case\"string\":return quote(i);case\"number\":return isFinite(i)?String(i):\"null\";case\"boolean\":case\"null\":return String(i);case\"object\":if(!i)return\"null\";gap+=indent,h=[];if(Object.prototype.toString.apply(i)===\"[object Array]\"){f=i.length;for(c=0;c<f;c+=1)h[c]=str(c,i)||\"null\";e=h.length===0?\"[]\":gap?\"[\\n\"+gap+h.join(\",\\n\"+gap)+\"\\n\"+g+\"]\":\"[\"+h.join(\",\")+\"]\",gap=g;return e}if(rep&&typeof rep==\"object\"){f=rep.length;for(c=0;c<f;c+=1)typeof rep[c]==\"string\"&&(d=rep[c],e=str(d,i),e&&h.push(quote(d)+(gap?\": \":\":\")+e))}else for(d in i)Object.prototype.hasOwnProperty.call(i,d)&&(e=str(d,i),e&&h.push(quote(d)+(gap?\": \":\":\")+e));e=h.length===0?\"{}\":gap?\"{\\n\"+gap+h.join(\",\\n\"+gap)+\"\\n\"+g+\"}\":\"{\"+h.join(\",\")+\"}\",gap=g;return e}}function quote(a){escapable.lastIndex=0;return escapable.test(a)?'\"'+a.replace(escapable,function(a){var b=meta[a];return typeof b==\"string\"?b:\"\\\\u\"+(\"0000\"+a.charCodeAt(0).toString(16)).slice(-4)})+'\"':'\"'+a+'\"'}function f(a){return a<10?\"0\"+a:a}\"use strict\",typeof Date.prototype.toJSON!=\"function\"&&(Date.prototype.toJSON=function(a){return isFinite(this.valueOf())?this.getUTCFullYear()+\"-\"+f(this.getUTCMonth()+1)+\"-\"+f(this.getUTCDate())+\"T\"+f(this.getUTCHours())+\":\"+f(this.getUTCMinutes())+\":\"+f(this.getUTCSeconds())+\"Z\":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(a){return this.valueOf()});var cx=/[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,escapable=/[\\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,gap,indent,meta={\"\\b\":\"\\\\b\",\"\\t\":\"\\\\t\",\"\\n\":\"\\\\n\",\"\\f\":\"\\\\f\",\"\\r\":\"\\\\r\",'\"':'\\\\\"',\"\\\\\":\"\\\\\\\\\"},rep;typeof JSON.stringify!=\"function\"&&(JSON.stringify=function(a,b,c){var d;gap=\"\",indent=\"\";if(typeof c==\"number\")for(d=0;d<c;d+=1)indent+=\" \";else typeof c==\"string\"&&(indent=c);rep=b;if(!b||typeof b==\"function\"||typeof b==\"object\"&&typeof b.length==\"number\")return str(\"\",{\"\":a});throw new Error(\"JSON.stringify\")}),typeof JSON.parse!=\"function\"&&(JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&typeof e==\"object\")for(c in e)Object.prototype.hasOwnProperty.call(e,c)&&(d=walk(e,c),d!==undefined?e[c]=d:delete e[c]);return reviver.call(a,b,e)}var j;text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return\"\\\\u\"+(\"0000\"+a.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\\],:{}\\s]*$/.test(text.replace(/\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g,\"@\").replace(/\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g,\"]\").replace(/(?:^|:|,)(?:\\s*\\[)+/g,\"\"))){j=eval(\"(\"+text+\")\");return typeof reviver==\"function\"?walk({\"\":j},\"\"):j}throw new SyntaxError(\"JSON.parse\")})}()\n// </METEOR>\n\n// [*] Including lib/index.js\n// Public object\nSockJS = (function(){\n var _document = document;\n var _window = window;\n var utils = {};\n\n\n// [*] Including lib/reventtarget.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\n/* Simplified implementation of DOM2 EventTarget.\n * http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget\n */\nvar REventTarget = function() {};\nREventTarget.prototype.addEventListener = function (eventType, listener) {\n if(!this._listeners) {\n this._listeners = {};\n }\n if(!(eventType in this._listeners)) {\n this._listeners[eventType] = [];\n }\n var arr = this._listeners[eventType];\n if(utils.arrIndexOf(arr, listener) === -1) {\n arr.push(listener);\n }\n return;\n};\n\nREventTarget.prototype.removeEventListener = function (eventType, listener) {\n if(!(this._listeners && (eventType in this._listeners))) {\n return;\n }\n var arr = this._listeners[eventType];\n var idx = utils.arrIndexOf(arr, listener);\n if (idx !== -1) {\n if(arr.length > 1) {\n this._listeners[eventType] = arr.slice(0, idx).concat( arr.slice(idx+1) );\n } else {\n delete this._listeners[eventType];\n }\n return;\n }\n return;\n};\n\nREventTarget.prototype.dispatchEvent = function (event) {\n var t = event.type;\n var args = Array.prototype.slice.call(arguments, 0);\n if (this['on'+t]) {\n this['on'+t].apply(this, args);\n }\n if (this._listeners && t in this._listeners) {\n for(var i=0; i < this._listeners[t].length; i++) {\n this._listeners[t][i].apply(this, args);\n }\n }\n};\n// [*] End of lib/reventtarget.js\n\n\n// [*] Including lib/simpleevent.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar SimpleEvent = function(type, obj) {\n this.type = type;\n if (typeof obj !== 'undefined') {\n for(var k in obj) {\n if (!obj.hasOwnProperty(k)) continue;\n this[k] = obj[k];\n }\n }\n};\n\nSimpleEvent.prototype.toString = function() {\n var r = [];\n for(var k in this) {\n if (!this.hasOwnProperty(k)) continue;\n var v = this[k];\n if (typeof v === 'function') v = '[function]';\n r.push(k + '=' + v);\n }\n return 'SimpleEvent(' + r.join(', ') + ')';\n};\n// [*] End of lib/simpleevent.js\n\n\n// [*] Including lib/eventemitter.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar EventEmitter = function(events) {\n var that = this;\n that._events = events || [];\n that._listeners = {};\n};\nEventEmitter.prototype.emit = function(type) {\n var that = this;\n that._verifyType(type);\n if (that._nuked) return;\n\n var args = Array.prototype.slice.call(arguments, 1);\n if (that['on'+type]) {\n that['on'+type].apply(that, args);\n }\n if (type in that._listeners) {\n for(var i = 0; i < that._listeners[type].length; i++) {\n that._listeners[type][i].apply(that, args);\n }\n }\n};\n\nEventEmitter.prototype.on = function(type, callback) {\n var that = this;\n that._verifyType(type);\n if (that._nuked) return;\n\n if (!(type in that._listeners)) {\n that._listeners[type] = [];\n }\n that._listeners[type].push(callback);\n};\n\nEventEmitter.prototype._verifyType = function(type) {\n var that = this;\n if (utils.arrIndexOf(that._events, type) === -1) {\n utils.log('Event ' + JSON.stringify(type) +\n ' not listed ' + JSON.stringify(that._events) +\n ' in ' + that);\n }\n};\n\nEventEmitter.prototype.nuke = function() {\n var that = this;\n that._nuked = true;\n for(var i=0; i<that._events.length; i++) {\n delete that[that._events[i]];\n }\n that._listeners = {};\n};\n// [*] End of lib/eventemitter.js\n\n\n// [*] Including lib/utils.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar random_string_chars = 'abcdefghijklmnopqrstuvwxyz0123456789_';\nutils.random_string = function(length, max) {\n max = max || random_string_chars.length;\n var i, ret = [];\n for(i=0; i < length; i++) {\n ret.push( random_string_chars.substr(Math.floor(Math.random() * max),1) );\n }\n return ret.join('');\n};\nutils.random_number = function(max) {\n return Math.floor(Math.random() * max);\n};\nutils.random_number_string = function(max) {\n var t = (''+(max - 1)).length;\n var p = Array(t+1).join('0');\n return (p + utils.random_number(max)).slice(-t);\n};\n\n// Assuming that url looks like: http://asdasd:111/asd\nutils.getOrigin = function(url) {\n url += '/';\n var parts = url.split('/').slice(0, 3);\n return parts.join('/');\n};\n\nutils.isSameOriginUrl = function(url_a, url_b) {\n // location.origin would do, but it's not always available.\n if (!url_b) url_b = _window.location.href;\n\n return (url_a.split('/').slice(0,3).join('/')\n ===\n url_b.split('/').slice(0,3).join('/'));\n};\n\n// <METEOR>\n// https://github.com/sockjs/sockjs-client/issues/79\nutils.isSameOriginScheme = function(url_a, url_b) {\n if (!url_b) url_b = _window.location.href;\n\n return (url_a.split(':')[0]\n ===\n url_b.split(':')[0]);\n};\n// </METEOR>\n\n\nutils.getParentDomain = function(url) {\n // ipv4 ip address\n if (/^[0-9.]*$/.test(url)) return url;\n // ipv6 ip address\n if (/^\\[/.test(url)) return url;\n // no dots\n if (!(/[.]/.test(url))) return url;\n\n var parts = url.split('.').slice(1);\n return parts.join('.');\n};\n\nutils.objectExtend = function(dst, src) {\n for(var k in src) {\n if (src.hasOwnProperty(k)) {\n dst[k] = src[k];\n }\n }\n return dst;\n};\n\nvar WPrefix = '_jp';\n\nutils.polluteGlobalNamespace = function() {\n if (!(WPrefix in _window)) {\n _window[WPrefix] = {};\n }\n};\n\nutils.closeFrame = function (code, reason) {\n return 'c'+JSON.stringify([code, reason]);\n};\n\nutils.userSetCode = function (code) {\n return code === 1000 || (code >= 3000 && code <= 4999);\n};\n\n// See: http://www.erg.abdn.ac.uk/~gerrit/dccp/notes/ccid2/rto_estimator/\n// and RFC 2988.\nutils.countRTO = function (rtt) {\n var rto;\n if (rtt > 100) {\n rto = 3 * rtt; // rto > 300msec\n } else {\n rto = rtt + 200; // 200msec < rto <= 300msec\n }\n return rto;\n}\n\nutils.log = function() {\n if (_window.console && console.log && console.log.apply) {\n console.log.apply(console, arguments);\n }\n};\n\nutils.bind = function(fun, that) {\n if (fun.bind) {\n return fun.bind(that);\n } else {\n return function() {\n return fun.apply(that, arguments);\n };\n }\n};\n\nutils.flatUrl = function(url) {\n return url.indexOf('?') === -1 && url.indexOf('#') === -1;\n};\n\n// `relativeTo` is an optional absolute URL. If provided, `url` will be\n// interpreted relative to `relativeTo`. Defaults to `document.location`.\n// <METEOR>\nutils.amendUrl = function(url, relativeTo) {\n var baseUrl;\n if (relativeTo === undefined) {\n baseUrl = _document.location;\n } else {\n var protocolMatch = /^([a-z0-9.+-]+:)/i.exec(relativeTo);\n if (protocolMatch) {\n var protocol = protocolMatch[0].toLowerCase();\n var rest = relativeTo.substring(protocol.length);\n var hostMatch = /[a-z0-9\\.-]+(:[0-9]+)?/.exec(rest);\n if (hostMatch)\n var host = hostMatch[0];\n }\n if (! protocol || ! host)\n throw new Error(\"relativeTo must be an absolute url\");\n baseUrl = {\n protocol: protocol,\n host: host\n };\n }\n if (!url) {\n throw new Error('Wrong url for SockJS');\n }\n if (!utils.flatUrl(url)) {\n throw new Error('Only basic urls are supported in SockJS');\n }\n\n // '//abc' --> 'http://abc'\n if (url.indexOf('//') === 0) {\n url = baseUrl.protocol + url;\n }\n // '/abc' --> 'http://localhost:1234/abc'\n if (url.indexOf('/') === 0) {\n url = baseUrl.protocol + '//' + baseUrl.host + url;\n }\n // </METEOR>\n // strip trailing slashes\n url = url.replace(/[/]+$/,'');\n\n // We have a full url here, with proto and host. For some browsers\n // http://localhost:80/ is not in the same origin as http://localhost/\n\t// Remove explicit :80 or :443 in such cases. See #74\n var parts = url.split(\"/\");\n if ((parts[0] === \"http:\" && /:80$/.test(parts[2])) ||\n\t (parts[0] === \"https:\" && /:443$/.test(parts[2]))) {\n\t\tparts[2] = parts[2].replace(/:(80|443)$/, \"\");\n\t}\n url = parts.join(\"/\");\n return url;\n};\n\n// IE doesn't support [].indexOf.\nutils.arrIndexOf = function(arr, obj){\n for(var i=0; i < arr.length; i++){\n if(arr[i] === obj){\n return i;\n }\n }\n return -1;\n};\n\nutils.arrSkip = function(arr, obj) {\n var idx = utils.arrIndexOf(arr, obj);\n if (idx === -1) {\n return arr.slice();\n } else {\n var dst = arr.slice(0, idx);\n return dst.concat(arr.slice(idx+1));\n }\n};\n\n// Via: https://gist.github.com/1133122/2121c601c5549155483f50be3da5305e83b8c5df\nutils.isArray = Array.isArray || function(value) {\n return {}.toString.call(value).indexOf('Array') >= 0\n};\n\nutils.delay = function(t, fun) {\n if(typeof t === 'function') {\n fun = t;\n t = 0;\n }\n return setTimeout(fun, t);\n};\n\n\n// Chars worth escaping, as defined by Douglas Crockford:\n// https://github.com/douglascrockford/JSON-js/blob/47a9882cddeb1e8529e07af9736218075372b8ac/json2.js#L196\nvar json_escapable = /[\\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,\n json_lookup = {\n\"\\u0000\":\"\\\\u0000\",\"\\u0001\":\"\\\\u0001\",\"\\u0002\":\"\\\\u0002\",\"\\u0003\":\"\\\\u0003\",\n\"\\u0004\":\"\\\\u0004\",\"\\u0005\":\"\\\\u0005\",\"\\u0006\":\"\\\\u0006\",\"\\u0007\":\"\\\\u0007\",\n\"\\b\":\"\\\\b\",\"\\t\":\"\\\\t\",\"\\n\":\"\\\\n\",\"\\u000b\":\"\\\\u000b\",\"\\f\":\"\\\\f\",\"\\r\":\"\\\\r\",\n\"\\u000e\":\"\\\\u000e\",\"\\u000f\":\"\\\\u000f\",\"\\u0010\":\"\\\\u0010\",\"\\u0011\":\"\\\\u0011\",\n\"\\u0012\":\"\\\\u0012\",\"\\u0013\":\"\\\\u0013\",\"\\u0014\":\"\\\\u0014\",\"\\u0015\":\"\\\\u0015\",\n\"\\u0016\":\"\\\\u0016\",\"\\u0017\":\"\\\\u0017\",\"\\u0018\":\"\\\\u0018\",\"\\u0019\":\"\\\\u0019\",\n\"\\u001a\":\"\\\\u001a\",\"\\u001b\":\"\\\\u001b\",\"\\u001c\":\"\\\\u001c\",\"\\u001d\":\"\\\\u001d\",\n\"\\u001e\":\"\\\\u001e\",\"\\u001f\":\"\\\\u001f\",\"\\\"\":\"\\\\\\\"\",\"\\\\\":\"\\\\\\\\\",\n\"\\u007f\":\"\\\\u007f\",\"\\u0080\":\"\\\\u0080\",\"\\u0081\":\"\\\\u0081\",\"\\u0082\":\"\\\\u0082\",\n\"\\u0083\":\"\\\\u0083\",\"\\u0084\":\"\\\\u0084\",\"\\u0085\":\"\\\\u0085\",\"\\u0086\":\"\\\\u0086\",\n\"\\u0087\":\"\\\\u0087\",\"\\u0088\":\"\\\\u0088\",\"\\u0089\":\"\\\\u0089\",\"\\u008a\":\"\\\\u008a\",\n\"\\u008b\":\"\\\\u008b\",\"\\u008c\":\"\\\\u008c\",\"\\u008d\":\"\\\\u008d\",\"\\u008e\":\"\\\\u008e\",\n\"\\u008f\":\"\\\\u008f\",\"\\u0090\":\"\\\\u0090\",\"\\u0091\":\"\\\\u0091\",\"\\u0092\":\"\\\\u0092\",\n\"\\u0093\":\"\\\\u0093\",\"\\u0094\":\"\\\\u0094\",\"\\u0095\":\"\\\\u0095\",\"\\u0096\":\"\\\\u0096\",\n\"\\u0097\":\"\\\\u0097\",\"\\u0098\":\"\\\\u0098\",\"\\u0099\":\"\\\\u0099\",\"\\u009a\":\"\\\\u009a\",\n\"\\u009b\":\"\\\\u009b\",\"\\u009c\":\"\\\\u009c\",\"\\u009d\":\"\\\\u009d\",\"\\u009e\":\"\\\\u009e\",\n\"\\u009f\":\"\\\\u009f\",\"\\u00ad\":\"\\\\u00ad\",\"\\u0600\":\"\\\\u0600\",\"\\u0601\":\"\\\\u0601\",\n\"\\u0602\":\"\\\\u0602\",\"\\u0603\":\"\\\\u0603\",\"\\u0604\":\"\\\\u0604\",\"\\u070f\":\"\\\\u070f\",\n\"\\u17b4\":\"\\\\u17b4\",\"\\u17b5\":\"\\\\u17b5\",\"\\u200c\":\"\\\\u200c\",\"\\u200d\":\"\\\\u200d\",\n\"\\u200e\":\"\\\\u200e\",\"\\u200f\":\"\\\\u200f\",\"\\u2028\":\"\\\\u2028\",\"\\u2029\":\"\\\\u2029\",\n\"\\u202a\":\"\\\\u202a\",\"\\u202b\":\"\\\\u202b\",\"\\u202c\":\"\\\\u202c\",\"\\u202d\":\"\\\\u202d\",\n\"\\u202e\":\"\\\\u202e\",\"\\u202f\":\"\\\\u202f\",\"\\u2060\":\"\\\\u2060\",\"\\u2061\":\"\\\\u2061\",\n\"\\u2062\":\"\\\\u2062\",\"\\u2063\":\"\\\\u2063\",\"\\u2064\":\"\\\\u2064\",\"\\u2065\":\"\\\\u2065\",\n\"\\u2066\":\"\\\\u2066\",\"\\u2067\":\"\\\\u2067\",\"\\u2068\":\"\\\\u2068\",\"\\u2069\":\"\\\\u2069\",\n\"\\u206a\":\"\\\\u206a\",\"\\u206b\":\"\\\\u206b\",\"\\u206c\":\"\\\\u206c\",\"\\u206d\":\"\\\\u206d\",\n\"\\u206e\":\"\\\\u206e\",\"\\u206f\":\"\\\\u206f\",\"\\ufeff\":\"\\\\ufeff\",\"\\ufff0\":\"\\\\ufff0\",\n\"\\ufff1\":\"\\\\ufff1\",\"\\ufff2\":\"\\\\ufff2\",\"\\ufff3\":\"\\\\ufff3\",\"\\ufff4\":\"\\\\ufff4\",\n\"\\ufff5\":\"\\\\ufff5\",\"\\ufff6\":\"\\\\ufff6\",\"\\ufff7\":\"\\\\ufff7\",\"\\ufff8\":\"\\\\ufff8\",\n\"\\ufff9\":\"\\\\ufff9\",\"\\ufffa\":\"\\\\ufffa\",\"\\ufffb\":\"\\\\ufffb\",\"\\ufffc\":\"\\\\ufffc\",\n\"\\ufffd\":\"\\\\ufffd\",\"\\ufffe\":\"\\\\ufffe\",\"\\uffff\":\"\\\\uffff\"};\n\n// Some extra characters that Chrome gets wrong, and substitutes with\n// something else on the wire.\nvar extra_escapable = /[\\x00-\\x1f\\ud800-\\udfff\\ufffe\\uffff\\u0300-\\u0333\\u033d-\\u0346\\u034a-\\u034c\\u0350-\\u0352\\u0357-\\u0358\\u035c-\\u0362\\u0374\\u037e\\u0387\\u0591-\\u05af\\u05c4\\u0610-\\u0617\\u0653-\\u0654\\u0657-\\u065b\\u065d-\\u065e\\u06df-\\u06e2\\u06eb-\\u06ec\\u0730\\u0732-\\u0733\\u0735-\\u0736\\u073a\\u073d\\u073f-\\u0741\\u0743\\u0745\\u0747\\u07eb-\\u07f1\\u0951\\u0958-\\u095f\\u09dc-\\u09dd\\u09df\\u0a33\\u0a36\\u0a59-\\u0a5b\\u0a5e\\u0b5c-\\u0b5d\\u0e38-\\u0e39\\u0f43\\u0f4d\\u0f52\\u0f57\\u0f5c\\u0f69\\u0f72-\\u0f76\\u0f78\\u0f80-\\u0f83\\u0f93\\u0f9d\\u0fa2\\u0fa7\\u0fac\\u0fb9\\u1939-\\u193a\\u1a17\\u1b6b\\u1cda-\\u1cdb\\u1dc0-\\u1dcf\\u1dfc\\u1dfe\\u1f71\\u1f73\\u1f75\\u1f77\\u1f79\\u1f7b\\u1f7d\\u1fbb\\u1fbe\\u1fc9\\u1fcb\\u1fd3\\u1fdb\\u1fe3\\u1feb\\u1fee-\\u1fef\\u1ff9\\u1ffb\\u1ffd\\u2000-\\u2001\\u20d0-\\u20d1\\u20d4-\\u20d7\\u20e7-\\u20e9\\u2126\\u212a-\\u212b\\u2329-\\u232a\\u2adc\\u302b-\\u302c\\uaab2-\\uaab3\\uf900-\\ufa0d\\ufa10\\ufa12\\ufa15-\\ufa1e\\ufa20\\ufa22\\ufa25-\\ufa26\\ufa2a-\\ufa2d\\ufa30-\\ufa6d\\ufa70-\\ufad9\\ufb1d\\ufb1f\\ufb2a-\\ufb36\\ufb38-\\ufb3c\\ufb3e\\ufb40-\\ufb41\\ufb43-\\ufb44\\ufb46-\\ufb4e\\ufff0-\\uffff]/g,\n extra_lookup;\n\n// JSON Quote string. Use native implementation when possible.\nvar JSONQuote = (JSON && JSON.stringify) || function(string) {\n json_escapable.lastIndex = 0;\n if (json_escapable.test(string)) {\n string = string.replace(json_escapable, function(a) {\n return json_lookup[a];\n });\n }\n return '\"' + string + '\"';\n};\n\n// This may be quite slow, so let's delay until user actually uses bad\n// characters.\nvar unroll_lookup = function(escapable) {\n var i;\n var unrolled = {}\n var c = []\n for(i=0; i<65536; i++) {\n c.push( String.fromCharCode(i) );\n }\n escapable.lastIndex = 0;\n c.join('').replace(escapable, function (a) {\n unrolled[ a ] = '\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n return '';\n });\n escapable.lastIndex = 0;\n return unrolled;\n};\n\n// Quote string, also taking care of unicode characters that browsers\n// often break. Especially, take care of unicode surrogates:\n// http://en.wikipedia.org/wiki/Mapping_of_Unicode_characters#Surrogates\nutils.quote = function(string) {\n var quoted = JSONQuote(string);\n\n // In most cases this should be very fast and good enough.\n extra_escapable.lastIndex = 0;\n if(!extra_escapable.test(quoted)) {\n return quoted;\n }\n\n if(!extra_lookup) extra_lookup = unroll_lookup(extra_escapable);\n\n return quoted.replace(extra_escapable, function(a) {\n return extra_lookup[a];\n });\n}\n\nvar _all_protocols = ['websocket',\n 'xdr-streaming',\n 'xhr-streaming',\n 'iframe-eventsource',\n 'iframe-htmlfile',\n 'xdr-polling',\n 'xhr-polling',\n 'iframe-xhr-polling',\n 'jsonp-polling'];\n\nutils.probeProtocols = function() {\n var probed = {};\n for(var i=0; i<_all_protocols.length; i++) {\n var protocol = _all_protocols[i];\n // User can have a typo in protocol name.\n probed[protocol] = SockJS[protocol] &&\n SockJS[protocol].enabled();\n }\n return probed;\n};\n\nutils.detectProtocols = function(probed, protocols_whitelist, info) {\n var pe = {},\n protocols = [];\n if (!protocols_whitelist) protocols_whitelist = _all_protocols;\n for(var i=0; i<protocols_whitelist.length; i++) {\n var protocol = protocols_whitelist[i];\n pe[protocol] = probed[protocol];\n }\n var maybe_push = function(protos) {\n var proto = protos.shift();\n if (pe[proto]) {\n protocols.push(proto);\n } else {\n if (protos.length > 0) {\n maybe_push(protos);\n }\n }\n }\n\n // 1. Websocket\n if (info.websocket !== false) {\n maybe_push(['websocket']);\n }\n\n // 2. Streaming\n if (pe['xhr-streaming'] && !info.null_origin) {\n protocols.push('xhr-streaming');\n } else {\n if (pe['xdr-streaming'] && !info.cookie_needed && !info.null_origin) {\n protocols.push('xdr-streaming');\n } else {\n maybe_push(['iframe-eventsource',\n 'iframe-htmlfile']);\n }\n }\n\n // 3. Polling\n if (pe['xhr-polling'] && !info.null_origin) {\n protocols.push('xhr-polling');\n } else {\n if (pe['xdr-polling'] && !info.cookie_needed && !info.null_origin) {\n protocols.push('xdr-polling');\n } else {\n maybe_push(['iframe-xhr-polling',\n 'jsonp-polling']);\n }\n }\n return protocols;\n}\n// [*] End of lib/utils.js\n\n\n// [*] Including lib/dom.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\n// May be used by htmlfile jsonp and transports.\nvar MPrefix = '_sockjs_global';\nutils.createHook = function() {\n var window_id = 'a' + utils.random_string(8);\n if (!(MPrefix in _window)) {\n var map = {};\n _window[MPrefix] = function(window_id) {\n if (!(window_id in map)) {\n map[window_id] = {\n id: window_id,\n del: function() {delete map[window_id];}\n };\n }\n return map[window_id];\n }\n }\n return _window[MPrefix](window_id);\n};\n\n\n\nutils.attachMessage = function(listener) {\n utils.attachEvent('message', listener);\n};\nutils.attachEvent = function(event, listener) {\n if (typeof _window.addEventListener !== 'undefined') {\n _window.addEventListener(event, listener, false);\n } else {\n // IE quirks.\n // According to: http://stevesouders.com/misc/test-postmessage.php\n // the message gets delivered only to 'document', not 'window'.\n _document.attachEvent(\"on\" + event, listener);\n // I get 'window' for ie8.\n _window.attachEvent(\"on\" + event, listener);\n }\n};\n\nutils.detachMessage = function(listener) {\n utils.detachEvent('message', listener);\n};\nutils.detachEvent = function(event, listener) {\n if (typeof _window.addEventListener !== 'undefined') {\n _window.removeEventListener(event, listener, false);\n } else {\n _document.detachEvent(\"on\" + event, listener);\n _window.detachEvent(\"on\" + event, listener);\n }\n};\n\n\nvar on_unload = {};\n// Things registered after beforeunload are to be called immediately.\nvar after_unload = false;\n\nvar trigger_unload_callbacks = function() {\n for(var ref in on_unload) {\n on_unload[ref]();\n delete on_unload[ref];\n };\n};\n\nvar unload_triggered = function() {\n if(after_unload) return;\n after_unload = true;\n trigger_unload_callbacks();\n};\n\n// 'unload' alone is not reliable in opera within an iframe, but we\n// can't use `beforeunload` as IE fires it on javascript: links.\nutils.attachEvent('unload', unload_triggered);\n\nutils.unload_add = function(listener) {\n var ref = utils.random_string(8);\n on_unload[ref] = listener;\n if (after_unload) {\n utils.delay(trigger_unload_callbacks);\n }\n return ref;\n};\nutils.unload_del = function(ref) {\n if (ref in on_unload)\n delete on_unload[ref];\n};\n\n\nutils.createIframe = function (iframe_url, error_callback) {\n var iframe = _document.createElement('iframe');\n var tref, unload_ref;\n var unattach = function() {\n clearTimeout(tref);\n // Explorer had problems with that.\n try {iframe.onload = null;} catch (x) {}\n iframe.onerror = null;\n };\n var cleanup = function() {\n if (iframe) {\n unattach();\n // This timeout makes chrome fire onbeforeunload event\n // within iframe. Without the timeout it goes straight to\n // onunload.\n setTimeout(function() {\n if(iframe) {\n iframe.parentNode.removeChild(iframe);\n }\n iframe = null;\n }, 0);\n utils.unload_del(unload_ref);\n }\n };\n var onerror = function(r) {\n if (iframe) {\n cleanup();\n error_callback(r);\n }\n };\n var post = function(msg, origin) {\n try {\n // When the iframe is not loaded, IE raises an exception\n // on 'contentWindow'.\n if (iframe && iframe.contentWindow) {\n iframe.contentWindow.postMessage(msg, origin);\n }\n } catch (x) {};\n };\n\n iframe.src = iframe_url;\n iframe.style.display = 'none';\n iframe.style.position = 'absolute';\n iframe.onerror = function(){onerror('onerror');};\n iframe.onload = function() {\n // `onload` is triggered before scripts on the iframe are\n // executed. Give it few seconds to actually load stuff.\n clearTimeout(tref);\n tref = setTimeout(function(){onerror('onload timeout');}, 2000);\n };\n _document.body.appendChild(iframe);\n tref = setTimeout(function(){onerror('timeout');}, 15000);\n unload_ref = utils.unload_add(cleanup);\n return {\n post: post,\n cleanup: cleanup,\n loaded: unattach\n };\n};\n\nutils.createHtmlfile = function (iframe_url, error_callback) {\n var doc = new ActiveXObject('htmlfile');\n var tref, unload_ref;\n var iframe;\n var unattach = function() {\n clearTimeout(tref);\n };\n var cleanup = function() {\n if (doc) {\n unattach();\n utils.unload_del(unload_ref);\n iframe.parentNode.removeChild(iframe);\n iframe = doc = null;\n CollectGarbage();\n }\n };\n var onerror = function(r) {\n if (doc) {\n cleanup();\n error_callback(r);\n }\n };\n var post = function(msg, origin) {\n try {\n // When the iframe is not loaded, IE raises an exception\n // on 'contentWindow'.\n if (iframe && iframe.contentWindow) {\n iframe.contentWindow.postMessage(msg, origin);\n }\n } catch (x) {};\n };\n\n doc.open();\n doc.write('<html><s' + 'cript>' +\n 'document.domain=\"' + document.domain + '\";' +\n '</s' + 'cript></html>');\n doc.close();\n doc.parentWindow[WPrefix] = _window[WPrefix];\n var c = doc.createElement('div');\n doc.body.appendChild(c);\n iframe = doc.createElement('iframe');\n c.appendChild(iframe);\n iframe.src = iframe_url;\n tref = setTimeout(function(){onerror('timeout');}, 15000);\n unload_ref = utils.unload_add(cleanup);\n return {\n post: post,\n cleanup: cleanup,\n loaded: unattach\n };\n};\n// [*] End of lib/dom.js\n\n\n// [*] Including lib/dom2.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar AbstractXHRObject = function(){};\nAbstractXHRObject.prototype = new EventEmitter(['chunk', 'finish']);\n\nAbstractXHRObject.prototype._start = function(method, url, payload, opts) {\n var that = this;\n\n try {\n that.xhr = new XMLHttpRequest();\n } catch(x) {};\n\n if (!that.xhr) {\n try {\n that.xhr = new _window.ActiveXObject('Microsoft.XMLHTTP');\n } catch(x) {};\n }\n if (_window.ActiveXObject || _window.XDomainRequest) {\n // IE8 caches even POSTs\n url += ((url.indexOf('?') === -1) ? '?' : '&') + 't='+(+new Date);\n }\n\n // Explorer tends to keep connection open, even after the\n // tab gets closed: http://bugs.jquery.com/ticket/5280\n that.unload_ref = utils.unload_add(function(){that._cleanup(true);});\n try {\n that.xhr.open(method, url, true);\n } catch(e) {\n // IE raises an exception on wrong port.\n that.emit('finish', 0, '');\n that._cleanup();\n return;\n };\n\n if (!opts || !opts.no_credentials) {\n // Mozilla docs says https://developer.mozilla.org/en/XMLHttpRequest :\n // \"This never affects same-site requests.\"\n that.xhr.withCredentials = 'true';\n }\n if (opts && opts.headers) {\n for(var key in opts.headers) {\n that.xhr.setRequestHeader(key, opts.headers[key]);\n }\n }\n\n that.xhr.onreadystatechange = function() {\n if (that.xhr) {\n var x = that.xhr;\n switch (x.readyState) {\n case 3:\n // IE doesn't like peeking into responseText or status\n // on Microsoft.XMLHTTP and readystate=3\n try {\n var status = x.status;\n var text = x.responseText;\n } catch (x) {};\n // IE returns 1223 for 204: http://bugs.jquery.com/ticket/1450\n if (status === 1223) status = 204;\n\n // IE does return readystate == 3 for 404 answers.\n if (text && text.length > 0) {\n that.emit('chunk', status, text);\n }\n break;\n case 4:\n var status = x.status;\n // IE returns 1223 for 204: http://bugs.jquery.com/ticket/1450\n if (status === 1223) status = 204;\n\n that.emit('finish', status, x.responseText);\n that._cleanup(false);\n break;\n }\n }\n };\n that.xhr.send(payload);\n};\n\nAbstractXHRObject.prototype._cleanup = function(abort) {\n var that = this;\n if (!that.xhr) return;\n utils.unload_del(that.unload_ref);\n\n // IE needs this field to be a function\n that.xhr.onreadystatechange = function(){};\n\n if (abort) {\n try {\n that.xhr.abort();\n } catch(x) {};\n }\n that.unload_ref = that.xhr = null;\n};\n\nAbstractXHRObject.prototype.close = function() {\n var that = this;\n that.nuke();\n that._cleanup(true);\n};\n\nvar XHRCorsObject = utils.XHRCorsObject = function() {\n var that = this, args = arguments;\n utils.delay(function(){that._start.apply(that, args);});\n};\nXHRCorsObject.prototype = new AbstractXHRObject();\n\nvar XHRLocalObject = utils.XHRLocalObject = function(method, url, payload) {\n var that = this;\n utils.delay(function(){\n that._start(method, url, payload, {\n no_credentials: true\n });\n });\n};\nXHRLocalObject.prototype = new AbstractXHRObject();\n\n\n\n// References:\n// http://ajaxian.com/archives/100-line-ajax-wrapper\n// http://msdn.microsoft.com/en-us/library/cc288060(v=VS.85).aspx\nvar XDRObject = utils.XDRObject = function(method, url, payload) {\n var that = this;\n utils.delay(function(){that._start(method, url, payload);});\n};\nXDRObject.prototype = new EventEmitter(['chunk', 'finish']);\nXDRObject.prototype._start = function(method, url, payload) {\n var that = this;\n var xdr = new XDomainRequest();\n // IE caches even POSTs\n url += ((url.indexOf('?') === -1) ? '?' : '&') + 't='+(+new Date);\n\n var onerror = xdr.ontimeout = xdr.onerror = function() {\n that.emit('finish', 0, '');\n that._cleanup(false);\n };\n xdr.onprogress = function() {\n that.emit('chunk', 200, xdr.responseText);\n };\n xdr.onload = function() {\n that.emit('finish', 200, xdr.responseText);\n that._cleanup(false);\n };\n that.xdr = xdr;\n that.unload_ref = utils.unload_add(function(){that._cleanup(true);});\n try {\n // Fails with AccessDenied if port number is bogus\n that.xdr.open(method, url);\n that.xdr.send(payload);\n } catch(x) {\n onerror();\n }\n};\n\nXDRObject.prototype._cleanup = function(abort) {\n var that = this;\n if (!that.xdr) return;\n utils.unload_del(that.unload_ref);\n\n that.xdr.ontimeout = that.xdr.onerror = that.xdr.onprogress =\n that.xdr.onload = null;\n if (abort) {\n try {\n that.xdr.abort();\n } catch(x) {};\n }\n that.unload_ref = that.xdr = null;\n};\n\nXDRObject.prototype.close = function() {\n var that = this;\n that.nuke();\n that._cleanup(true);\n};\n\n// 1. Is natively via XHR\n// 2. Is natively via XDR\n// 3. Nope, but postMessage is there so it should work via the Iframe.\n// 4. Nope, sorry.\nutils.isXHRCorsCapable = function() {\n if (_window.XMLHttpRequest && 'withCredentials' in new XMLHttpRequest()) {\n return 1;\n }\n // XDomainRequest doesn't work if page is served from file://\n if (_window.XDomainRequest && _document.domain) {\n return 2;\n }\n if (IframeTransport.enabled()) {\n return 3;\n }\n return 4;\n};\n// [*] End of lib/dom2.js\n\n\n// [*] Including lib/sockjs.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar SockJS = function(url, dep_protocols_whitelist, options) {\n if (!(this instanceof SockJS)) {\n // makes `new` optional\n return new SockJS(url, dep_protocols_whitelist, options);\n }\n\n var that = this, protocols_whitelist;\n that._options = {devel: false, debug: false, protocols_whitelist: [],\n info: undefined, rtt: undefined};\n if (options) {\n utils.objectExtend(that._options, options);\n }\n that._base_url = utils.amendUrl(url);\n that._server = that._options.server || utils.random_number_string(1000);\n if (that._options.protocols_whitelist &&\n that._options.protocols_whitelist.length) {\n protocols_whitelist = that._options.protocols_whitelist;\n } else {\n // Deprecated API\n if (typeof dep_protocols_whitelist === 'string' &&\n dep_protocols_whitelist.length > 0) {\n protocols_whitelist = [dep_protocols_whitelist];\n } else if (utils.isArray(dep_protocols_whitelist)) {\n protocols_whitelist = dep_protocols_whitelist\n } else {\n protocols_whitelist = null;\n }\n if (protocols_whitelist) {\n that._debug('Deprecated API: Use \"protocols_whitelist\" option ' +\n 'instead of supplying protocol list as a second ' +\n 'parameter to SockJS constructor.');\n }\n }\n that._protocols = [];\n that.protocol = null;\n that.readyState = SockJS.CONNECTING;\n that._ir = createInfoReceiver(that._base_url);\n that._ir.onfinish = function(info, rtt) {\n that._ir = null;\n if (info) {\n if (that._options.info) {\n // Override if user supplies the option\n info = utils.objectExtend(info, that._options.info);\n }\n if (that._options.rtt) {\n rtt = that._options.rtt;\n }\n that._applyInfo(info, rtt, protocols_whitelist);\n that._didClose();\n } else {\n that._didClose(1002, 'Can\\'t connect to server', true);\n }\n };\n};\n// Inheritance\nSockJS.prototype = new REventTarget();\n\nSockJS.version = \"0.3.4\";\n\nSockJS.CONNECTING = 0;\nSockJS.OPEN = 1;\nSockJS.CLOSING = 2;\nSockJS.CLOSED = 3;\n\nSockJS.prototype._debug = function() {\n if (this._options.debug)\n utils.log.apply(utils, arguments);\n};\n\nSockJS.prototype._dispatchOpen = function() {\n var that = this;\n if (that.readyState === SockJS.CONNECTING) {\n if (that._transport_tref) {\n clearTimeout(that._transport_tref);\n that._transport_tref = null;\n }\n that.readyState = SockJS.OPEN;\n that.dispatchEvent(new SimpleEvent(\"open\"));\n } else {\n // The server might have been restarted, and lost track of our\n // connection.\n that._didClose(1006, \"Server lost session\");\n }\n};\n\nSockJS.prototype._dispatchMessage = function(data) {\n var that = this;\n if (that.readyState !== SockJS.OPEN)\n return;\n that.dispatchEvent(new SimpleEvent(\"message\", {data: data}));\n};\n\nSockJS.prototype._dispatchHeartbeat = function(data) {\n var that = this;\n if (that.readyState !== SockJS.OPEN)\n return;\n that.dispatchEvent(new SimpleEvent('heartbeat', {}));\n};\n\nSockJS.prototype._didClose = function(code, reason, force) {\n var that = this;\n if (that.readyState !== SockJS.CONNECTING &&\n that.readyState !== SockJS.OPEN &&\n that.readyState !== SockJS.CLOSING)\n throw new Error('INVALID_STATE_ERR');\n if (that._ir) {\n that._ir.nuke();\n that._ir = null;\n }\n\n if (that._transport) {\n that._transport.doCleanup();\n that._transport = null;\n }\n\n var close_event = new SimpleEvent(\"close\", {\n code: code,\n reason: reason,\n wasClean: utils.userSetCode(code)});\n\n if (!utils.userSetCode(code) &&\n that.readyState === SockJS.CONNECTING && !force) {\n if (that._try_next_protocol(close_event)) {\n return;\n }\n close_event = new SimpleEvent(\"close\", {code: 2000,\n reason: \"All transports failed\",\n wasClean: false,\n last_event: close_event});\n }\n that.readyState = SockJS.CLOSED;\n\n utils.delay(function() {\n that.dispatchEvent(close_event);\n });\n};\n\nSockJS.prototype._didMessage = function(data) {\n var that = this;\n var type = data.slice(0, 1);\n switch(type) {\n case 'o':\n that._dispatchOpen();\n break;\n case 'a':\n var payload = JSON.parse(data.slice(1) || '[]');\n for(var i=0; i < payload.length; i++){\n that._dispatchMessage(payload[i]);\n }\n break;\n case 'm':\n var payload = JSON.parse(data.slice(1) || 'null');\n that._dispatchMessage(payload);\n break;\n case 'c':\n var payload = JSON.parse(data.slice(1) || '[]');\n that._didClose(payload[0], payload[1]);\n break;\n case 'h':\n that._dispatchHeartbeat();\n break;\n }\n};\n\nSockJS.prototype._try_next_protocol = function(close_event) {\n var that = this;\n if (that.protocol) {\n that._debug('Closed transport:', that.protocol, ''+close_event);\n that.protocol = null;\n }\n if (that._transport_tref) {\n clearTimeout(that._transport_tref);\n that._transport_tref = null;\n }\n\n while(1) {\n var protocol = that.protocol = that._protocols.shift();\n if (!protocol) {\n return false;\n }\n // Some protocols require access to `body`, what if were in\n // the `head`?\n if (SockJS[protocol] &&\n SockJS[protocol].need_body === true &&\n (!_document.body ||\n (typeof _document.readyState !== 'undefined'\n && _document.readyState !== 'complete'))) {\n that._protocols.unshift(protocol);\n that.protocol = 'waiting-for-load';\n utils.attachEvent('load', function(){\n that._try_next_protocol();\n });\n return true;\n }\n\n if (!SockJS[protocol] ||\n !SockJS[protocol].enabled(that._options)) {\n that._debug('Skipping transport:', protocol);\n } else {\n var roundTrips = SockJS[protocol].roundTrips || 1;\n var to = ((that._options.rto || 0) * roundTrips) || 5000;\n that._transport_tref = utils.delay(to, function() {\n if (that.readyState === SockJS.CONNECTING) {\n // I can't understand how it is possible to run\n // this timer, when the state is CLOSED, but\n // apparently in IE everythin is possible.\n that._didClose(2007, \"Transport timeouted\");\n }\n });\n\n var connid = utils.random_string(8);\n var trans_url = that._base_url + '/' + that._server + '/' + connid;\n that._debug('Opening transport:', protocol, ' url:'+trans_url,\n ' RTO:'+that._options.rto);\n that._transport = new SockJS[protocol](that, trans_url,\n that._base_url);\n return true;\n }\n }\n};\n\nSockJS.prototype.close = function(code, reason) {\n var that = this;\n if (code && !utils.userSetCode(code))\n throw new Error(\"INVALID_ACCESS_ERR\");\n if(that.readyState !== SockJS.CONNECTING &&\n that.readyState !== SockJS.OPEN) {\n return false;\n }\n that.readyState = SockJS.CLOSING;\n that._didClose(code || 1000, reason || \"Normal closure\");\n return true;\n};\n\nSockJS.prototype.send = function(data) {\n var that = this;\n if (that.readyState === SockJS.CONNECTING)\n throw new Error('INVALID_STATE_ERR');\n if (that.readyState === SockJS.OPEN) {\n that._transport.doSend(utils.quote('' + data));\n }\n return true;\n};\n\nSockJS.prototype._applyInfo = function(info, rtt, protocols_whitelist) {\n var that = this;\n that._options.info = info;\n that._options.rtt = rtt;\n that._options.rto = utils.countRTO(rtt);\n that._options.info.null_origin = !_document.domain;\n // Servers can override base_url, eg to provide a randomized domain name and\n // avoid browser per-domain connection limits.\n if (info.base_url)\n // <METEOR>\n that._base_url = utils.amendUrl(info.base_url, that._base_url);\n // </METEOR>\n var probed = utils.probeProtocols();\n that._protocols = utils.detectProtocols(probed, protocols_whitelist, info);\n// <METEOR>\n// https://github.com/sockjs/sockjs-client/issues/79\n // Hack to avoid XDR when using different protocols\n // We're on IE trying to do cross-protocol. jsonp only.\n if (!utils.isSameOriginScheme(that._base_url) &&\n 2 === utils.isXHRCorsCapable()) {\n that._protocols = ['jsonp-polling'];\n }\n// </METEOR>\n};\n// [*] End of lib/sockjs.js\n\n\n// [*] Including lib/trans-websocket.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar WebSocketTransport = SockJS.websocket = function(ri, trans_url) {\n var that = this;\n var url = trans_url + '/websocket';\n if (url.slice(0, 5) === 'https') {\n url = 'wss' + url.slice(5);\n } else {\n url = 'ws' + url.slice(4);\n }\n that.ri = ri;\n that.url = url;\n var Constructor = _window.WebSocket || _window.MozWebSocket;\n\n that.ws = new Constructor(that.url);\n that.ws.onmessage = function(e) {\n that.ri._didMessage(e.data);\n };\n // Firefox has an interesting bug. If a websocket connection is\n // created after onunload, it stays alive even when user\n // navigates away from the page. In such situation let's lie -\n // let's not open the ws connection at all. See:\n // https://github.com/sockjs/sockjs-client/issues/28\n // https://bugzilla.mozilla.org/show_bug.cgi?id=696085\n that.unload_ref = utils.unload_add(function(){that.ws.close()});\n that.ws.onclose = function() {\n that.ri._didMessage(utils.closeFrame(1006, \"WebSocket connection broken\"));\n };\n};\n\nWebSocketTransport.prototype.doSend = function(data) {\n this.ws.send('[' + data + ']');\n};\n\nWebSocketTransport.prototype.doCleanup = function() {\n var that = this;\n var ws = that.ws;\n if (ws) {\n ws.onmessage = ws.onclose = null;\n ws.close();\n utils.unload_del(that.unload_ref);\n that.unload_ref = that.ri = that.ws = null;\n }\n};\n\nWebSocketTransport.enabled = function() {\n return !!(_window.WebSocket || _window.MozWebSocket);\n};\n\n// In theory, ws should require 1 round trip. But in chrome, this is\n// not very stable over SSL. Most likely a ws connection requires a\n// separate SSL connection, in which case 2 round trips are an\n// absolute minumum.\nWebSocketTransport.roundTrips = 2;\n// [*] End of lib/trans-websocket.js\n\n\n// [*] Including lib/trans-sender.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar BufferedSender = function() {};\nBufferedSender.prototype.send_constructor = function(sender) {\n var that = this;\n that.send_buffer = [];\n that.sender = sender;\n};\nBufferedSender.prototype.doSend = function(message) {\n var that = this;\n that.send_buffer.push(message);\n if (!that.send_stop) {\n that.send_schedule();\n }\n};\n\n// For polling transports in a situation when in the message callback,\n// new message is being send. If the sending connection was started\n// before receiving one, it is possible to saturate the network and\n// timeout due to the lack of receiving socket. To avoid that we delay\n// sending messages by some small time, in order to let receiving\n// connection be started beforehand. This is only a halfmeasure and\n// does not fix the big problem, but it does make the tests go more\n// stable on slow networks.\nBufferedSender.prototype.send_schedule_wait = function() {\n var that = this;\n var tref;\n that.send_stop = function() {\n that.send_stop = null;\n clearTimeout(tref);\n };\n tref = utils.delay(25, function() {\n that.send_stop = null;\n that.send_schedule();\n });\n};\n\nBufferedSender.prototype.send_schedule = function() {\n var that = this;\n if (that.send_buffer.length > 0) {\n var payload = '[' + that.send_buffer.join(',') + ']';\n that.send_stop = that.sender(that.trans_url, payload, function(success, abort_reason) {\n that.send_stop = null;\n if (success === false) {\n that.ri._didClose(1006, 'Sending error ' + abort_reason);\n } else {\n that.send_schedule_wait();\n }\n });\n that.send_buffer = [];\n }\n};\n\nBufferedSender.prototype.send_destructor = function() {\n var that = this;\n if (that._send_stop) {\n that._send_stop();\n }\n that._send_stop = null;\n};\n\nvar jsonPGenericSender = function(url, payload, callback) {\n var that = this;\n\n if (!('_send_form' in that)) {\n var form = that._send_form = _document.createElement('form');\n var area = that._send_area = _document.createElement('textarea');\n area.name = 'd';\n form.style.display = 'none';\n form.style.position = 'absolute';\n form.method = 'POST';\n form.enctype = 'application/x-www-form-urlencoded';\n form.acceptCharset = \"UTF-8\";\n form.appendChild(area);\n _document.body.appendChild(form);\n }\n var form = that._send_form;\n var area = that._send_area;\n var id = 'a' + utils.random_string(8);\n form.target = id;\n form.action = url + '/jsonp_send?i=' + id;\n\n var iframe;\n try {\n // ie6 dynamic iframes with target=\"\" support (thanks Chris Lambacher)\n iframe = _document.createElement('<iframe name=\"'+ id +'\">');\n } catch(x) {\n iframe = _document.createElement('iframe');\n iframe.name = id;\n }\n iframe.id = id;\n form.appendChild(iframe);\n iframe.style.display = 'none';\n\n try {\n area.value = payload;\n } catch(e) {\n utils.log('Your browser is seriously broken. Go home! ' + e.message);\n }\n form.submit();\n\n var completed = function(e) {\n if (!iframe.onerror) return;\n iframe.onreadystatechange = iframe.onerror = iframe.onload = null;\n // Opera mini doesn't like if we GC iframe\n // immediately, thus this timeout.\n utils.delay(500, function() {\n iframe.parentNode.removeChild(iframe);\n iframe = null;\n });\n area.value = '';\n // It is not possible to detect if the iframe succeeded or\n // failed to submit our form.\n callback(true);\n };\n iframe.onerror = iframe.onload = completed;\n iframe.onreadystatechange = function(e) {\n if (iframe.readyState == 'complete') completed();\n };\n return completed;\n};\n\nvar createAjaxSender = function(AjaxObject) {\n return function(url, payload, callback) {\n var xo = new AjaxObject('POST', url + '/xhr_send', payload);\n xo.onfinish = function(status, text) {\n callback(status === 200 || status === 204,\n 'http status ' + status);\n };\n return function(abort_reason) {\n callback(false, abort_reason);\n };\n };\n};\n// [*] End of lib/trans-sender.js\n\n\n// [*] Including lib/trans-jsonp-receiver.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\n// Parts derived from Socket.io:\n// https://github.com/LearnBoost/socket.io/blob/0.6.17/lib/socket.io/transports/jsonp-polling.js\n// and jQuery-JSONP:\n// https://code.google.com/p/jquery-jsonp/source/browse/trunk/core/jquery.jsonp.js\nvar jsonPGenericReceiver = function(url, callback) {\n var tref;\n var script = _document.createElement('script');\n var script2; // Opera synchronous load trick.\n var close_script = function(frame) {\n if (script2) {\n script2.parentNode.removeChild(script2);\n script2 = null;\n }\n if (script) {\n clearTimeout(tref);\n // Unfortunately, you can't really abort script loading of\n // the script.\n script.parentNode.removeChild(script);\n script.onreadystatechange = script.onerror =\n script.onload = script.onclick = null;\n script = null;\n callback(frame);\n callback = null;\n }\n };\n\n // IE9 fires 'error' event after orsc or before, in random order.\n var loaded_okay = false;\n var error_timer = null;\n\n script.id = 'a' + utils.random_string(8);\n script.src = url;\n script.type = 'text/javascript';\n script.charset = 'UTF-8';\n script.onerror = function(e) {\n if (!error_timer) {\n // Delay firing close_script.\n error_timer = setTimeout(function() {\n if (!loaded_okay) {\n close_script(utils.closeFrame(\n 1006,\n \"JSONP script loaded abnormally (onerror)\"));\n }\n }, 1000);\n }\n };\n script.onload = function(e) {\n close_script(utils.closeFrame(1006, \"JSONP script loaded abnormally (onload)\"));\n };\n\n script.onreadystatechange = function(e) {\n if (/loaded|closed/.test(script.readyState)) {\n if (script && script.htmlFor && script.onclick) {\n loaded_okay = true;\n try {\n // In IE, actually execute the script.\n script.onclick();\n } catch (x) {}\n }\n if (script) {\n close_script(utils.closeFrame(1006, \"JSONP script loaded abnormally (onreadystatechange)\"));\n }\n }\n };\n // IE: event/htmlFor/onclick trick.\n // One can't rely on proper order for onreadystatechange. In order to\n // make sure, set a 'htmlFor' and 'event' properties, so that\n // script code will be installed as 'onclick' handler for the\n // script object. Later, onreadystatechange, manually execute this\n // code. FF and Chrome doesn't work with 'event' and 'htmlFor'\n // set. For reference see:\n // http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html\n // Also, read on that about script ordering:\n // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order\n if (typeof script.async === 'undefined' && _document.attachEvent) {\n // According to mozilla docs, in recent browsers script.async defaults\n // to 'true', so we may use it to detect a good browser:\n // https://developer.mozilla.org/en/HTML/Element/script\n if (!/opera/i.test(navigator.userAgent)) {\n // Naively assume we're in IE\n try {\n script.htmlFor = script.id;\n script.event = \"onclick\";\n } catch (x) {}\n script.async = true;\n } else {\n // Opera, second sync script hack\n script2 = _document.createElement('script');\n script2.text = \"try{var a = document.getElementById('\"+script.id+\"'); if(a)a.onerror();}catch(x){};\";\n script.async = script2.async = false;\n }\n }\n if (typeof script.async !== 'undefined') {\n script.async = true;\n }\n\n // Fallback mostly for Konqueror - stupid timer, 35 seconds shall be plenty.\n tref = setTimeout(function() {\n close_script(utils.closeFrame(1006, \"JSONP script loaded abnormally (timeout)\"));\n }, 35000);\n\n var head = _document.getElementsByTagName('head')[0];\n head.insertBefore(script, head.firstChild);\n if (script2) {\n head.insertBefore(script2, head.firstChild);\n }\n return close_script;\n};\n// [*] End of lib/trans-jsonp-receiver.js\n\n\n// [*] Including lib/trans-jsonp-polling.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\n// The simplest and most robust transport, using the well-know cross\n// domain hack - JSONP. This transport is quite inefficient - one\n// mssage could use up to one http request. But at least it works almost\n// everywhere.\n// Known limitations:\n// o you will get a spinning cursor\n// o for Konqueror a dumb timer is needed to detect errors\n\n\nvar JsonPTransport = SockJS['jsonp-polling'] = function(ri, trans_url) {\n utils.polluteGlobalNamespace();\n var that = this;\n that.ri = ri;\n that.trans_url = trans_url;\n that.send_constructor(jsonPGenericSender);\n that._schedule_recv();\n};\n\n// Inheritnace\nJsonPTransport.prototype = new BufferedSender();\n\nJsonPTransport.prototype._schedule_recv = function() {\n var that = this;\n var callback = function(data) {\n that._recv_stop = null;\n if (data) {\n // no data - heartbeat;\n if (!that._is_closing) {\n that.ri._didMessage(data);\n }\n }\n // The message can be a close message, and change is_closing state.\n if (!that._is_closing) {\n that._schedule_recv();\n }\n };\n that._recv_stop = jsonPReceiverWrapper(that.trans_url + '/jsonp',\n jsonPGenericReceiver, callback);\n};\n\nJsonPTransport.enabled = function() {\n return true;\n};\n\nJsonPTransport.need_body = true;\n\n\nJsonPTransport.prototype.doCleanup = function() {\n var that = this;\n that._is_closing = true;\n if (that._recv_stop) {\n that._recv_stop();\n }\n that.ri = that._recv_stop = null;\n that.send_destructor();\n};\n\n\n// Abstract away code that handles global namespace pollution.\nvar jsonPReceiverWrapper = function(url, constructReceiver, user_callback) {\n var id = 'a' + utils.random_string(6);\n var url_id = url + '?c=' + escape(WPrefix + '.' + id);\n\n // Unfortunately it is not possible to abort loading of the\n // script. We need to keep track of frake close frames.\n var aborting = 0;\n\n // Callback will be called exactly once.\n var callback = function(frame) {\n switch(aborting) {\n case 0:\n // Normal behaviour - delete hook _and_ emit message.\n delete _window[WPrefix][id];\n user_callback(frame);\n break;\n case 1:\n // Fake close frame - emit but don't delete hook.\n user_callback(frame);\n aborting = 2;\n break;\n case 2:\n // Got frame after connection was closed, delete hook, don't emit.\n delete _window[WPrefix][id];\n break;\n }\n };\n\n var close_script = constructReceiver(url_id, callback);\n _window[WPrefix][id] = close_script;\n var stop = function() {\n if (_window[WPrefix][id]) {\n aborting = 1;\n _window[WPrefix][id](utils.closeFrame(1000, \"JSONP user aborted read\"));\n }\n };\n return stop;\n};\n// [*] End of lib/trans-jsonp-polling.js\n\n\n// [*] Including lib/trans-xhr.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar AjaxBasedTransport = function() {};\nAjaxBasedTransport.prototype = new BufferedSender();\n\nAjaxBasedTransport.prototype.run = function(ri, trans_url,\n url_suffix, Receiver, AjaxObject) {\n var that = this;\n that.ri = ri;\n that.trans_url = trans_url;\n that.send_constructor(createAjaxSender(AjaxObject));\n that.poll = new Polling(ri, Receiver,\n trans_url + url_suffix, AjaxObject);\n};\n\nAjaxBasedTransport.prototype.doCleanup = function() {\n var that = this;\n if (that.poll) {\n that.poll.abort();\n that.poll = null;\n }\n};\n\n// xhr-streaming\nvar XhrStreamingTransport = SockJS['xhr-streaming'] = function(ri, trans_url) {\n this.run(ri, trans_url, '/xhr_streaming', XhrReceiver, utils.XHRCorsObject);\n};\n\nXhrStreamingTransport.prototype = new AjaxBasedTransport();\n\nXhrStreamingTransport.enabled = function() {\n // Support for CORS Ajax aka Ajax2? Opera 12 claims CORS but\n // doesn't do streaming.\n return (_window.XMLHttpRequest &&\n 'withCredentials' in new XMLHttpRequest() &&\n (!/opera/i.test(navigator.userAgent)));\n};\nXhrStreamingTransport.roundTrips = 2; // preflight, ajax\n\n// Safari gets confused when a streaming ajax request is started\n// before onload. This causes the load indicator to spin indefinetely.\nXhrStreamingTransport.need_body = true;\n\n\n// According to:\n// http://stackoverflow.com/questions/1641507/detect-browser-support-for-cross-domain-xmlhttprequests\n// http://hacks.mozilla.org/2009/07/cross-site-xmlhttprequest-with-cors/\n\n\n// xdr-streaming\nvar XdrStreamingTransport = SockJS['xdr-streaming'] = function(ri, trans_url) {\n this.run(ri, trans_url, '/xhr_streaming', XhrReceiver, utils.XDRObject);\n};\n\nXdrStreamingTransport.prototype = new AjaxBasedTransport();\n\nXdrStreamingTransport.enabled = function() {\n return !!_window.XDomainRequest;\n};\nXdrStreamingTransport.roundTrips = 2; // preflight, ajax\n\n\n\n// xhr-polling\nvar XhrPollingTransport = SockJS['xhr-polling'] = function(ri, trans_url) {\n this.run(ri, trans_url, '/xhr', XhrReceiver, utils.XHRCorsObject);\n};\n\nXhrPollingTransport.prototype = new AjaxBasedTransport();\n\nXhrPollingTransport.enabled = XhrStreamingTransport.enabled;\nXhrPollingTransport.roundTrips = 2; // preflight, ajax\n\n\n// xdr-polling\nvar XdrPollingTransport = SockJS['xdr-polling'] = function(ri, trans_url) {\n this.run(ri, trans_url, '/xhr', XhrReceiver, utils.XDRObject);\n};\n\nXdrPollingTransport.prototype = new AjaxBasedTransport();\n\nXdrPollingTransport.enabled = XdrStreamingTransport.enabled;\nXdrPollingTransport.roundTrips = 2; // preflight, ajax\n// [*] End of lib/trans-xhr.js\n\n\n// [*] Including lib/trans-iframe.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\n// Few cool transports do work only for same-origin. In order to make\n// them working cross-domain we shall use iframe, served form the\n// remote domain. New browsers, have capabilities to communicate with\n// cross domain iframe, using postMessage(). In IE it was implemented\n// from IE 8+, but of course, IE got some details wrong:\n// http://msdn.microsoft.com/en-us/library/cc197015(v=VS.85).aspx\n// http://stevesouders.com/misc/test-postmessage.php\n\nvar IframeTransport = function() {};\n\nIframeTransport.prototype.i_constructor = function(ri, trans_url, base_url) {\n var that = this;\n that.ri = ri;\n that.origin = utils.getOrigin(base_url);\n that.base_url = base_url;\n that.trans_url = trans_url;\n\n var iframe_url = base_url + '/iframe.html';\n if (that.ri._options.devel) {\n iframe_url += '?t=' + (+new Date);\n }\n that.window_id = utils.random_string(8);\n iframe_url += '#' + that.window_id;\n\n that.iframeObj = utils.createIframe(iframe_url, function(r) {\n that.ri._didClose(1006, \"Unable to load an iframe (\" + r + \")\");\n });\n\n that.onmessage_cb = utils.bind(that.onmessage, that);\n utils.attachMessage(that.onmessage_cb);\n};\n\nIframeTransport.prototype.doCleanup = function() {\n var that = this;\n if (that.iframeObj) {\n utils.detachMessage(that.onmessage_cb);\n try {\n // When the iframe is not loaded, IE raises an exception\n // on 'contentWindow'.\n if (that.iframeObj.iframe.contentWindow) {\n that.postMessage('c');\n }\n } catch (x) {}\n that.iframeObj.cleanup();\n that.iframeObj = null;\n that.onmessage_cb = that.iframeObj = null;\n }\n};\n\nIframeTransport.prototype.onmessage = function(e) {\n var that = this;\n if (e.origin !== that.origin) return;\n var window_id = e.data.slice(0, 8);\n var type = e.data.slice(8, 9);\n var data = e.data.slice(9);\n\n if (window_id !== that.window_id) return;\n\n switch(type) {\n case 's':\n that.iframeObj.loaded();\n that.postMessage('s', JSON.stringify([SockJS.version, that.protocol, that.trans_url, that.base_url]));\n break;\n case 't':\n that.ri._didMessage(data);\n break;\n }\n};\n\nIframeTransport.prototype.postMessage = function(type, data) {\n var that = this;\n that.iframeObj.post(that.window_id + type + (data || ''), that.origin);\n};\n\nIframeTransport.prototype.doSend = function (message) {\n this.postMessage('m', message);\n};\n\nIframeTransport.enabled = function() {\n // postMessage misbehaves in konqueror 4.6.5 - the messages are delivered with\n // huge delay, or not at all.\n var konqueror = navigator && navigator.userAgent && navigator.userAgent.indexOf('Konqueror') !== -1;\n return ((typeof _window.postMessage === 'function' ||\n typeof _window.postMessage === 'object') && (!konqueror));\n};\n// [*] End of lib/trans-iframe.js\n\n\n// [*] Including lib/trans-iframe-within.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar curr_window_id;\n\nvar postMessage = function (type, data) {\n if(parent !== _window) {\n parent.postMessage(curr_window_id + type + (data || ''), '*');\n } else {\n utils.log(\"Can't postMessage, no parent window.\", type, data);\n }\n};\n\nvar FacadeJS = function() {};\nFacadeJS.prototype._didClose = function (code, reason) {\n postMessage('t', utils.closeFrame(code, reason));\n};\nFacadeJS.prototype._didMessage = function (frame) {\n postMessage('t', frame);\n};\nFacadeJS.prototype._doSend = function (data) {\n this._transport.doSend(data);\n};\nFacadeJS.prototype._doCleanup = function () {\n this._transport.doCleanup();\n};\n\nutils.parent_origin = undefined;\n\nSockJS.bootstrap_iframe = function() {\n var facade;\n curr_window_id = _document.location.hash.slice(1);\n var onMessage = function(e) {\n if(e.source !== parent) return;\n if(typeof utils.parent_origin === 'undefined')\n utils.parent_origin = e.origin;\n if (e.origin !== utils.parent_origin) return;\n\n var window_id = e.data.slice(0, 8);\n var type = e.data.slice(8, 9);\n var data = e.data.slice(9);\n if (window_id !== curr_window_id) return;\n switch(type) {\n case 's':\n var p = JSON.parse(data);\n var version = p[0];\n var protocol = p[1];\n var trans_url = p[2];\n var base_url = p[3];\n if (version !== SockJS.version) {\n utils.log(\"Incompatibile SockJS! Main site uses:\" +\n \" \\\"\" + version + \"\\\", the iframe:\" +\n \" \\\"\" + SockJS.version + \"\\\".\");\n }\n if (!utils.flatUrl(trans_url) || !utils.flatUrl(base_url)) {\n utils.log(\"Only basic urls are supported in SockJS\");\n return;\n }\n\n if (!utils.isSameOriginUrl(trans_url) ||\n !utils.isSameOriginUrl(base_url)) {\n utils.log(\"Can't connect to different domain from within an \" +\n \"iframe. (\" + JSON.stringify([_window.location.href, trans_url, base_url]) +\n \")\");\n return;\n }\n facade = new FacadeJS();\n facade._transport = new FacadeJS[protocol](facade, trans_url, base_url);\n break;\n case 'm':\n facade._doSend(data);\n break;\n case 'c':\n if (facade)\n facade._doCleanup();\n facade = null;\n break;\n }\n };\n\n // alert('test ticker');\n // facade = new FacadeJS();\n // facade._transport = new FacadeJS['w-iframe-xhr-polling'](facade, 'http://host.com:9999/ticker/12/basd');\n\n utils.attachMessage(onMessage);\n\n // Start\n postMessage('s');\n};\n// [*] End of lib/trans-iframe-within.js\n\n\n// [*] Including lib/info.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar InfoReceiver = function(base_url, AjaxObject) {\n var that = this;\n utils.delay(function(){that.doXhr(base_url, AjaxObject);});\n};\n\nInfoReceiver.prototype = new EventEmitter(['finish']);\n\nInfoReceiver.prototype.doXhr = function(base_url, AjaxObject) {\n var that = this;\n var t0 = (new Date()).getTime();\n\n// <METEOR>\n // https://github.com/sockjs/sockjs-client/pull/129\n // var xo = new AjaxObject('GET', base_url + '/info');\n\n var xo = new AjaxObject(\n // add cachebusting parameter to url to work around a chrome bug:\n // https://code.google.com/p/chromium/issues/detail?id=263981\n // or misbehaving proxies.\n 'GET', base_url + '/info?cb=' + utils.random_string(10))\n// </METEOR>\n\n var tref = utils.delay(8000,\n function(){xo.ontimeout();});\n\n xo.onfinish = function(status, text) {\n clearTimeout(tref);\n tref = null;\n if (status === 200) {\n var rtt = (new Date()).getTime() - t0;\n var info = JSON.parse(text);\n if (typeof info !== 'object') info = {};\n that.emit('finish', info, rtt);\n } else {\n that.emit('finish');\n }\n };\n xo.ontimeout = function() {\n xo.close();\n that.emit('finish');\n };\n};\n\nvar InfoReceiverIframe = function(base_url) {\n var that = this;\n var go = function() {\n var ifr = new IframeTransport();\n ifr.protocol = 'w-iframe-info-receiver';\n var fun = function(r) {\n if (typeof r === 'string' && r.substr(0,1) === 'm') {\n var d = JSON.parse(r.substr(1));\n var info = d[0], rtt = d[1];\n that.emit('finish', info, rtt);\n } else {\n that.emit('finish');\n }\n ifr.doCleanup();\n ifr = null;\n };\n var mock_ri = {\n _options: {},\n _didClose: fun,\n _didMessage: fun\n };\n ifr.i_constructor(mock_ri, base_url, base_url);\n }\n if(!_document.body) {\n utils.attachEvent('load', go);\n } else {\n go();\n }\n};\nInfoReceiverIframe.prototype = new EventEmitter(['finish']);\n\n\nvar InfoReceiverFake = function() {\n // It may not be possible to do cross domain AJAX to get the info\n // data, for example for IE7. But we want to run JSONP, so let's\n // fake the response, with rtt=2s (rto=6s).\n var that = this;\n utils.delay(function() {\n that.emit('finish', {}, 2000);\n });\n};\nInfoReceiverFake.prototype = new EventEmitter(['finish']);\n\nvar createInfoReceiver = function(base_url) {\n if (utils.isSameOriginUrl(base_url)) {\n // If, for some reason, we have SockJS locally - there's no\n // need to start up the complex machinery. Just use ajax.\n return new InfoReceiver(base_url, utils.XHRLocalObject);\n }\n switch (utils.isXHRCorsCapable()) {\n case 1:\n // XHRLocalObject -> no_credentials=true\n return new InfoReceiver(base_url, utils.XHRLocalObject);\n case 2:\n// <METEOR>\n// https://github.com/sockjs/sockjs-client/issues/79\n // XDR doesn't work across different schemes\n // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx\n if (utils.isSameOriginScheme(base_url))\n return new InfoReceiver(base_url, utils.XDRObject);\n else\n return new InfoReceiverFake();\n// </METEOR>\n case 3:\n // Opera\n return new InfoReceiverIframe(base_url);\n default:\n // IE 7\n return new InfoReceiverFake();\n };\n};\n\n\nvar WInfoReceiverIframe = FacadeJS['w-iframe-info-receiver'] = function(ri, _trans_url, base_url) {\n var ir = new InfoReceiver(base_url, utils.XHRLocalObject);\n ir.onfinish = function(info, rtt) {\n ri._didMessage('m'+JSON.stringify([info, rtt]));\n ri._didClose();\n }\n};\nWInfoReceiverIframe.prototype.doCleanup = function() {};\n// [*] End of lib/info.js\n\n\n// [*] Including lib/trans-iframe-eventsource.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar EventSourceIframeTransport = SockJS['iframe-eventsource'] = function () {\n var that = this;\n that.protocol = 'w-iframe-eventsource';\n that.i_constructor.apply(that, arguments);\n};\n\nEventSourceIframeTransport.prototype = new IframeTransport();\n\nEventSourceIframeTransport.enabled = function () {\n return ('EventSource' in _window) && IframeTransport.enabled();\n};\n\nEventSourceIframeTransport.need_body = true;\nEventSourceIframeTransport.roundTrips = 3; // html, javascript, eventsource\n\n\n// w-iframe-eventsource\nvar EventSourceTransport = FacadeJS['w-iframe-eventsource'] = function(ri, trans_url) {\n this.run(ri, trans_url, '/eventsource', EventSourceReceiver, utils.XHRLocalObject);\n}\nEventSourceTransport.prototype = new AjaxBasedTransport();\n// [*] End of lib/trans-iframe-eventsource.js\n\n\n// [*] Including lib/trans-iframe-xhr-polling.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar XhrPollingIframeTransport = SockJS['iframe-xhr-polling'] = function () {\n var that = this;\n that.protocol = 'w-iframe-xhr-polling';\n that.i_constructor.apply(that, arguments);\n};\n\nXhrPollingIframeTransport.prototype = new IframeTransport();\n\nXhrPollingIframeTransport.enabled = function () {\n return _window.XMLHttpRequest && IframeTransport.enabled();\n};\n\nXhrPollingIframeTransport.need_body = true;\nXhrPollingIframeTransport.roundTrips = 3; // html, javascript, xhr\n\n\n// w-iframe-xhr-polling\nvar XhrPollingITransport = FacadeJS['w-iframe-xhr-polling'] = function(ri, trans_url) {\n this.run(ri, trans_url, '/xhr', XhrReceiver, utils.XHRLocalObject);\n};\n\nXhrPollingITransport.prototype = new AjaxBasedTransport();\n// [*] End of lib/trans-iframe-xhr-polling.js\n\n\n// [*] Including lib/trans-iframe-htmlfile.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\n// This transport generally works in any browser, but will cause a\n// spinning cursor to appear in any browser other than IE.\n// We may test this transport in all browsers - why not, but in\n// production it should be only run in IE.\n\nvar HtmlFileIframeTransport = SockJS['iframe-htmlfile'] = function () {\n var that = this;\n that.protocol = 'w-iframe-htmlfile';\n that.i_constructor.apply(that, arguments);\n};\n\n// Inheritance.\nHtmlFileIframeTransport.prototype = new IframeTransport();\n\nHtmlFileIframeTransport.enabled = function() {\n return IframeTransport.enabled();\n};\n\nHtmlFileIframeTransport.need_body = true;\nHtmlFileIframeTransport.roundTrips = 3; // html, javascript, htmlfile\n\n\n// w-iframe-htmlfile\nvar HtmlFileTransport = FacadeJS['w-iframe-htmlfile'] = function(ri, trans_url) {\n this.run(ri, trans_url, '/htmlfile', HtmlfileReceiver, utils.XHRLocalObject);\n};\nHtmlFileTransport.prototype = new AjaxBasedTransport();\n// [*] End of lib/trans-iframe-htmlfile.js\n\n\n// [*] Including lib/trans-polling.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar Polling = function(ri, Receiver, recv_url, AjaxObject) {\n var that = this;\n that.ri = ri;\n that.Receiver = Receiver;\n that.recv_url = recv_url;\n that.AjaxObject = AjaxObject;\n that._scheduleRecv();\n};\n\nPolling.prototype._scheduleRecv = function() {\n var that = this;\n var poll = that.poll = new that.Receiver(that.recv_url, that.AjaxObject);\n var msg_counter = 0;\n poll.onmessage = function(e) {\n msg_counter += 1;\n that.ri._didMessage(e.data);\n };\n poll.onclose = function(e) {\n that.poll = poll = poll.onmessage = poll.onclose = null;\n if (!that.poll_is_closing) {\n if (e.reason === 'permanent') {\n that.ri._didClose(1006, 'Polling error (' + e.reason + ')');\n } else {\n that._scheduleRecv();\n }\n }\n };\n};\n\nPolling.prototype.abort = function() {\n var that = this;\n that.poll_is_closing = true;\n if (that.poll) {\n that.poll.abort();\n }\n};\n// [*] End of lib/trans-polling.js\n\n\n// [*] Including lib/trans-receiver-eventsource.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar EventSourceReceiver = function(url) {\n var that = this;\n var es = new EventSource(url);\n es.onmessage = function(e) {\n that.dispatchEvent(new SimpleEvent('message',\n {'data': unescape(e.data)}));\n };\n that.es_close = es.onerror = function(e, abort_reason) {\n // ES on reconnection has readyState = 0 or 1.\n // on network error it's CLOSED = 2\n var reason = abort_reason ? 'user' :\n (es.readyState !== 2 ? 'network' : 'permanent');\n that.es_close = es.onmessage = es.onerror = null;\n // EventSource reconnects automatically.\n es.close();\n es = null;\n // Safari and chrome < 15 crash if we close window before\n // waiting for ES cleanup. See:\n // https://code.google.com/p/chromium/issues/detail?id=89155\n utils.delay(200, function() {\n that.dispatchEvent(new SimpleEvent('close', {reason: reason}));\n });\n };\n};\n\nEventSourceReceiver.prototype = new REventTarget();\n\nEventSourceReceiver.prototype.abort = function() {\n var that = this;\n if (that.es_close) {\n that.es_close({}, true);\n }\n};\n// [*] End of lib/trans-receiver-eventsource.js\n\n\n// [*] Including lib/trans-receiver-htmlfile.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar _is_ie_htmlfile_capable;\nvar isIeHtmlfileCapable = function() {\n if (_is_ie_htmlfile_capable === undefined) {\n if ('ActiveXObject' in _window) {\n try {\n _is_ie_htmlfile_capable = !!new ActiveXObject('htmlfile');\n } catch (x) {}\n } else {\n _is_ie_htmlfile_capable = false;\n }\n }\n return _is_ie_htmlfile_capable;\n};\n\n\nvar HtmlfileReceiver = function(url) {\n var that = this;\n utils.polluteGlobalNamespace();\n\n that.id = 'a' + utils.random_string(6, 26);\n url += ((url.indexOf('?') === -1) ? '?' : '&') +\n 'c=' + escape(WPrefix + '.' + that.id);\n\n var constructor = isIeHtmlfileCapable() ?\n utils.createHtmlfile : utils.createIframe;\n\n var iframeObj;\n _window[WPrefix][that.id] = {\n start: function () {\n iframeObj.loaded();\n },\n message: function (data) {\n that.dispatchEvent(new SimpleEvent('message', {'data': data}));\n },\n stop: function () {\n that.iframe_close({}, 'network');\n }\n };\n that.iframe_close = function(e, abort_reason) {\n iframeObj.cleanup();\n that.iframe_close = iframeObj = null;\n delete _window[WPrefix][that.id];\n that.dispatchEvent(new SimpleEvent('close', {reason: abort_reason}));\n };\n iframeObj = constructor(url, function(e) {\n that.iframe_close({}, 'permanent');\n });\n};\n\nHtmlfileReceiver.prototype = new REventTarget();\n\nHtmlfileReceiver.prototype.abort = function() {\n var that = this;\n if (that.iframe_close) {\n that.iframe_close({}, 'user');\n }\n};\n// [*] End of lib/trans-receiver-htmlfile.js\n\n\n// [*] Including lib/trans-receiver-xhr.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\nvar XhrReceiver = function(url, AjaxObject) {\n var that = this;\n var buf_pos = 0;\n\n that.xo = new AjaxObject('POST', url, null);\n that.xo.onchunk = function(status, text) {\n if (status !== 200) return;\n while (1) {\n var buf = text.slice(buf_pos);\n var p = buf.indexOf('\\n');\n if (p === -1) break;\n buf_pos += p+1;\n var msg = buf.slice(0, p);\n that.dispatchEvent(new SimpleEvent('message', {data: msg}));\n }\n };\n that.xo.onfinish = function(status, text) {\n that.xo.onchunk(status, text);\n that.xo = null;\n var reason = status === 200 ? 'network' : 'permanent';\n that.dispatchEvent(new SimpleEvent('close', {reason: reason}));\n }\n};\n\nXhrReceiver.prototype = new REventTarget();\n\nXhrReceiver.prototype.abort = function() {\n var that = this;\n if (that.xo) {\n that.xo.close();\n that.dispatchEvent(new SimpleEvent('close', {reason: 'user'}));\n that.xo = null;\n }\n};\n// [*] End of lib/trans-receiver-xhr.js\n\n\n// [*] Including lib/test-hooks.js\n/*\n * ***** BEGIN LICENSE BLOCK *****\n * Copyright (c) 2011-2012 VMware, Inc.\n *\n * For the license see COPYING.\n * ***** END LICENSE BLOCK *****\n */\n\n// For testing\nSockJS.getUtils = function(){\n return utils;\n};\n\nSockJS.getIframeTransport = function(){\n return IframeTransport;\n};\n// [*] End of lib/test-hooks.js\n\n return SockJS;\n })();\nif ('_sockjs_onload' in window) setTimeout(_sockjs_onload, 1);\n\n// AMD compliance\nif (typeof define === 'function' && define.amd) {\n define('sockjs', [], function(){return SockJS;});\n}\n// [*] End of lib/index.js\n\n// [*] End of lib/all.js\n","// @param url {String} URL to Meteor app\n// \"http://subdomain.meteor.com/\" or \"/\" or\n// \"ddp+sockjs://foo-**.meteor.com/sockjs\"\nLivedataTest.ClientStream = function (url, options) {\n var self = this;\n self.options = _.extend({\n retry: true\n }, options);\n self._initCommon(self.options);\n\n //// Constants\n\n\n // how long between hearing heartbeat from the server until we declare\n // the connection dead. heartbeats come every 45s (stream_server.js)\n //\n // NOTE: this is a older timeout mechanism. We now send heartbeats at\n // the DDP level (https://github.com/meteor/meteor/pull/1865), and\n // expect those timeouts to kill a non-responsive connection before\n // this timeout fires. This is kept around for compatibility (when\n // talking to a server that doesn't support DDP heartbeats) and can be\n // removed later.\n self.HEARTBEAT_TIMEOUT = 100*1000;\n\n self.rawUrl = url;\n self.socket = null;\n\n self.heartbeatTimer = null;\n\n // Listen to global 'online' event if we are running in a browser.\n // (IE8 does not support addEventListener)\n if (typeof window !== 'undefined' && window.addEventListener)\n window.addEventListener(\"online\", _.bind(self._online, self),\n false /* useCapture. make FF3.6 happy. */);\n\n //// Kickoff!\n self._launchConnection();\n};\n\n_.extend(LivedataTest.ClientStream.prototype, {\n\n // data is a utf8 string. Data sent while not connected is dropped on\n // the floor, and it is up the user of this API to retransmit lost\n // messages on 'reset'\n send: function (data) {\n var self = this;\n if (self.currentStatus.connected) {\n self.socket.send(data);\n }\n },\n\n // Changes where this connection points\n _changeUrl: function (url) {\n var self = this;\n self.rawUrl = url;\n },\n\n _connected: function () {\n var self = this;\n\n if (self.connectionTimer) {\n clearTimeout(self.connectionTimer);\n self.connectionTimer = null;\n }\n\n if (self.currentStatus.connected) {\n // already connected. do nothing. this probably shouldn't happen.\n return;\n }\n\n // update status\n self.currentStatus.status = \"connected\";\n self.currentStatus.connected = true;\n self.currentStatus.retryCount = 0;\n self.statusChanged();\n\n // fire resets. This must come after status change so that clients\n // can call send from within a reset callback.\n _.each(self.eventCallbacks.reset, function (callback) { callback(); });\n\n },\n\n _cleanup: function (maybeError) {\n var self = this;\n\n self._clearConnectionAndHeartbeatTimers();\n if (self.socket) {\n self.socket.onmessage = self.socket.onclose\n = self.socket.onerror = self.socket.onheartbeat = function () {};\n self.socket.close();\n self.socket = null;\n }\n\n _.each(self.eventCallbacks.disconnect, function (callback) {\n callback(maybeError);\n });\n },\n\n _clearConnectionAndHeartbeatTimers: function () {\n var self = this;\n if (self.connectionTimer) {\n clearTimeout(self.connectionTimer);\n self.connectionTimer = null;\n }\n if (self.heartbeatTimer) {\n clearTimeout(self.heartbeatTimer);\n self.heartbeatTimer = null;\n }\n },\n\n _heartbeat_timeout: function () {\n var self = this;\n Meteor._debug(\"Connection timeout. No sockjs heartbeat received.\");\n self._lostConnection(new DDP.ConnectionError(\"Heartbeat timed out\"));\n },\n\n _heartbeat_received: function () {\n var self = this;\n // If we've already permanently shut down this stream, the timeout is\n // already cleared, and we don't need to set it again.\n if (self._forcedToDisconnect)\n return;\n if (self.heartbeatTimer)\n clearTimeout(self.heartbeatTimer);\n self.heartbeatTimer = setTimeout(\n _.bind(self._heartbeat_timeout, self),\n self.HEARTBEAT_TIMEOUT);\n },\n\n _sockjsProtocolsWhitelist: function () {\n // only allow polling protocols. no streaming. streaming\n // makes safari spin.\n var protocolsWhitelist = [\n 'xdr-polling', 'xhr-polling', 'iframe-xhr-polling', 'jsonp-polling'];\n\n // iOS 4 and 5 and below crash when using websockets over certain\n // proxies. this seems to be resolved with iOS 6. eg\n // https://github.com/LearnBoost/socket.io/issues/193#issuecomment-7308865.\n //\n // iOS <4 doesn't support websockets at all so sockjs will just\n // immediately fall back to http\n var noWebsockets = navigator &&\n /iPhone|iPad|iPod/.test(navigator.userAgent) &&\n /OS 4_|OS 5_/.test(navigator.userAgent);\n\n if (!noWebsockets)\n protocolsWhitelist = ['websocket'].concat(protocolsWhitelist);\n\n return protocolsWhitelist;\n },\n\n _launchConnection: function () {\n var self = this;\n self._cleanup(); // cleanup the old socket, if there was one.\n\n var options = _.extend({\n protocols_whitelist:self._sockjsProtocolsWhitelist()\n }, self.options._sockjsOptions);\n\n // Convert raw URL to SockJS URL each time we open a connection, so that we\n // can connect to random hostnames and get around browser per-host\n // connection limits.\n self.socket = new SockJS(toSockjsUrl(self.rawUrl), undefined, options);\n self.socket.onopen = function (data) {\n self._connected();\n };\n self.socket.onmessage = function (data) {\n self._heartbeat_received();\n\n if (self.currentStatus.connected)\n _.each(self.eventCallbacks.message, function (callback) {\n callback(data.data);\n });\n };\n self.socket.onclose = function () {\n self._lostConnection();\n };\n self.socket.onerror = function () {\n // XXX is this ever called?\n Meteor._debug(\"stream error\", _.toArray(arguments), (new Date()).toDateString());\n };\n\n self.socket.onheartbeat = function () {\n self._heartbeat_received();\n };\n\n if (self.connectionTimer)\n clearTimeout(self.connectionTimer);\n self.connectionTimer = setTimeout(function () {\n self._lostConnection(\n new DDP.ConnectionError(\"DDP connection timed out\"));\n }, self.CONNECT_TIMEOUT);\n }\n});\n","// XXX from Underscore.String (http://epeli.github.com/underscore.string/)\nvar startsWith = function(str, starts) {\n return str.length >= starts.length &&\n str.substring(0, starts.length) === starts;\n};\nvar endsWith = function(str, ends) {\n return str.length >= ends.length &&\n str.substring(str.length - ends.length) === ends;\n};\n\n// @param url {String} URL to Meteor app, eg:\n// \"/\" or \"madewith.meteor.com\" or \"https://foo.meteor.com\"\n// or \"ddp+sockjs://ddp--****-foo.meteor.com/sockjs\"\n// @returns {String} URL to the endpoint with the specific scheme and subPath, e.g.\n// for scheme \"http\" and subPath \"sockjs\"\n// \"http://subdomain.meteor.com/sockjs\" or \"/sockjs\"\n// or \"https://ddp--1234-foo.meteor.com/sockjs\"\nvar translateUrl = function(url, newSchemeBase, subPath) {\n if (! newSchemeBase) {\n newSchemeBase = \"http\";\n }\n\n var ddpUrlMatch = url.match(/^ddp(i?)\\+sockjs:\\/\\//);\n var httpUrlMatch = url.match(/^http(s?):\\/\\//);\n var newScheme;\n if (ddpUrlMatch) {\n // Remove scheme and split off the host.\n var urlAfterDDP = url.substr(ddpUrlMatch[0].length);\n newScheme = ddpUrlMatch[1] === \"i\" ? newSchemeBase : newSchemeBase + \"s\";\n var slashPos = urlAfterDDP.indexOf('/');\n var host =\n slashPos === -1 ? urlAfterDDP : urlAfterDDP.substr(0, slashPos);\n var rest = slashPos === -1 ? '' : urlAfterDDP.substr(slashPos);\n\n // In the host (ONLY!), change '*' characters into random digits. This\n // allows different stream connections to connect to different hostnames\n // and avoid browser per-hostname connection limits.\n host = host.replace(/\\*/g, function () {\n return Math.floor(Random.fraction()*10);\n });\n\n return newScheme + '://' + host + rest;\n } else if (httpUrlMatch) {\n newScheme = !httpUrlMatch[1] ? newSchemeBase : newSchemeBase + \"s\";\n var urlAfterHttp = url.substr(httpUrlMatch[0].length);\n url = newScheme + \"://\" + urlAfterHttp;\n }\n\n // Prefix FQDNs but not relative URLs\n if (url.indexOf(\"://\") === -1 && !startsWith(url, \"/\")) {\n url = newSchemeBase + \"://\" + url;\n }\n\n // XXX This is not what we should be doing: if I have a site\n // deployed at \"/foo\", then DDP.connect(\"/\") should actually connect\n // to \"/\", not to \"/foo\". \"/\" is an absolute path. (Contrast: if\n // deployed at \"/foo\", it would be reasonable for DDP.connect(\"bar\")\n // to connect to \"/foo/bar\").\n //\n // We should make this properly honor absolute paths rather than\n // forcing the path to be relative to the site root. Simultaneously,\n // we should set DDP_DEFAULT_CONNECTION_URL to include the site\n // root. See also client_convenience.js #RationalizingRelativeDDPURLs\n url = Meteor._relativeToSiteRootUrl(url);\n\n if (endsWith(url, \"/\"))\n return url + subPath;\n else\n return url + \"/\" + subPath;\n};\n\ntoSockjsUrl = function (url) {\n return translateUrl(url, \"http\", \"sockjs\");\n};\n\ntoWebsocketUrl = function (url) {\n var ret = translateUrl(url, \"ws\", \"websocket\");\n return ret;\n};\n\nLivedataTest.toSockjsUrl = toSockjsUrl;\n\n\n_.extend(LivedataTest.ClientStream.prototype, {\n\n // Register for callbacks.\n on: function (name, callback) {\n var self = this;\n\n if (name !== 'message' && name !== 'reset' && name !== 'disconnect')\n throw new Error(\"unknown event type: \" + name);\n\n if (!self.eventCallbacks[name])\n self.eventCallbacks[name] = [];\n self.eventCallbacks[name].push(callback);\n },\n\n\n _initCommon: function (options) {\n var self = this;\n options = options || {};\n\n //// Constants\n\n // how long to wait until we declare the connection attempt\n // failed.\n self.CONNECT_TIMEOUT = options.connectTimeoutMs || 10000;\n\n self.eventCallbacks = {}; // name -> [callback]\n\n self._forcedToDisconnect = false;\n\n //// Reactive status\n self.currentStatus = {\n status: \"connecting\",\n connected: false,\n retryCount: 0\n };\n\n\n self.statusListeners = typeof Tracker !== 'undefined' && new Tracker.Dependency;\n self.statusChanged = function () {\n if (self.statusListeners)\n self.statusListeners.changed();\n };\n\n //// Retry logic\n self._retry = new Retry;\n self.connectionTimer = null;\n\n },\n\n // Trigger a reconnect.\n reconnect: function (options) {\n var self = this;\n options = options || {};\n\n if (options.url) {\n self._changeUrl(options.url);\n }\n\n if (options._sockjsOptions) {\n self.options._sockjsOptions = options._sockjsOptions;\n }\n\n if (self.currentStatus.connected) {\n if (options._force || options.url) {\n // force reconnect.\n self._lostConnection(new DDP.ForcedReconnectError);\n } // else, noop.\n return;\n }\n\n // if we're mid-connection, stop it.\n if (self.currentStatus.status === \"connecting\") {\n // Pretend it's a clean close.\n self._lostConnection();\n }\n\n self._retry.clear();\n self.currentStatus.retryCount -= 1; // don't count manual retries\n self._retryNow();\n },\n\n disconnect: function (options) {\n var self = this;\n options = options || {};\n\n // Failed is permanent. If we're failed, don't let people go back\n // online by calling 'disconnect' then 'reconnect'.\n if (self._forcedToDisconnect)\n return;\n\n // If _permanent is set, permanently disconnect a stream. Once a stream\n // is forced to disconnect, it can never reconnect. This is for\n // error cases such as ddp version mismatch, where trying again\n // won't fix the problem.\n if (options._permanent) {\n self._forcedToDisconnect = true;\n }\n\n self._cleanup();\n self._retry.clear();\n\n self.currentStatus = {\n status: (options._permanent ? \"failed\" : \"offline\"),\n connected: false,\n retryCount: 0\n };\n\n if (options._permanent && options._error)\n self.currentStatus.reason = options._error;\n\n self.statusChanged();\n },\n\n // maybeError is set unless it's a clean protocol-level close.\n _lostConnection: function (maybeError) {\n var self = this;\n\n self._cleanup(maybeError);\n self._retryLater(maybeError); // sets status. no need to do it here.\n },\n\n // fired when we detect that we've gone online. try to reconnect\n // immediately.\n _online: function () {\n // if we've requested to be offline by disconnecting, don't reconnect.\n if (this.currentStatus.status != \"offline\")\n this.reconnect();\n },\n\n _retryLater: function (maybeError) {\n var self = this;\n\n var timeout = 0;\n if (self.options.retry ||\n (maybeError && maybeError.errorType === \"DDP.ForcedReconnectError\")) {\n timeout = self._retry.retryLater(\n self.currentStatus.retryCount,\n _.bind(self._retryNow, self)\n );\n self.currentStatus.status = \"waiting\";\n self.currentStatus.retryTime = (new Date()).getTime() + timeout;\n } else {\n self.currentStatus.status = \"failed\";\n delete self.currentStatus.retryTime;\n }\n\n self.currentStatus.connected = false;\n self.statusChanged();\n },\n\n _retryNow: function () {\n var self = this;\n\n if (self._forcedToDisconnect)\n return;\n\n self.currentStatus.retryCount += 1;\n self.currentStatus.status = \"connecting\";\n self.currentStatus.connected = false;\n delete self.currentStatus.retryTime;\n self.statusChanged();\n\n self._launchConnection();\n },\n\n\n // Get current status. Reactive.\n status: function () {\n var self = this;\n if (self.statusListeners)\n self.statusListeners.depend();\n return self.currentStatus;\n }\n});\n\nDDP.ConnectionError = Meteor.makeErrorType(\n \"DDP.ConnectionError\", function (message) {\n var self = this;\n self.message = message;\n});\n\nDDP.ForcedReconnectError = Meteor.makeErrorType(\n \"DDP.ForcedReconnectError\", function () {});\n","// Heartbeat options:\n// heartbeatInterval: interval to send pings, in milliseconds.\n// heartbeatTimeout: timeout to close the connection if a reply isn't\n// received, in milliseconds.\n// sendPing: function to call to send a ping on the connection.\n// onTimeout: function to call to close the connection.\n\nHeartbeat = function (options) {\n var self = this;\n\n self.heartbeatInterval = options.heartbeatInterval;\n self.heartbeatTimeout = options.heartbeatTimeout;\n self._sendPing = options.sendPing;\n self._onTimeout = options.onTimeout;\n\n self._heartbeatIntervalHandle = null;\n self._heartbeatTimeoutHandle = null;\n};\n\n_.extend(Heartbeat.prototype, {\n stop: function () {\n var self = this;\n self._clearHeartbeatIntervalTimer();\n self._clearHeartbeatTimeoutTimer();\n },\n\n start: function () {\n var self = this;\n self.stop();\n self._startHeartbeatIntervalTimer();\n },\n\n _startHeartbeatIntervalTimer: function () {\n var self = this;\n self._heartbeatIntervalHandle = Meteor.setTimeout(\n _.bind(self._heartbeatIntervalFired, self),\n self.heartbeatInterval\n );\n },\n\n _startHeartbeatTimeoutTimer: function () {\n var self = this;\n self._heartbeatTimeoutHandle = Meteor.setTimeout(\n _.bind(self._heartbeatTimeoutFired, self),\n self.heartbeatTimeout\n );\n },\n\n _clearHeartbeatIntervalTimer: function () {\n var self = this;\n if (self._heartbeatIntervalHandle) {\n Meteor.clearTimeout(self._heartbeatIntervalHandle);\n self._heartbeatIntervalHandle = null;\n }\n },\n\n _clearHeartbeatTimeoutTimer: function () {\n var self = this;\n if (self._heartbeatTimeoutHandle) {\n Meteor.clearTimeout(self._heartbeatTimeoutHandle);\n self._heartbeatTimeoutHandle = null;\n }\n },\n\n // The heartbeat interval timer is fired when we should send a ping.\n _heartbeatIntervalFired: function () {\n var self = this;\n self._heartbeatIntervalHandle = null;\n self._sendPing();\n // Wait for a pong.\n self._startHeartbeatTimeoutTimer();\n },\n\n // The heartbeat timeout timer is fired when we sent a ping, but we\n // timed out waiting for the pong.\n _heartbeatTimeoutFired: function () {\n var self = this;\n self._heartbeatTimeoutHandle = null;\n self._onTimeout();\n },\n\n pingReceived: function () {\n var self = this;\n // We know the connection is alive if we receive a ping, so we\n // don't need to send a ping ourselves. Reset the interval timer.\n if (self._heartbeatIntervalHandle) {\n self._clearHeartbeatIntervalTimer();\n self._startHeartbeatIntervalTimer();\n }\n },\n\n pongReceived: function () {\n var self = this;\n\n // Receiving a pong means we won't timeout, so clear the timeout\n // timer and start the interval again.\n if (self._heartbeatTimeoutHandle) {\n self._clearHeartbeatTimeoutTimer();\n self._startHeartbeatIntervalTimer();\n }\n }\n});\n","// All the supported versions (for both the client and server)\n// These must be in order of preference; most favored-first\nSUPPORTED_DDP_VERSIONS = [ '1', 'pre2', 'pre1' ];\n\nLivedataTest.SUPPORTED_DDP_VERSIONS = SUPPORTED_DDP_VERSIONS;\n\n// Instance name is this because it is usually referred to as this inside a\n// method definition\n/**\n * @summary The state for a single invocation of a method, referenced by this\n * inside a method definition.\n * @param {Object} options\n * @instanceName this\n */\nMethodInvocation = function (options) {\n var self = this;\n\n // true if we're running not the actual method, but a stub (that is,\n // if we're on a client (which may be a browser, or in the future a\n // server connecting to another server) and presently running a\n // simulation of a server-side method for latency compensation\n // purposes). not currently true except in a client such as a browser,\n // since there's usually no point in running stubs unless you have a\n // zero-latency connection to the user.\n\n /**\n * @summary Access inside a method invocation. Boolean value, true if this invocation is a stub.\n * @locus Anywhere\n * @name isSimulation\n * @memberOf MethodInvocation\n * @instance\n * @type {Boolean}\n */\n this.isSimulation = options.isSimulation;\n\n // call this function to allow other method invocations (from the\n // same client) to continue running without waiting for this one to\n // complete.\n this._unblock = options.unblock || function () {};\n this._calledUnblock = false;\n\n // current user id\n\n /**\n * @summary The id of the user that made this method call, or `null` if no user was logged in.\n * @locus Anywhere\n * @name userId\n * @memberOf MethodInvocation\n * @instance\n */\n this.userId = options.userId;\n\n // sets current user id in all appropriate server contexts and\n // reruns subscriptions\n this._setUserId = options.setUserId || function () {};\n\n // On the server, the connection this method call came in on.\n\n /**\n * @summary Access inside a method invocation. The [connection](#meteor_onconnection) that this method was received on. `null` if the method is not associated with a connection, eg. a server initiated method call.\n * @locus Server\n * @name connection\n * @memberOf MethodInvocation\n * @instance\n */\n this.connection = options.connection;\n\n // The seed for randomStream value generation\n this.randomSeed = options.randomSeed;\n\n // This is set by RandomStream.get; and holds the random stream state\n this.randomStream = null;\n};\n\n_.extend(MethodInvocation.prototype, {\n /**\n * @summary Call inside a method invocation. Allow subsequent method from this client to begin running in a new fiber.\n * @locus Server\n * @memberOf MethodInvocation\n * @instance\n */\n unblock: function () {\n var self = this;\n self._calledUnblock = true;\n self._unblock();\n },\n\n /**\n * @summary Set the logged in user.\n * @locus Server\n * @memberOf MethodInvocation\n * @instance\n * @param {String | null} userId The value that should be returned by `userId` on this connection.\n */\n setUserId: function(userId) {\n var self = this;\n if (self._calledUnblock)\n throw new Error(\"Can't call setUserId in a method after calling unblock\");\n self.userId = userId;\n self._setUserId(userId);\n }\n});\n\nparseDDP = function (stringMessage) {\n try {\n var msg = JSON.parse(stringMessage);\n } catch (e) {\n Meteor._debug(\"Discarding message with invalid JSON\", stringMessage);\n return null;\n }\n // DDP messages must be objects.\n if (msg === null || typeof msg !== 'object') {\n Meteor._debug(\"Discarding non-object DDP message\", stringMessage);\n return null;\n }\n\n // massage msg to get it into \"abstract ddp\" rather than \"wire ddp\" format.\n\n // switch between \"cleared\" rep of unsetting fields and \"undefined\"\n // rep of same\n if (_.has(msg, 'cleared')) {\n if (!_.has(msg, 'fields'))\n msg.fields = {};\n _.each(msg.cleared, function (clearKey) {\n msg.fields[clearKey] = undefined;\n });\n delete msg.cleared;\n }\n\n _.each(['fields', 'params', 'result'], function (field) {\n if (_.has(msg, field))\n msg[field] = EJSON._adjustTypesFromJSONValue(msg[field]);\n });\n\n return msg;\n};\n\nstringifyDDP = function (msg) {\n var copy = EJSON.clone(msg);\n // swizzle 'changed' messages from 'fields undefined' rep to 'fields\n // and cleared' rep\n if (_.has(msg, 'fields')) {\n var cleared = [];\n _.each(msg.fields, function (value, key) {\n if (value === undefined) {\n cleared.push(key);\n delete copy.fields[key];\n }\n });\n if (!_.isEmpty(cleared))\n copy.cleared = cleared;\n if (_.isEmpty(copy.fields))\n delete copy.fields;\n }\n // adjust types to basic\n _.each(['fields', 'params', 'result'], function (field) {\n if (_.has(copy, field))\n copy[field] = EJSON._adjustTypesToJSONValue(copy[field]);\n });\n if (msg.id && typeof msg.id !== 'string') {\n throw new Error(\"Message id is not a string\");\n }\n return JSON.stringify(copy);\n};\n\n// This is private but it's used in a few places. accounts-base uses\n// it to get the current user. accounts-password uses it to stash SRP\n// state in the DDP session. Meteor.setTimeout and friends clear\n// it. We can probably find a better way to factor this.\nDDP._CurrentInvocation = new Meteor.EnvironmentVariable;\n","// RandomStream allows for generation of pseudo-random values, from a seed.\n//\n// We use this for consistent 'random' numbers across the client and server.\n// We want to generate probably-unique IDs on the client, and we ideally want\n// the server to generate the same IDs when it executes the method.\n//\n// For generated values to be the same, we must seed ourselves the same way,\n// and we must keep track of the current state of our pseudo-random generators.\n// We call this state the scope. By default, we use the current DDP method\n// invocation as our scope. DDP now allows the client to specify a randomSeed.\n// If a randomSeed is provided it will be used to seed our random sequences.\n// In this way, client and server method calls will generate the same values.\n//\n// We expose multiple named streams; each stream is independent\n// and is seeded differently (but predictably from the name).\n// By using multiple streams, we support reordering of requests,\n// as long as they occur on different streams.\n//\n// @param options {Optional Object}\n// seed: Array or value - Seed value(s) for the generator.\n// If an array, will be used as-is\n// If a value, will be converted to a single-value array\n// If omitted, a random array will be used as the seed.\nRandomStream = function (options) {\n var self = this;\n\n this.seed = [].concat(options.seed || randomToken());\n\n this.sequences = {};\n};\n\n// Returns a random string of sufficient length for a random seed.\n// This is a placeholder function; a similar function is planned\n// for Random itself; when that is added we should remove this function,\n// and call Random's randomToken instead.\nfunction randomToken() {\n return Random.hexString(20);\n};\n\n// Returns the random stream with the specified name, in the specified scope.\n// If scope is null (or otherwise falsey) then we will use Random, which will\n// give us as random numbers as possible, but won't produce the same\n// values across client and server.\n// However, scope will normally be the current DDP method invocation, so\n// we'll use the stream with the specified name, and we should get consistent\n// values on the client and server sides of a method call.\nRandomStream.get = function (scope, name) {\n if (!name) {\n name = \"default\";\n }\n if (!scope) {\n // There was no scope passed in;\n // the sequence won't actually be reproducible.\n return Random;\n }\n var randomStream = scope.randomStream;\n if (!randomStream) {\n scope.randomStream = randomStream = new RandomStream({\n seed: scope.randomSeed\n });\n }\n return randomStream._sequence(name);\n};\n\n// Returns the named sequence of pseudo-random values.\n// The scope will be DDP._CurrentInvocation.get(), so the stream will produce\n// consistent values for method calls on the client and server.\nDDP.randomStream = function (name) {\n var scope = DDP._CurrentInvocation.get();\n return RandomStream.get(scope, name);\n};\n\n// Creates a randomSeed for passing to a method call.\n// Note that we take enclosing as an argument,\n// though we expect it to be DDP._CurrentInvocation.get()\n// However, we often evaluate makeRpcSeed lazily, and thus the relevant\n// invocation may not be the one currently in scope.\n// If enclosing is null, we'll use Random and values won't be repeatable.\nmakeRpcSeed = function (enclosing, methodName) {\n var stream = RandomStream.get(enclosing, '/rpc/' + methodName);\n return stream.hexString(20);\n};\n\n_.extend(RandomStream.prototype, {\n // Get a random sequence with the specified name, creating it if does not exist.\n // New sequences are seeded with the seed concatenated with the name.\n // By passing a seed into Random.create, we use the Alea generator.\n _sequence: function (name) {\n var self = this;\n\n var sequence = self.sequences[name] || null;\n if (sequence === null) {\n var sequenceSeed = self.seed.concat(name);\n for (var i = 0; i < sequenceSeed.length; i++) {\n if (_.isFunction(sequenceSeed[i])) {\n sequenceSeed[i] = sequenceSeed[i]();\n }\n }\n self.sequences[name] = sequence = Random.createWithSeeds.apply(null, sequenceSeed);\n }\n return sequence;\n }\n});\n","if (Meteor.isServer) {\n var path = Npm.require('path');\n var Fiber = Npm.require('fibers');\n var Future = Npm.require(path.join('fibers', 'future'));\n}\n\n// @param url {String|Object} URL to Meteor app,\n// or an object as a test hook (see code)\n// Options:\n// reloadWithOutstanding: is it OK to reload if there are outstanding methods?\n// headers: extra headers to send on the websockets connection, for\n// server-to-server DDP only\n// _sockjsOptions: Specifies options to pass through to the sockjs client\n// onDDPNegotiationVersionFailure: callback when version negotiation fails.\n//\n// XXX There should be a way to destroy a DDP connection, causing all\n// outstanding method calls to fail.\n//\n// XXX Our current way of handling failure and reconnection is great\n// for an app (where we want to tolerate being disconnected as an\n// expect state, and keep trying forever to reconnect) but cumbersome\n// for something like a command line tool that wants to make a\n// connection, call a method, and print an error if connection\n// fails. We should have better usability in the latter case (while\n// still transparently reconnecting if it's just a transient failure\n// or the server migrating us).\nvar Connection = function (url, options) {\n var self = this;\n options = _.extend({\n onConnected: function () {},\n onDDPVersionNegotiationFailure: function (description) {\n Meteor._debug(description);\n },\n heartbeatInterval: 35000,\n heartbeatTimeout: 15000,\n // These options are only for testing.\n reloadWithOutstanding: false,\n supportedDDPVersions: SUPPORTED_DDP_VERSIONS,\n retry: true,\n respondToPings: true\n }, options);\n\n // If set, called when we reconnect, queuing method calls _before_ the\n // existing outstanding ones. This is the only data member that is part of the\n // public API!\n self.onReconnect = null;\n\n // as a test hook, allow passing a stream instead of a url.\n if (typeof url === \"object\") {\n self._stream = url;\n } else {\n self._stream = new LivedataTest.ClientStream(url, {\n retry: options.retry,\n headers: options.headers,\n _sockjsOptions: options._sockjsOptions,\n // Used to keep some tests quiet, or for other cases in which\n // the right thing to do with connection errors is to silently\n // fail (e.g. sending package usage stats). At some point we\n // should have a real API for handling client-stream-level\n // errors.\n _dontPrintErrors: options._dontPrintErrors,\n connectTimeoutMs: options.connectTimeoutMs\n });\n }\n\n self._lastSessionId = null;\n self._versionSuggestion = null; // The last proposed DDP version.\n self._version = null; // The DDP version agreed on by client and server.\n self._stores = {}; // name -> object with methods\n self._methodHandlers = {}; // name -> func\n self._nextMethodId = 1;\n self._supportedDDPVersions = options.supportedDDPVersions;\n\n self._heartbeatInterval = options.heartbeatInterval;\n self._heartbeatTimeout = options.heartbeatTimeout;\n\n // Tracks methods which the user has tried to call but which have not yet\n // called their user callback (ie, they are waiting on their result or for all\n // of their writes to be written to the local cache). Map from method ID to\n // MethodInvoker object.\n self._methodInvokers = {};\n\n // Tracks methods which the user has called but whose result messages have not\n // arrived yet.\n //\n // _outstandingMethodBlocks is an array of blocks of methods. Each block\n // represents a set of methods that can run at the same time. The first block\n // represents the methods which are currently in flight; subsequent blocks\n // must wait for previous blocks to be fully finished before they can be sent\n // to the server.\n //\n // Each block is an object with the following fields:\n // - methods: a list of MethodInvoker objects\n // - wait: a boolean; if true, this block had a single method invoked with\n // the \"wait\" option\n //\n // There will never be adjacent blocks with wait=false, because the only thing\n // that makes methods need to be serialized is a wait method.\n //\n // Methods are removed from the first block when their \"result\" is\n // received. The entire first block is only removed when all of the in-flight\n // methods have received their results (so the \"methods\" list is empty) *AND*\n // all of the data written by those methods are visible in the local cache. So\n // it is possible for the first block's methods list to be empty, if we are\n // still waiting for some objects to quiesce.\n //\n // Example:\n // _outstandingMethodBlocks = [\n // {wait: false, methods: []},\n // {wait: true, methods: [<MethodInvoker for 'login'>]},\n // {wait: false, methods: [<MethodInvoker for 'foo'>,\n // <MethodInvoker for 'bar'>]}]\n // This means that there were some methods which were sent to the server and\n // which have returned their results, but some of the data written by\n // the methods may not be visible in the local cache. Once all that data is\n // visible, we will send a 'login' method. Once the login method has returned\n // and all the data is visible (including re-running subs if userId changes),\n // we will send the 'foo' and 'bar' methods in parallel.\n self._outstandingMethodBlocks = [];\n\n // method ID -> array of objects with keys 'collection' and 'id', listing\n // documents written by a given method's stub. keys are associated with\n // methods whose stub wrote at least one document, and whose data-done message\n // has not yet been received.\n self._documentsWrittenByStub = {};\n // collection -> IdMap of \"server document\" object. A \"server document\" has:\n // - \"document\": the version of the document according the\n // server (ie, the snapshot before a stub wrote it, amended by any changes\n // received from the server)\n // It is undefined if we think the document does not exist\n // - \"writtenByStubs\": a set of method IDs whose stubs wrote to the document\n // whose \"data done\" messages have not yet been processed\n self._serverDocuments = {};\n\n // Array of callbacks to be called after the next update of the local\n // cache. Used for:\n // - Calling methodInvoker.dataVisible and sub ready callbacks after\n // the relevant data is flushed.\n // - Invoking the callbacks of \"half-finished\" methods after reconnect\n // quiescence. Specifically, methods whose result was received over the old\n // connection (so we don't re-send it) but whose data had not been made\n // visible.\n self._afterUpdateCallbacks = [];\n\n // In two contexts, we buffer all incoming data messages and then process them\n // all at once in a single update:\n // - During reconnect, we buffer all data messages until all subs that had\n // been ready before reconnect are ready again, and all methods that are\n // active have returned their \"data done message\"; then\n // - During the execution of a \"wait\" method, we buffer all data messages\n // until the wait method gets its \"data done\" message. (If the wait method\n // occurs during reconnect, it doesn't get any special handling.)\n // all data messages are processed in one update.\n //\n // The following fields are used for this \"quiescence\" process.\n\n // This buffers the messages that aren't being processed yet.\n self._messagesBufferedUntilQuiescence = [];\n // Map from method ID -> true. Methods are removed from this when their\n // \"data done\" message is received, and we will not quiesce until it is\n // empty.\n self._methodsBlockingQuiescence = {};\n // map from sub ID -> true for subs that were ready (ie, called the sub\n // ready callback) before reconnect but haven't become ready again yet\n self._subsBeingRevived = {}; // map from sub._id -> true\n // if true, the next data update should reset all stores. (set during\n // reconnect.)\n self._resetStores = false;\n\n // name -> array of updates for (yet to be created) collections\n self._updatesForUnknownStores = {};\n // if we're blocking a migration, the retry func\n self._retryMigrate = null;\n\n // metadata for subscriptions. Map from sub ID to object with keys:\n // - id\n // - name\n // - params\n // - inactive (if true, will be cleaned up if not reused in re-run)\n // - ready (has the 'ready' message been received?)\n // - readyCallback (an optional callback to call when ready)\n // - errorCallback (an optional callback to call if the sub terminates with\n // an error, XXX COMPAT WITH 1.0.3.1)\n // - stopCallback (an optional callback to call when the sub terminates\n // for any reason, with an error argument if an error triggered the stop)\n self._subscriptions = {};\n\n // Reactive userId.\n self._userId = null;\n self._userIdDeps = new Tracker.Dependency;\n\n // Block auto-reload while we're waiting for method responses.\n if (Meteor.isClient && Package.reload && !options.reloadWithOutstanding) {\n Package.reload.Reload._onMigrate(function (retry) {\n if (!self._readyToMigrate()) {\n if (self._retryMigrate)\n throw new Error(\"Two migrations in progress?\");\n self._retryMigrate = retry;\n return false;\n } else {\n return [true];\n }\n });\n }\n\n var onMessage = function (raw_msg) {\n try {\n var msg = parseDDP(raw_msg);\n } catch (e) {\n Meteor._debug(\"Exception while parsing DDP\", e);\n return;\n }\n\n if (msg === null || !msg.msg) {\n // XXX COMPAT WITH 0.6.6. ignore the old welcome message for back\n // compat. Remove this 'if' once the server stops sending welcome\n // messages (stream_server.js).\n if (! (msg && msg.server_id))\n Meteor._debug(\"discarding invalid livedata message\", msg);\n return;\n }\n\n if (msg.msg === 'connected') {\n self._version = self._versionSuggestion;\n self._livedata_connected(msg);\n options.onConnected();\n }\n else if (msg.msg == 'failed') {\n if (_.contains(self._supportedDDPVersions, msg.version)) {\n self._versionSuggestion = msg.version;\n self._stream.reconnect({_force: true});\n } else {\n var description =\n \"DDP version negotiation failed; server requested version \" + msg.version;\n self._stream.disconnect({_permanent: true, _error: description});\n options.onDDPVersionNegotiationFailure(description);\n }\n }\n else if (msg.msg === 'ping') {\n if (options.respondToPings)\n self._send({msg: \"pong\", id: msg.id});\n if (self._heartbeat)\n self._heartbeat.pingReceived();\n }\n else if (msg.msg === 'pong') {\n if (self._heartbeat) {\n self._heartbeat.pongReceived();\n }\n }\n else if (_.include(['added', 'changed', 'removed', 'ready', 'updated'], msg.msg))\n self._livedata_data(msg);\n else if (msg.msg === 'nosub')\n self._livedata_nosub(msg);\n else if (msg.msg === 'result')\n self._livedata_result(msg);\n else if (msg.msg === 'error')\n self._livedata_error(msg);\n else\n Meteor._debug(\"discarding unknown livedata message type\", msg);\n };\n\n var onReset = function () {\n // Send a connect message at the beginning of the stream.\n // NOTE: reset is called even on the first connection, so this is\n // the only place we send this message.\n var msg = {msg: 'connect'};\n if (self._lastSessionId)\n msg.session = self._lastSessionId;\n msg.version = self._versionSuggestion || self._supportedDDPVersions[0];\n self._versionSuggestion = msg.version;\n msg.support = self._supportedDDPVersions;\n self._send(msg);\n\n // Now, to minimize setup latency, go ahead and blast out all of\n // our pending methods ands subscriptions before we've even taken\n // the necessary RTT to know if we successfully reconnected. (1)\n // They're supposed to be idempotent; (2) even if we did\n // reconnect, we're not sure what messages might have gotten lost\n // (in either direction) since we were disconnected (TCP being\n // sloppy about that.)\n\n // If the current block of methods all got their results (but didn't all get\n // their data visible), discard the empty block now.\n if (! _.isEmpty(self._outstandingMethodBlocks) &&\n _.isEmpty(self._outstandingMethodBlocks[0].methods)) {\n self._outstandingMethodBlocks.shift();\n }\n\n // Mark all messages as unsent, they have not yet been sent on this\n // connection.\n _.each(self._methodInvokers, function (m) {\n m.sentMessage = false;\n });\n\n // If an `onReconnect` handler is set, call it first. Go through\n // some hoops to ensure that methods that are called from within\n // `onReconnect` get executed _before_ ones that were originally\n // outstanding (since `onReconnect` is used to re-establish auth\n // certificates)\n if (self.onReconnect)\n self._callOnReconnectAndSendAppropriateOutstandingMethods();\n else\n self._sendOutstandingMethods();\n\n // add new subscriptions at the end. this way they take effect after\n // the handlers and we don't see flicker.\n _.each(self._subscriptions, function (sub, id) {\n self._send({\n msg: 'sub',\n id: id,\n name: sub.name,\n params: sub.params\n });\n });\n };\n\n var onDisconnect = function () {\n if (self._heartbeat) {\n self._heartbeat.stop();\n self._heartbeat = null;\n }\n };\n\n if (Meteor.isServer) {\n self._stream.on('message', Meteor.bindEnvironment(onMessage, Meteor._debug));\n self._stream.on('reset', Meteor.bindEnvironment(onReset, Meteor._debug));\n self._stream.on('disconnect', Meteor.bindEnvironment(onDisconnect, Meteor._debug));\n } else {\n self._stream.on('message', onMessage);\n self._stream.on('reset', onReset);\n self._stream.on('disconnect', onDisconnect);\n }\n};\n\n// A MethodInvoker manages sending a method to the server and calling the user's\n// callbacks. On construction, it registers itself in the connection's\n// _methodInvokers map; it removes itself once the method is fully finished and\n// the callback is invoked. This occurs when it has both received a result,\n// and the data written by it is fully visible.\nvar MethodInvoker = function (options) {\n var self = this;\n\n // Public (within this file) fields.\n self.methodId = options.methodId;\n self.sentMessage = false;\n\n self._callback = options.callback;\n self._connection = options.connection;\n self._message = options.message;\n self._onResultReceived = options.onResultReceived || function () {};\n self._wait = options.wait;\n self._methodResult = null;\n self._dataVisible = false;\n\n // Register with the connection.\n self._connection._methodInvokers[self.methodId] = self;\n};\n_.extend(MethodInvoker.prototype, {\n // Sends the method message to the server. May be called additional times if\n // we lose the connection and reconnect before receiving a result.\n sendMessage: function () {\n var self = this;\n // This function is called before sending a method (including resending on\n // reconnect). We should only (re)send methods where we don't already have a\n // result!\n if (self.gotResult())\n throw new Error(\"sendingMethod is called on method with result\");\n\n // If we're re-sending it, it doesn't matter if data was written the first\n // time.\n self._dataVisible = false;\n\n self.sentMessage = true;\n\n // If this is a wait method, make all data messages be buffered until it is\n // done.\n if (self._wait)\n self._connection._methodsBlockingQuiescence[self.methodId] = true;\n\n // Actually send the message.\n self._connection._send(self._message);\n },\n // Invoke the callback, if we have both a result and know that all data has\n // been written to the local cache.\n _maybeInvokeCallback: function () {\n var self = this;\n if (self._methodResult && self._dataVisible) {\n // Call the callback. (This won't throw: the callback was wrapped with\n // bindEnvironment.)\n self._callback(self._methodResult[0], self._methodResult[1]);\n\n // Forget about this method.\n delete self._connection._methodInvokers[self.methodId];\n\n // Let the connection know that this method is finished, so it can try to\n // move on to the next block of methods.\n self._connection._outstandingMethodFinished();\n }\n },\n // Call with the result of the method from the server. Only may be called\n // once; once it is called, you should not call sendMessage again.\n // If the user provided an onResultReceived callback, call it immediately.\n // Then invoke the main callback if data is also visible.\n receiveResult: function (err, result) {\n var self = this;\n if (self.gotResult())\n throw new Error(\"Methods should only receive results once\");\n self._methodResult = [err, result];\n self._onResultReceived(err, result);\n self._maybeInvokeCallback();\n },\n // Call this when all data written by the method is visible. This means that\n // the method has returns its \"data is done\" message *AND* all server\n // documents that are buffered at that time have been written to the local\n // cache. Invokes the main callback if the result has been received.\n dataVisible: function () {\n var self = this;\n self._dataVisible = true;\n self._maybeInvokeCallback();\n },\n // True if receiveResult has been called.\n gotResult: function () {\n var self = this;\n return !!self._methodResult;\n }\n});\n\n_.extend(Connection.prototype, {\n // 'name' is the name of the data on the wire that should go in the\n // store. 'wrappedStore' should be an object with methods beginUpdate, update,\n // endUpdate, saveOriginals, retrieveOriginals. see Collection for an example.\n registerStore: function (name, wrappedStore) {\n var self = this;\n\n if (name in self._stores)\n return false;\n\n // Wrap the input object in an object which makes any store method not\n // implemented by 'store' into a no-op.\n var store = {};\n _.each(['update', 'beginUpdate', 'endUpdate', 'saveOriginals',\n 'retrieveOriginals'], function (method) {\n store[method] = function () {\n return (wrappedStore[method]\n ? wrappedStore[method].apply(wrappedStore, arguments)\n : undefined);\n };\n });\n\n self._stores[name] = store;\n\n var queued = self._updatesForUnknownStores[name];\n if (queued) {\n store.beginUpdate(queued.length, false);\n _.each(queued, function (msg) {\n store.update(msg);\n });\n store.endUpdate();\n delete self._updatesForUnknownStores[name];\n }\n\n return true;\n },\n\n /**\n * @memberOf Meteor\n * @summary Subscribe to a record set. Returns a handle that provides\n * `stop()` and `ready()` methods.\n * @locus Client\n * @param {String} name Name of the subscription. Matches the name of the\n * server's `publish()` call.\n * @param {Any} [arg1,arg2...] Optional arguments passed to publisher\n * function on server.\n * @param {Function|Object} [callbacks] Optional. May include `onStop`\n * and `onReady` callbacks. If there is an error, it is passed as an\n * argument to `onStop`. If a function is passed instead of an object, it\n * is interpreted as an `onReady` callback.\n */\n subscribe: function (name /* .. [arguments] .. (callback|callbacks) */) {\n var self = this;\n\n var params = Array.prototype.slice.call(arguments, 1);\n var callbacks = {};\n if (params.length) {\n var lastParam = params[params.length - 1];\n if (_.isFunction(lastParam)) {\n callbacks.onReady = params.pop();\n } else if (lastParam &&\n // XXX COMPAT WITH 1.0.3.1 onError used to exist, but now we use\n // onStop with an error callback instead.\n _.any([lastParam.onReady, lastParam.onError, lastParam.onStop],\n _.isFunction)) {\n callbacks = params.pop();\n }\n }\n\n // Is there an existing sub with the same name and param, run in an\n // invalidated Computation? This will happen if we are rerunning an\n // existing computation.\n //\n // For example, consider a rerun of:\n //\n // Tracker.autorun(function () {\n // Meteor.subscribe(\"foo\", Session.get(\"foo\"));\n // Meteor.subscribe(\"bar\", Session.get(\"bar\"));\n // });\n //\n // If \"foo\" has changed but \"bar\" has not, we will match the \"bar\"\n // subcribe to an existing inactive subscription in order to not\n // unsub and resub the subscription unnecessarily.\n //\n // We only look for one such sub; if there are N apparently-identical subs\n // being invalidated, we will require N matching subscribe calls to keep\n // them all active.\n var existing = _.find(self._subscriptions, function (sub) {\n return sub.inactive && sub.name === name &&\n EJSON.equals(sub.params, params);\n });\n\n var id;\n if (existing) {\n id = existing.id;\n existing.inactive = false; // reactivate\n\n if (callbacks.onReady) {\n // If the sub is not already ready, replace any ready callback with the\n // one provided now. (It's not really clear what users would expect for\n // an onReady callback inside an autorun; the semantics we provide is\n // that at the time the sub first becomes ready, we call the last\n // onReady callback provided, if any.)\n if (!existing.ready)\n existing.readyCallback = callbacks.onReady;\n }\n\n // XXX COMPAT WITH 1.0.3.1 we used to have onError but now we call\n // onStop with an optional error argument\n if (callbacks.onError) {\n // Replace existing callback if any, so that errors aren't\n // double-reported.\n existing.errorCallback = callbacks.onError;\n }\n\n if (callbacks.onStop) {\n existing.stopCallback = callbacks.onStop;\n }\n } else {\n // New sub! Generate an id, save it locally, and send message.\n id = Random.id();\n self._subscriptions[id] = {\n id: id,\n name: name,\n params: EJSON.clone(params),\n inactive: false,\n ready: false,\n readyDeps: new Tracker.Dependency,\n readyCallback: callbacks.onReady,\n // XXX COMPAT WITH 1.0.3.1 #errorCallback\n errorCallback: callbacks.onError,\n stopCallback: callbacks.onStop,\n connection: self,\n remove: function() {\n delete this.connection._subscriptions[this.id];\n this.ready && this.readyDeps.changed();\n },\n stop: function() {\n this.connection._send({msg: 'unsub', id: id});\n this.remove();\n\n if (callbacks.onStop) {\n callbacks.onStop();\n }\n }\n };\n self._send({msg: 'sub', id: id, name: name, params: params});\n }\n\n // return a handle to the application.\n var handle = {\n stop: function () {\n if (!_.has(self._subscriptions, id))\n return;\n\n self._subscriptions[id].stop();\n },\n ready: function () {\n // return false if we've unsubscribed.\n if (!_.has(self._subscriptions, id))\n return false;\n var record = self._subscriptions[id];\n record.readyDeps.depend();\n return record.ready;\n },\n subscriptionId: id\n };\n\n if (Tracker.active) {\n // We're in a reactive computation, so we'd like to unsubscribe when the\n // computation is invalidated... but not if the rerun just re-subscribes\n // to the same subscription! When a rerun happens, we use onInvalidate\n // as a change to mark the subscription \"inactive\" so that it can\n // be reused from the rerun. If it isn't reused, it's killed from\n // an afterFlush.\n Tracker.onInvalidate(function (c) {\n if (_.has(self._subscriptions, id))\n self._subscriptions[id].inactive = true;\n\n Tracker.afterFlush(function () {\n if (_.has(self._subscriptions, id) &&\n self._subscriptions[id].inactive)\n handle.stop();\n });\n });\n }\n\n return handle;\n },\n\n // options:\n // - onLateError {Function(error)} called if an error was received after the ready event.\n // (errors received before ready cause an error to be thrown)\n _subscribeAndWait: function (name, args, options) {\n var self = this;\n var f = new Future();\n var ready = false;\n var handle;\n args = args || [];\n args.push({\n onReady: function () {\n ready = true;\n f['return']();\n },\n onError: function (e) {\n if (!ready)\n f['throw'](e);\n else\n options && options.onLateError && options.onLateError(e);\n }\n });\n\n handle = self.subscribe.apply(self, [name].concat(args));\n f.wait();\n return handle;\n },\n\n methods: function (methods) {\n var self = this;\n _.each(methods, function (func, name) {\n if (self._methodHandlers[name])\n throw new Error(\"A method named '\" + name + \"' is already defined\");\n self._methodHandlers[name] = func;\n });\n },\n\n /**\n * @memberOf Meteor\n * @summary Invokes a method passing any number of arguments.\n * @locus Anywhere\n * @param {String} name Name of method to invoke\n * @param {EJSONable} [arg1,arg2...] Optional method arguments\n * @param {Function} [asyncCallback] Optional callback, which is called asynchronously with the error or result after the method is complete. If not provided, the method runs synchronously if possible (see below).\n */\n call: function (name /* .. [arguments] .. callback */) {\n // if it's a function, the last argument is the result callback,\n // not a parameter to the remote method.\n var args = Array.prototype.slice.call(arguments, 1);\n if (args.length && typeof args[args.length - 1] === \"function\")\n var callback = args.pop();\n return this.apply(name, args, callback);\n },\n\n // @param options {Optional Object}\n // wait: Boolean - Should we wait to call this until all current methods\n // are fully finished, and block subsequent method calls\n // until this method is fully finished?\n // (does not affect methods called from within this method)\n // onResultReceived: Function - a callback to call as soon as the method\n // result is received. the data written by\n // the method may not yet be in the cache!\n // returnStubValue: Boolean - If true then in cases where we would have\n // otherwise discarded the stub's return value\n // and returned undefined, instead we go ahead\n // and return it. Specifically, this is any\n // time other than when (a) we are already\n // inside a stub or (b) we are in Node and no\n // callback was provided. Currently we require\n // this flag to be explicitly passed to reduce\n // the likelihood that stub return values will\n // be confused with server return values; we\n // may improve this in future.\n // @param callback {Optional Function}\n\n /**\n * @memberOf Meteor\n * @summary Invoke a method passing an array of arguments.\n * @locus Anywhere\n * @param {String} name Name of method to invoke\n * @param {EJSONable[]} args Method arguments\n * @param {Object} [options]\n * @param {Boolean} options.wait (Client only) If true, don't send this method until all previous method calls have completed, and don't send any subsequent method calls until this one is completed.\n * @param {Function} options.onResultReceived (Client only) This callback is invoked with the error or result of the method (just like `asyncCallback`) as soon as the error or result is available. The local cache may not yet reflect the writes performed by the method.\n * @param {Function} [asyncCallback] Optional callback; same semantics as in [`Meteor.call`](#meteor_call).\n */\n apply: function (name, args, options, callback) {\n var self = this;\n\n // We were passed 3 arguments. They may be either (name, args, options)\n // or (name, args, callback)\n if (!callback && typeof options === 'function') {\n callback = options;\n options = {};\n }\n options = options || {};\n\n if (callback) {\n // XXX would it be better form to do the binding in stream.on,\n // or caller, instead of here?\n // XXX improve error message (and how we report it)\n callback = Meteor.bindEnvironment(\n callback,\n \"delivering result of invoking '\" + name + \"'\"\n );\n }\n\n // Keep our args safe from mutation (eg if we don't send the message for a\n // while because of a wait method).\n args = EJSON.clone(args);\n\n // Lazily allocate method ID once we know that it'll be needed.\n var methodId = (function () {\n var id;\n return function () {\n if (id === undefined)\n id = '' + (self._nextMethodId++);\n return id;\n };\n })();\n\n var enclosing = DDP._CurrentInvocation.get();\n var alreadyInSimulation = enclosing && enclosing.isSimulation;\n\n // Lazily generate a randomSeed, only if it is requested by the stub.\n // The random streams only have utility if they're used on both the client\n // and the server; if the client doesn't generate any 'random' values\n // then we don't expect the server to generate any either.\n // Less commonly, the server may perform different actions from the client,\n // and may in fact generate values where the client did not, but we don't\n // have any client-side values to match, so even here we may as well just\n // use a random seed on the server. In that case, we don't pass the\n // randomSeed to save bandwidth, and we don't even generate it to save a\n // bit of CPU and to avoid consuming entropy.\n var randomSeed = null;\n var randomSeedGenerator = function () {\n if (randomSeed === null) {\n randomSeed = makeRpcSeed(enclosing, name);\n }\n return randomSeed;\n };\n\n // Run the stub, if we have one. The stub is supposed to make some\n // temporary writes to the database to give the user a smooth experience\n // until the actual result of executing the method comes back from the\n // server (whereupon the temporary writes to the database will be reversed\n // during the beginUpdate/endUpdate process.)\n //\n // Normally, we ignore the return value of the stub (even if it is an\n // exception), in favor of the real return value from the server. The\n // exception is if the *caller* is a stub. In that case, we're not going\n // to do a RPC, so we use the return value of the stub as our return\n // value.\n\n var stub = self._methodHandlers[name];\n if (stub) {\n var setUserId = function(userId) {\n self.setUserId(userId);\n };\n\n var invocation = new MethodInvocation({\n isSimulation: true,\n userId: self.userId(),\n setUserId: setUserId,\n randomSeed: function () { return randomSeedGenerator(); }\n });\n\n if (!alreadyInSimulation)\n self._saveOriginals();\n\n try {\n // Note that unlike in the corresponding server code, we never audit\n // that stubs check() their arguments.\n var stubReturnValue = DDP._CurrentInvocation.withValue(invocation, function () {\n if (Meteor.isServer) {\n // Because saveOriginals and retrieveOriginals aren't reentrant,\n // don't allow stubs to yield.\n return Meteor._noYieldsAllowed(function () {\n // re-clone, so that the stub can't affect our caller's values\n return stub.apply(invocation, EJSON.clone(args));\n });\n } else {\n return stub.apply(invocation, EJSON.clone(args));\n }\n });\n }\n catch (e) {\n var exception = e;\n }\n\n if (!alreadyInSimulation)\n self._retrieveAndStoreOriginals(methodId());\n }\n\n // If we're in a simulation, stop and return the result we have,\n // rather than going on to do an RPC. If there was no stub,\n // we'll end up returning undefined.\n if (alreadyInSimulation) {\n if (callback) {\n callback(exception, stubReturnValue);\n return undefined;\n }\n if (exception)\n throw exception;\n return stubReturnValue;\n }\n\n // If an exception occurred in a stub, and we're ignoring it\n // because we're doing an RPC and want to use what the server\n // returns instead, log it so the developer knows.\n //\n // Tests can set the 'expected' flag on an exception so it won't\n // go to log.\n if (exception && !exception.expected) {\n Meteor._debug(\"Exception while simulating the effect of invoking '\" +\n name + \"'\", exception, exception.stack);\n }\n\n\n // At this point we're definitely doing an RPC, and we're going to\n // return the value of the RPC to the caller.\n\n // If the caller didn't give a callback, decide what to do.\n if (!callback) {\n if (Meteor.isClient) {\n // On the client, we don't have fibers, so we can't block. The\n // only thing we can do is to return undefined and discard the\n // result of the RPC. If an error occurred then print the error\n // to the console.\n callback = function (err) {\n err && Meteor._debug(\"Error invoking Method '\" + name + \"':\",\n err.message);\n };\n } else {\n // On the server, make the function synchronous. Throw on\n // errors, return on success.\n var future = new Future;\n callback = future.resolver();\n }\n }\n // Send the RPC. Note that on the client, it is important that the\n // stub have finished before we send the RPC, so that we know we have\n // a complete list of which local documents the stub wrote.\n var message = {\n msg: 'method',\n method: name,\n params: args,\n id: methodId()\n };\n\n // Send the randomSeed only if we used it\n if (randomSeed !== null) {\n message.randomSeed = randomSeed;\n }\n\n var methodInvoker = new MethodInvoker({\n methodId: methodId(),\n callback: callback,\n connection: self,\n onResultReceived: options.onResultReceived,\n wait: !!options.wait,\n message: message\n });\n\n if (options.wait) {\n // It's a wait method! Wait methods go in their own block.\n self._outstandingMethodBlocks.push(\n {wait: true, methods: [methodInvoker]});\n } else {\n // Not a wait method. Start a new block if the previous block was a wait\n // block, and add it to the last block of methods.\n if (_.isEmpty(self._outstandingMethodBlocks) ||\n _.last(self._outstandingMethodBlocks).wait)\n self._outstandingMethodBlocks.push({wait: false, methods: []});\n _.last(self._outstandingMethodBlocks).methods.push(methodInvoker);\n }\n\n // If we added it to the first block, send it out now.\n if (self._outstandingMethodBlocks.length === 1)\n methodInvoker.sendMessage();\n\n // If we're using the default callback on the server,\n // block waiting for the result.\n if (future) {\n return future.wait();\n }\n return options.returnStubValue ? stubReturnValue : undefined;\n },\n\n // Before calling a method stub, prepare all stores to track changes and allow\n // _retrieveAndStoreOriginals to get the original versions of changed\n // documents.\n _saveOriginals: function () {\n var self = this;\n _.each(self._stores, function (s) {\n s.saveOriginals();\n });\n },\n // Retrieves the original versions of all documents modified by the stub for\n // method 'methodId' from all stores and saves them to _serverDocuments (keyed\n // by document) and _documentsWrittenByStub (keyed by method ID).\n _retrieveAndStoreOriginals: function (methodId) {\n var self = this;\n if (self._documentsWrittenByStub[methodId])\n throw new Error(\"Duplicate methodId in _retrieveAndStoreOriginals\");\n\n var docsWritten = [];\n _.each(self._stores, function (s, collection) {\n var originals = s.retrieveOriginals();\n // not all stores define retrieveOriginals\n if (!originals)\n return;\n originals.forEach(function (doc, id) {\n docsWritten.push({collection: collection, id: id});\n if (!_.has(self._serverDocuments, collection))\n self._serverDocuments[collection] = new LocalCollection._IdMap;\n var serverDoc = self._serverDocuments[collection].setDefault(id, {});\n if (serverDoc.writtenByStubs) {\n // We're not the first stub to write this doc. Just add our method ID\n // to the record.\n serverDoc.writtenByStubs[methodId] = true;\n } else {\n // First stub! Save the original value and our method ID.\n serverDoc.document = doc;\n serverDoc.flushCallbacks = [];\n serverDoc.writtenByStubs = {};\n serverDoc.writtenByStubs[methodId] = true;\n }\n });\n });\n if (!_.isEmpty(docsWritten)) {\n self._documentsWrittenByStub[methodId] = docsWritten;\n }\n },\n\n // This is very much a private function we use to make the tests\n // take up fewer server resources after they complete.\n _unsubscribeAll: function () {\n var self = this;\n _.each(_.clone(self._subscriptions), function (sub, id) {\n // Avoid killing the autoupdate subscription so that developers\n // still get hot code pushes when writing tests.\n //\n // XXX it's a hack to encode knowledge about autoupdate here,\n // but it doesn't seem worth it yet to have a special API for\n // subscriptions to preserve after unit tests.\n if (sub.name !== 'meteor_autoupdate_clientVersions') {\n self._subscriptions[id].stop();\n }\n });\n },\n\n // Sends the DDP stringification of the given message object\n _send: function (obj) {\n var self = this;\n self._stream.send(stringifyDDP(obj));\n },\n\n // We detected via DDP-level heartbeats that we've lost the\n // connection. Unlike `disconnect` or `close`, a lost connection\n // will be automatically retried.\n _lostConnection: function (error) {\n var self = this;\n self._stream._lostConnection(error);\n },\n\n /**\n * @summary Get the current connection status. A reactive data source.\n * @locus Client\n * @memberOf Meteor\n */\n status: function (/*passthrough args*/) {\n var self = this;\n return self._stream.status.apply(self._stream, arguments);\n },\n\n /**\n * @summary Force an immediate reconnection attempt if the client is not connected to the server.\n\n This method does nothing if the client is already connected.\n * @locus Client\n * @memberOf Meteor\n */\n reconnect: function (/*passthrough args*/) {\n var self = this;\n return self._stream.reconnect.apply(self._stream, arguments);\n },\n\n /**\n * @summary Disconnect the client from the server.\n * @locus Client\n * @memberOf Meteor\n */\n disconnect: function (/*passthrough args*/) {\n var self = this;\n return self._stream.disconnect.apply(self._stream, arguments);\n },\n\n close: function () {\n var self = this;\n return self._stream.disconnect({_permanent: true});\n },\n\n ///\n /// Reactive user system\n ///\n userId: function () {\n var self = this;\n if (self._userIdDeps)\n self._userIdDeps.depend();\n return self._userId;\n },\n\n setUserId: function (userId) {\n var self = this;\n // Avoid invalidating dependents if setUserId is called with current value.\n if (self._userId === userId)\n return;\n self._userId = userId;\n if (self._userIdDeps)\n self._userIdDeps.changed();\n },\n\n // Returns true if we are in a state after reconnect of waiting for subs to be\n // revived or early methods to finish their data, or we are waiting for a\n // \"wait\" method to finish.\n _waitingForQuiescence: function () {\n var self = this;\n return (! _.isEmpty(self._subsBeingRevived) ||\n ! _.isEmpty(self._methodsBlockingQuiescence));\n },\n\n // Returns true if any method whose message has been sent to the server has\n // not yet invoked its user callback.\n _anyMethodsAreOutstanding: function () {\n var self = this;\n return _.any(_.pluck(self._methodInvokers, 'sentMessage'));\n },\n\n _livedata_connected: function (msg) {\n var self = this;\n\n if (self._version !== 'pre1' && self._heartbeatInterval !== 0) {\n self._heartbeat = new Heartbeat({\n heartbeatInterval: self._heartbeatInterval,\n heartbeatTimeout: self._heartbeatTimeout,\n onTimeout: function () {\n self._lostConnection(\n new DDP.ConnectionError(\"DDP heartbeat timed out\"));\n },\n sendPing: function () {\n self._send({msg: 'ping'});\n }\n });\n self._heartbeat.start();\n }\n\n // If this is a reconnect, we'll have to reset all stores.\n if (self._lastSessionId)\n self._resetStores = true;\n\n if (typeof (msg.session) === \"string\") {\n var reconnectedToPreviousSession = (self._lastSessionId === msg.session);\n self._lastSessionId = msg.session;\n }\n\n if (reconnectedToPreviousSession) {\n // Successful reconnection -- pick up where we left off. Note that right\n // now, this never happens: the server never connects us to a previous\n // session, because DDP doesn't provide enough data for the server to know\n // what messages the client has processed. We need to improve DDP to make\n // this possible, at which point we'll probably need more code here.\n return;\n }\n\n // Server doesn't have our data any more. Re-sync a new session.\n\n // Forget about messages we were buffering for unknown collections. They'll\n // be resent if still relevant.\n self._updatesForUnknownStores = {};\n\n if (self._resetStores) {\n // Forget about the effects of stubs. We'll be resetting all collections\n // anyway.\n self._documentsWrittenByStub = {};\n self._serverDocuments = {};\n }\n\n // Clear _afterUpdateCallbacks.\n self._afterUpdateCallbacks = [];\n\n // Mark all named subscriptions which are ready (ie, we already called the\n // ready callback) as needing to be revived.\n // XXX We should also block reconnect quiescence until unnamed subscriptions\n // (eg, autopublish) are done re-publishing to avoid flicker!\n self._subsBeingRevived = {};\n _.each(self._subscriptions, function (sub, id) {\n if (sub.ready)\n self._subsBeingRevived[id] = true;\n });\n\n // Arrange for \"half-finished\" methods to have their callbacks run, and\n // track methods that were sent on this connection so that we don't\n // quiesce until they are all done.\n //\n // Start by clearing _methodsBlockingQuiescence: methods sent before\n // reconnect don't matter, and any \"wait\" methods sent on the new connection\n // that we drop here will be restored by the loop below.\n self._methodsBlockingQuiescence = {};\n if (self._resetStores) {\n _.each(self._methodInvokers, function (invoker) {\n if (invoker.gotResult()) {\n // This method already got its result, but it didn't call its callback\n // because its data didn't become visible. We did not resend the\n // method RPC. We'll call its callback when we get a full quiesce,\n // since that's as close as we'll get to \"data must be visible\".\n self._afterUpdateCallbacks.push(_.bind(invoker.dataVisible, invoker));\n } else if (invoker.sentMessage) {\n // This method has been sent on this connection (maybe as a resend\n // from the last connection, maybe from onReconnect, maybe just very\n // quickly before processing the connected message).\n //\n // We don't need to do anything special to ensure its callbacks get\n // called, but we'll count it as a method which is preventing\n // reconnect quiescence. (eg, it might be a login method that was run\n // from onReconnect, and we don't want to see flicker by seeing a\n // logged-out state.)\n self._methodsBlockingQuiescence[invoker.methodId] = true;\n }\n });\n }\n\n self._messagesBufferedUntilQuiescence = [];\n\n // If we're not waiting on any methods or subs, we can reset the stores and\n // call the callbacks immediately.\n if (!self._waitingForQuiescence()) {\n if (self._resetStores) {\n _.each(self._stores, function (s) {\n s.beginUpdate(0, true);\n s.endUpdate();\n });\n self._resetStores = false;\n }\n self._runAfterUpdateCallbacks();\n }\n },\n\n\n _processOneDataMessage: function (msg, updates) {\n var self = this;\n // Using underscore here so as not to need to capitalize.\n self['_process_' + msg.msg](msg, updates);\n },\n\n\n _livedata_data: function (msg) {\n var self = this;\n\n // collection name -> array of messages\n var updates = {};\n\n if (self._waitingForQuiescence()) {\n self._messagesBufferedUntilQuiescence.push(msg);\n\n if (msg.msg === \"nosub\")\n delete self._subsBeingRevived[msg.id];\n\n _.each(msg.subs || [], function (subId) {\n delete self._subsBeingRevived[subId];\n });\n _.each(msg.methods || [], function (methodId) {\n delete self._methodsBlockingQuiescence[methodId];\n });\n\n if (self._waitingForQuiescence())\n return;\n\n // No methods or subs are blocking quiescence!\n // We'll now process and all of our buffered messages, reset all stores,\n // and apply them all at once.\n _.each(self._messagesBufferedUntilQuiescence, function (bufferedMsg) {\n self._processOneDataMessage(bufferedMsg, updates);\n });\n self._messagesBufferedUntilQuiescence = [];\n } else {\n self._processOneDataMessage(msg, updates);\n }\n\n if (self._resetStores || !_.isEmpty(updates)) {\n // Begin a transactional update of each store.\n _.each(self._stores, function (s, storeName) {\n s.beginUpdate(_.has(updates, storeName) ? updates[storeName].length : 0,\n self._resetStores);\n });\n self._resetStores = false;\n\n _.each(updates, function (updateMessages, storeName) {\n var store = self._stores[storeName];\n if (store) {\n _.each(updateMessages, function (updateMessage) {\n store.update(updateMessage);\n });\n } else {\n // Nobody's listening for this data. Queue it up until\n // someone wants it.\n // XXX memory use will grow without bound if you forget to\n // create a collection or just don't care about it... going\n // to have to do something about that.\n if (!_.has(self._updatesForUnknownStores, storeName))\n self._updatesForUnknownStores[storeName] = [];\n Array.prototype.push.apply(self._updatesForUnknownStores[storeName],\n updateMessages);\n }\n });\n\n // End update transaction.\n _.each(self._stores, function (s) { s.endUpdate(); });\n }\n\n self._runAfterUpdateCallbacks();\n },\n\n // Call any callbacks deferred with _runWhenAllServerDocsAreFlushed whose\n // relevant docs have been flushed, as well as dataVisible callbacks at\n // reconnect-quiescence time.\n _runAfterUpdateCallbacks: function () {\n var self = this;\n var callbacks = self._afterUpdateCallbacks;\n self._afterUpdateCallbacks = [];\n _.each(callbacks, function (c) {\n c();\n });\n },\n\n _pushUpdate: function (updates, collection, msg) {\n var self = this;\n if (!_.has(updates, collection)) {\n updates[collection] = [];\n }\n updates[collection].push(msg);\n },\n\n _getServerDoc: function (collection, id) {\n var self = this;\n if (!_.has(self._serverDocuments, collection))\n return null;\n var serverDocsForCollection = self._serverDocuments[collection];\n return serverDocsForCollection.get(id) || null;\n },\n\n _process_added: function (msg, updates) {\n var self = this;\n var id = LocalCollection._idParse(msg.id);\n var serverDoc = self._getServerDoc(msg.collection, id);\n if (serverDoc) {\n // Some outstanding stub wrote here.\n if (serverDoc.document !== undefined)\n throw new Error(\"Server sent add for existing id: \" + msg.id);\n serverDoc.document = msg.fields || {};\n serverDoc.document._id = id;\n } else {\n self._pushUpdate(updates, msg.collection, msg);\n }\n },\n\n _process_changed: function (msg, updates) {\n var self = this;\n var serverDoc = self._getServerDoc(\n msg.collection, LocalCollection._idParse(msg.id));\n if (serverDoc) {\n if (serverDoc.document === undefined)\n throw new Error(\"Server sent changed for nonexisting id: \" + msg.id);\n LocalCollection._applyChanges(serverDoc.document, msg.fields);\n } else {\n self._pushUpdate(updates, msg.collection, msg);\n }\n },\n\n _process_removed: function (msg, updates) {\n var self = this;\n var serverDoc = self._getServerDoc(\n msg.collection, LocalCollection._idParse(msg.id));\n if (serverDoc) {\n // Some outstanding stub wrote here.\n if (serverDoc.document === undefined)\n throw new Error(\"Server sent removed for nonexisting id:\" + msg.id);\n serverDoc.document = undefined;\n } else {\n self._pushUpdate(updates, msg.collection, {\n msg: 'removed',\n collection: msg.collection,\n id: msg.id\n });\n }\n },\n\n _process_updated: function (msg, updates) {\n var self = this;\n // Process \"method done\" messages.\n _.each(msg.methods, function (methodId) {\n _.each(self._documentsWrittenByStub[methodId], function (written) {\n var serverDoc = self._getServerDoc(written.collection, written.id);\n if (!serverDoc)\n throw new Error(\"Lost serverDoc for \" + JSON.stringify(written));\n if (!serverDoc.writtenByStubs[methodId])\n throw new Error(\"Doc \" + JSON.stringify(written) +\n \" not written by method \" + methodId);\n delete serverDoc.writtenByStubs[methodId];\n if (_.isEmpty(serverDoc.writtenByStubs)) {\n // All methods whose stubs wrote this method have completed! We can\n // now copy the saved document to the database (reverting the stub's\n // change if the server did not write to this object, or applying the\n // server's writes if it did).\n\n // This is a fake ddp 'replace' message. It's just for talking\n // between livedata connections and minimongo. (We have to stringify\n // the ID because it's supposed to look like a wire message.)\n self._pushUpdate(updates, written.collection, {\n msg: 'replace',\n id: LocalCollection._idStringify(written.id),\n replace: serverDoc.document\n });\n // Call all flush callbacks.\n _.each(serverDoc.flushCallbacks, function (c) {\n c();\n });\n\n // Delete this completed serverDocument. Don't bother to GC empty\n // IdMaps inside self._serverDocuments, since there probably aren't\n // many collections and they'll be written repeatedly.\n self._serverDocuments[written.collection].remove(written.id);\n }\n });\n delete self._documentsWrittenByStub[methodId];\n\n // We want to call the data-written callback, but we can't do so until all\n // currently buffered messages are flushed.\n var callbackInvoker = self._methodInvokers[methodId];\n if (!callbackInvoker)\n throw new Error(\"No callback invoker for method \" + methodId);\n self._runWhenAllServerDocsAreFlushed(\n _.bind(callbackInvoker.dataVisible, callbackInvoker));\n });\n },\n\n _process_ready: function (msg, updates) {\n var self = this;\n // Process \"sub ready\" messages. \"sub ready\" messages don't take effect\n // until all current server documents have been flushed to the local\n // database. We can use a write fence to implement this.\n _.each(msg.subs, function (subId) {\n self._runWhenAllServerDocsAreFlushed(function () {\n var subRecord = self._subscriptions[subId];\n // Did we already unsubscribe?\n if (!subRecord)\n return;\n // Did we already receive a ready message? (Oops!)\n if (subRecord.ready)\n return;\n subRecord.readyCallback && subRecord.readyCallback();\n subRecord.ready = true;\n subRecord.readyDeps.changed();\n });\n });\n },\n\n // Ensures that \"f\" will be called after all documents currently in\n // _serverDocuments have been written to the local cache. f will not be called\n // if the connection is lost before then!\n _runWhenAllServerDocsAreFlushed: function (f) {\n var self = this;\n var runFAfterUpdates = function () {\n self._afterUpdateCallbacks.push(f);\n };\n var unflushedServerDocCount = 0;\n var onServerDocFlush = function () {\n --unflushedServerDocCount;\n if (unflushedServerDocCount === 0) {\n // This was the last doc to flush! Arrange to run f after the updates\n // have been applied.\n runFAfterUpdates();\n }\n };\n _.each(self._serverDocuments, function (collectionDocs) {\n collectionDocs.forEach(function (serverDoc) {\n var writtenByStubForAMethodWithSentMessage = _.any(\n serverDoc.writtenByStubs, function (dummy, methodId) {\n var invoker = self._methodInvokers[methodId];\n return invoker && invoker.sentMessage;\n });\n if (writtenByStubForAMethodWithSentMessage) {\n ++unflushedServerDocCount;\n serverDoc.flushCallbacks.push(onServerDocFlush);\n }\n });\n });\n if (unflushedServerDocCount === 0) {\n // There aren't any buffered docs --- we can call f as soon as the current\n // round of updates is applied!\n runFAfterUpdates();\n }\n },\n\n _livedata_nosub: function (msg) {\n var self = this;\n\n // First pass it through _livedata_data, which only uses it to help get\n // towards quiescence.\n self._livedata_data(msg);\n\n // Do the rest of our processing immediately, with no\n // buffering-until-quiescence.\n\n // we weren't subbed anyway, or we initiated the unsub.\n if (!_.has(self._subscriptions, msg.id))\n return;\n\n // XXX COMPAT WITH 1.0.3.1 #errorCallback\n var errorCallback = self._subscriptions[msg.id].errorCallback;\n var stopCallback = self._subscriptions[msg.id].stopCallback;\n\n self._subscriptions[msg.id].remove();\n\n var meteorErrorFromMsg = function (msgArg) {\n return msgArg && msgArg.error && new Meteor.Error(\n msgArg.error.error, msgArg.error.reason, msgArg.error.details);\n }\n\n // XXX COMPAT WITH 1.0.3.1 #errorCallback\n if (errorCallback && msg.error) {\n errorCallback(meteorErrorFromMsg(msg));\n }\n\n if (stopCallback) {\n stopCallback(meteorErrorFromMsg(msg));\n }\n },\n\n _process_nosub: function () {\n // This is called as part of the \"buffer until quiescence\" process, but\n // nosub's effect is always immediate. It only goes in the buffer at all\n // because it's possible for a nosub to be the thing that triggers\n // quiescence, if we were waiting for a sub to be revived and it dies\n // instead.\n },\n\n _livedata_result: function (msg) {\n // id, result or error. error has error (code), reason, details\n\n var self = this;\n\n // find the outstanding request\n // should be O(1) in nearly all realistic use cases\n if (_.isEmpty(self._outstandingMethodBlocks)) {\n Meteor._debug(\"Received method result but no methods outstanding\");\n return;\n }\n var currentMethodBlock = self._outstandingMethodBlocks[0].methods;\n var m;\n for (var i = 0; i < currentMethodBlock.length; i++) {\n m = currentMethodBlock[i];\n if (m.methodId === msg.id)\n break;\n }\n\n if (!m) {\n Meteor._debug(\"Can't match method response to original method call\", msg);\n return;\n }\n\n // Remove from current method block. This may leave the block empty, but we\n // don't move on to the next block until the callback has been delivered, in\n // _outstandingMethodFinished.\n currentMethodBlock.splice(i, 1);\n\n if (_.has(msg, 'error')) {\n m.receiveResult(new Meteor.Error(\n msg.error.error, msg.error.reason,\n msg.error.details));\n } else {\n // msg.result may be undefined if the method didn't return a\n // value\n m.receiveResult(undefined, msg.result);\n }\n },\n\n // Called by MethodInvoker after a method's callback is invoked. If this was\n // the last outstanding method in the current block, runs the next block. If\n // there are no more methods, consider accepting a hot code push.\n _outstandingMethodFinished: function () {\n var self = this;\n if (self._anyMethodsAreOutstanding())\n return;\n\n // No methods are outstanding. This should mean that the first block of\n // methods is empty. (Or it might not exist, if this was a method that\n // half-finished before disconnect/reconnect.)\n if (! _.isEmpty(self._outstandingMethodBlocks)) {\n var firstBlock = self._outstandingMethodBlocks.shift();\n if (! _.isEmpty(firstBlock.methods))\n throw new Error(\"No methods outstanding but nonempty block: \" +\n JSON.stringify(firstBlock));\n\n // Send the outstanding methods now in the first block.\n if (!_.isEmpty(self._outstandingMethodBlocks))\n self._sendOutstandingMethods();\n }\n\n // Maybe accept a hot code push.\n self._maybeMigrate();\n },\n\n // Sends messages for all the methods in the first block in\n // _outstandingMethodBlocks.\n _sendOutstandingMethods: function() {\n var self = this;\n if (_.isEmpty(self._outstandingMethodBlocks))\n return;\n _.each(self._outstandingMethodBlocks[0].methods, function (m) {\n m.sendMessage();\n });\n },\n\n _livedata_error: function (msg) {\n Meteor._debug(\"Received error from server: \", msg.reason);\n if (msg.offendingMessage)\n Meteor._debug(\"For: \", msg.offendingMessage);\n },\n\n _callOnReconnectAndSendAppropriateOutstandingMethods: function() {\n var self = this;\n var oldOutstandingMethodBlocks = self._outstandingMethodBlocks;\n self._outstandingMethodBlocks = [];\n\n self.onReconnect();\n\n if (_.isEmpty(oldOutstandingMethodBlocks))\n return;\n\n // We have at least one block worth of old outstanding methods to try\n // again. First: did onReconnect actually send anything? If not, we just\n // restore all outstanding methods and run the first block.\n if (_.isEmpty(self._outstandingMethodBlocks)) {\n self._outstandingMethodBlocks = oldOutstandingMethodBlocks;\n self._sendOutstandingMethods();\n return;\n }\n\n // OK, there are blocks on both sides. Special case: merge the last block of\n // the reconnect methods with the first block of the original methods, if\n // neither of them are \"wait\" blocks.\n if (!_.last(self._outstandingMethodBlocks).wait &&\n !oldOutstandingMethodBlocks[0].wait) {\n _.each(oldOutstandingMethodBlocks[0].methods, function (m) {\n _.last(self._outstandingMethodBlocks).methods.push(m);\n\n // If this \"last block\" is also the first block, send the message.\n if (self._outstandingMethodBlocks.length === 1)\n m.sendMessage();\n });\n\n oldOutstandingMethodBlocks.shift();\n }\n\n // Now add the rest of the original blocks on.\n _.each(oldOutstandingMethodBlocks, function (block) {\n self._outstandingMethodBlocks.push(block);\n });\n },\n\n // We can accept a hot code push if there are no methods in flight.\n _readyToMigrate: function() {\n var self = this;\n return _.isEmpty(self._methodInvokers);\n },\n\n // If we were blocking a migration, see if it's now possible to continue.\n // Call whenever the set of outstanding/blocked methods shrinks.\n _maybeMigrate: function () {\n var self = this;\n if (self._retryMigrate && self._readyToMigrate()) {\n self._retryMigrate();\n self._retryMigrate = null;\n }\n }\n});\n\nLivedataTest.Connection = Connection;\n\n// @param url {String} URL to Meteor app,\n// e.g.:\n// \"subdomain.meteor.com\",\n// \"http://subdomain.meteor.com\",\n// \"/\",\n// \"ddp+sockjs://ddp--****-foo.meteor.com/sockjs\"\n\n/**\n * @summary Connect to the server of a different Meteor application to subscribe to its document sets and invoke its remote methods.\n * @locus Anywhere\n * @param {String} url The URL of another Meteor application.\n */\nDDP.connect = function (url, options) {\n var ret = new Connection(url, options);\n allConnections.push(ret); // hack. see below.\n return ret;\n};\n\n// Hack for `spiderable` package: a way to see if the page is done\n// loading all the data it needs.\n//\nallConnections = [];\nDDP._allSubscriptionsReady = function () {\n return _.all(allConnections, function (conn) {\n return _.all(conn._subscriptions, function (sub) {\n return sub.ready;\n });\n });\n};\n","// Meteor.refresh can be called on the client (if you're in common code) but it\n// only has an effect on the server.\nMeteor.refresh = function (notification) {\n};\n\nif (Meteor.isClient) {\n // By default, try to connect back to the same endpoint as the page\n // was served from.\n //\n // XXX We should be doing this a different way. Right now we don't\n // include ROOT_URL_PATH_PREFIX when computing ddpUrl. (We don't\n // include it on the server when computing\n // DDP_DEFAULT_CONNECTION_URL, and we don't include it in our\n // default, '/'.) We get by with this because DDP.connect then\n // forces the URL passed to it to be interpreted relative to the\n // app's deploy path, even if it is absolute. Instead, we should\n // make DDP_DEFAULT_CONNECTION_URL, if set, include the path prefix;\n // make the default ddpUrl be '' rather that '/'; and make\n // _translateUrl in stream_client_common.js not force absolute paths\n // to be treated like relative paths. See also\n // stream_client_common.js #RationalizingRelativeDDPURLs\n var ddpUrl = '/';\n if (typeof __meteor_runtime_config__ !== \"undefined\") {\n if (__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL)\n ddpUrl = __meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL;\n }\n\n var retry = new Retry();\n\n var onDDPVersionNegotiationFailure = function (description) {\n Meteor._debug(description);\n if (Package.reload) {\n var migrationData = Package.reload.Reload._migrationData('livedata') || {};\n var failures = migrationData.DDPVersionNegotiationFailures || 0;\n ++failures;\n Package.reload.Reload._onMigrate('livedata', function () {\n return [true, {DDPVersionNegotiationFailures: failures}];\n });\n retry.retryLater(failures, function () {\n Package.reload.Reload._reload();\n });\n }\n };\n\n Meteor.connection =\n DDP.connect(ddpUrl, {\n onDDPVersionNegotiationFailure: onDDPVersionNegotiationFailure\n });\n\n // Proxy the public methods of Meteor.connection so they can\n // be called directly on Meteor.\n _.each(['subscribe', 'methods', 'call', 'apply', 'status', 'reconnect',\n 'disconnect'],\n function (name) {\n Meteor[name] = _.bind(Meteor.connection[name], Meteor.connection);\n });\n} else {\n // Never set up a default connection on the server. Don't even map\n // subscribe/call/etc onto Meteor.\n Meteor.connection = null;\n}\n\n// Meteor.connection used to be called\n// Meteor.default_connection. Provide backcompat as a courtesy even\n// though it was never documented.\n// XXX COMPAT WITH 0.6.4\nMeteor.default_connection = Meteor.connection;\n\n// We should transition from Meteor.connect to DDP.connect.\n// XXX COMPAT WITH 0.6.4\nMeteor.connect = DDP.connect;\n"]} |