Skip to content
This repository

Redirect connection.start to page load if needed #578

Merged
merged 4 commits into from over 1 year ago

1 participant

N. Taylor Mullen
N. Taylor Mullen
Collaborator

Fixed #215, #383 and #491

Executing Javascript once the DOM yielded constant loading in some
browsers where they viewed the page as continuously loading since the
entire page had not been loaded, even though the DOM had. Fixed this
issue by re-routing the connection.start call to the window.load event
by default but also allowing the user to overwrite the default via the
startAfterPageLoad flag.

added some commits
N. Taylor Mullen Fixed #215, #383 and #491
All the bugs fixed in this commit are duplicates.

Executing Javascript once the DOM yielded constant loading in some
browsers where they viewed the page as continuously loading since the
entire page had not been loaded, even though the DOM had.  Fixed this
issue by re-routing the connection.start call to the window.load event
by default but also allowing the user to overwrite the default via the
startAfterPageLoad flag.
d2b5c60
N. Taylor Mullen Changed Flag name waitAfterPageLoad
From startAfterPageLoad
93e9d69
N. Taylor Mullen Addressed code review issues
Made deferral flag check more consistent.  Fixed a comment to abide by
consistency
c3d1f8b
N. Taylor Mullen Saved referrence to $(window)
Replaced all $(window) usages with the new saved referrence
2ecb891
N. Taylor Mullen NTaylorMullen merged commit 78a4f97 into from
N. Taylor Mullen NTaylorMullen closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 4 unique commits by 1 author.

Aug 03, 2012
N. Taylor Mullen Fixed #215, #383 and #491
All the bugs fixed in this commit are duplicates.

Executing Javascript once the DOM yielded constant loading in some
browsers where they viewed the page as continuously loading since the
entire page had not been loaded, even though the DOM had.  Fixed this
issue by re-routing the connection.start call to the window.load event
by default but also allowing the user to overwrite the default via the
startAfterPageLoad flag.
d2b5c60
N. Taylor Mullen Changed Flag name waitAfterPageLoad
From startAfterPageLoad
93e9d69
N. Taylor Mullen Addressed code review issues
Made deferral flag check more consistent.  Fixed a comment to abide by
consistency
c3d1f8b
N. Taylor Mullen Saved referrence to $(window)
Replaced all $(window) usages with the new saved referrence
2ecb891
This page is out of date. Refresh to see the latest.
141  SignalR.Client.JS/jquery.signalR.core.js
@@ -24,6 +24,8 @@
24 24
     
25 25
     var signalR,
26 26
         _connection,
  27
+        _pageLoaded = false,
  28
+        _pageWindow = $(window),
27 29
 
28 30
         events = {
29 31
             onStart: "onStart",
@@ -118,6 +120,8 @@
118 120
         }
119 121
     };
120 122
 
  123
+    _pageWindow.load(function () { _pageLoaded = true; });
  124
+
121 125
     signalR.fn = signalR.prototype = {
122 126
         init: function (url, qs, logging) {
123 127
             this.url = url;
@@ -141,20 +145,13 @@
141 145
             /// <param name="callback" type="Function">A callback function to execute when the connection has started</param>
142 146
             var connection = this,
143 147
                 config = {
  148
+                    waitForPageLoad: true,
144 149
                     transport: "auto",
145 150
                     jsonp: false
146 151
                 },
147 152
                 initialize,
148  
-                deferred = $.Deferred(),
149  
-                parser = window.document.createElement("a");
150  
-
151  
-            if (changeState(connection,
152  
-                            signalR.connectionState.disconnected,
153  
-                            signalR.connectionState.connecting) === false) {
154  
-                // Already started, just return
155  
-                deferred.resolve(connection);
156  
-                return deferred.promise();
157  
-            }
  153
+                deferred = connection.deferral || $.Deferred(),// Check to see if there is a pre-existing deferral that's being built on, if so we want to keep using it
  154
+                parser = window.document.createElement("a");            
158 155
 
159 156
             if ($.type(options) === "function") {
160 157
                 // Support calling with single callback parameter
@@ -166,6 +163,24 @@
166 163
                 }
167 164
             }
168 165
 
  166
+            // Check to see if start is being called prior to page load
  167
+            // If waitForPageLoad is true we then want to re-direct function call to the window load event
  168
+            if (!_pageLoaded && config.waitForPageLoad === true) {
  169
+                _pageWindow.load(function () {
  170
+                    connection.deferral = deferred;
  171
+                    connection.start(options, callback);
  172
+                });
  173
+                return deferred.promise();
  174
+            }
  175
+
  176
+            if (changeState(connection,
  177
+                            signalR.connectionState.disconnected,
  178
+                            signalR.connectionState.connecting) === false) {
  179
+                // Already started, just return
  180
+                deferred.resolve(connection);
  181
+                return deferred.promise();
  182
+            }
  183
+
169 184
             // Resolve the full url
170 185
             parser.href = connection.url;
171 186
             if (!parser.protocol || parser.protocol === ":") {
@@ -248,7 +263,7 @@
248 263
 
249 264
                     $(connection).trigger(events.onStart);
250 265
 
251  
-                    $(window).unload(function () { // failure
  266
+                    _pageWindow.unload(function () { // failure
252 267
                         connection.stop(false /* async */);
253 268
                     });
254 269
 
@@ -257,65 +272,63 @@
257 272
                 });
258 273
             };
259 274
 
260  
-            window.setTimeout(function () {
261  
-                var url = connection.url + "/negotiate";
262  
-                connection.log("Negotiating with '" + url + "'.");
263  
-                $.ajax({
264  
-                    url: url,
265  
-                    global: false,
266  
-                    cache: false,
267  
-                    type: "GET",
268  
-                    data: {},
269  
-                    dataType: connection.ajaxDataType,
270  
-                    error: function (error) {
271  
-                        $(connection).trigger(events.onError, [error.responseText]);
272  
-                        deferred.reject("SignalR: Error during negotiation request: " + error.responseText);
273  
-                        // Stop the connection if negotiate failed
274  
-                        connection.stop();
275  
-                    },
276  
-                    success: function (res) {
277  
-                        connection.appRelativeUrl = res.Url;
278  
-                        connection.id = res.ConnectionId;
279  
-                        connection.webSocketServerUrl = res.WebSocketServerUrl;
280  
-
281  
-                        if (!res.ProtocolVersion || res.ProtocolVersion !== "1.0") {
282  
-                            $(connection).trigger(events.onError, "SignalR: Incompatible protocol version.");
283  
-                            deferred.reject("SignalR: Incompatible protocol version.");
284  
-                            return;
285  
-                        }
  275
+            var url = connection.url + "/negotiate";
  276
+            connection.log("Negotiating with '" + url + "'.");
  277
+            $.ajax({
  278
+                url: url,
  279
+                global: false,
  280
+                cache: false,
  281
+                type: "GET",
  282
+                data: {},
  283
+                dataType: connection.ajaxDataType,
  284
+                error: function (error) {
  285
+                    $(connection).trigger(events.onError, [error.responseText]);
  286
+                    deferred.reject("SignalR: Error during negotiation request: " + error.responseText);
  287
+                    // Stop the connection if negotiate failed
  288
+                    connection.stop();
  289
+                },
  290
+                success: function (res) {
  291
+                    connection.appRelativeUrl = res.Url;
  292
+                    connection.id = res.ConnectionId;
  293
+                    connection.webSocketServerUrl = res.WebSocketServerUrl;
  294
+
  295
+                    if (!res.ProtocolVersion || res.ProtocolVersion !== "1.0") {
  296
+                        $(connection).trigger(events.onError, "SignalR: Incompatible protocol version.");
  297
+                        deferred.reject("SignalR: Incompatible protocol version.");
  298
+                        return;
  299
+                    }
286 300
 
287  
-                        $(connection).trigger(events.onStarting);
  301
+                    $(connection).trigger(events.onStarting);
288 302
 
289  
-                        var transports = [],
290  
-                            supportedTransports = [];
  303
+                    var transports = [],
  304
+                        supportedTransports = [];
291 305
 
292  
-                        $.each(signalR.transports, function (key) {
293  
-                            if (key === "webSockets" && !res.TryWebSockets) {
294  
-                                // Server said don't even try WebSockets, but keep processing the loop
295  
-                                return true;
  306
+                    $.each(signalR.transports, function (key) {
  307
+                        if (key === "webSockets" && !res.TryWebSockets) {
  308
+                            // Server said don't even try WebSockets, but keep processing the loop
  309
+                            return true;
  310
+                        }
  311
+                        supportedTransports.push(key);
  312
+                    });
  313
+
  314
+                    if ($.isArray(config.transport)) {
  315
+                        // ordered list provided
  316
+                        $.each(config.transport, function () {
  317
+                            var transport = this;
  318
+                            if ($.type(transport) === "object" || ($.type(transport) === "string" && $.inArray("" + transport, supportedTransports) >= 0)) {
  319
+                                transports.push($.type(transport) === "string" ? "" + transport : transport);
296 320
                             }
297  
-                            supportedTransports.push(key);
298 321
                         });
299  
-
300  
-                        if ($.isArray(config.transport)) {
301  
-                            // ordered list provided
302  
-                            $.each(config.transport, function () {
303  
-                                var transport = this;
304  
-                                if ($.type(transport) === "object" || ($.type(transport) === "string" && $.inArray("" + transport, supportedTransports) >= 0)) {
305  
-                                    transports.push($.type(transport) === "string" ? "" + transport : transport);
306  
-                                }
307  
-                            });
308  
-                        } else if ($.type(config.transport) === "object" ||
309  
-                                       $.inArray(config.transport, supportedTransports) >= 0) {
310  
-                                // specific transport provided, as object or a named transport, e.g. "longPolling"
311  
-                            transports.push(config.transport);
312  
-                        } else { // default "auto"
313  
-                            transports = supportedTransports;
314  
-                        }
315  
-                        initialize(transports);
  322
+                    } else if ($.type(config.transport) === "object" ||
  323
+                                    $.inArray(config.transport, supportedTransports) >= 0) {
  324
+                            // specific transport provided, as object or a named transport, e.g. "longPolling"
  325
+                        transports.push(config.transport);
  326
+                    } else { // default "auto"
  327
+                        transports = supportedTransports;
316 328
                     }
317  
-                });
318  
-            }, 0);
  329
+                    initialize(transports);
  330
+                }
  331
+            });
319 332
 
320 333
             return deferred.promise();
321 334
         },
141  samples/SignalR.Hosting.AspNet.Samples/Scripts/jquery.signalR.js
@@ -25,6 +25,8 @@
25 25
     
26 26
     var signalR,
27 27
         _connection,
  28
+        _pageLoaded = false,
  29
+        _pageWindow = $(window),
28 30
 
29 31
         events = {
30 32
             onStart: "onStart",
@@ -119,6 +121,8 @@
119 121
         }
120 122
     };
121 123
 
  124
+    _pageWindow.load(function () { _pageLoaded = true; });
  125
+
122 126
     signalR.fn = signalR.prototype = {
123 127
         init: function (url, qs, logging) {
124 128
             this.url = url;
@@ -142,20 +146,13 @@
142 146
             /// <param name="callback" type="Function">A callback function to execute when the connection has started</param>
143 147
             var connection = this,
144 148
                 config = {
  149
+                    waitForPageLoad: true,
145 150
                     transport: "auto",
146 151
                     jsonp: false
147 152
                 },
148 153
                 initialize,
149  
-                deferred = $.Deferred(),
150  
-                parser = window.document.createElement("a");
151  
-
152  
-            if (changeState(connection,
153  
-                            signalR.connectionState.disconnected,
154  
-                            signalR.connectionState.connecting) === false) {
155  
-                // Already started, just return
156  
-                deferred.resolve(connection);
157  
-                return deferred.promise();
158  
-            }
  154
+                deferred = connection.deferral || $.Deferred(),// Check to see if there is a pre-existing deferral that's being built on, if so we want to keep using it
  155
+                parser = window.document.createElement("a");            
159 156
 
160 157
             if ($.type(options) === "function") {
161 158
                 // Support calling with single callback parameter
@@ -167,6 +164,24 @@
167 164
                 }
168 165
             }
169 166
 
  167
+            // Check to see if start is being called prior to page load
  168
+            // If waitForPageLoad is true we then want to re-direct function call to the window load event
  169
+            if (!_pageLoaded && config.waitForPageLoad === true) {
  170
+                _pageWindow.load(function () {
  171
+                    connection.deferral = deferred;
  172
+                    connection.start(options, callback);
  173
+                });
  174
+                return deferred.promise();
  175
+            }
  176
+
  177
+            if (changeState(connection,
  178
+                            signalR.connectionState.disconnected,
  179
+                            signalR.connectionState.connecting) === false) {
  180
+                // Already started, just return
  181
+                deferred.resolve(connection);
  182
+                return deferred.promise();
  183
+            }
  184
+
170 185
             // Resolve the full url
171 186
             parser.href = connection.url;
172 187
             if (!parser.protocol || parser.protocol === ":") {
@@ -249,7 +264,7 @@
249 264
 
250 265
                     $(connection).trigger(events.onStart);
251 266
 
252  
-                    $(window).unload(function () { // failure
  267
+                    _pageWindow.unload(function () { // failure
253 268
                         connection.stop(false /* async */);
254 269
                     });
255 270
 
@@ -258,65 +273,63 @@
258 273
                 });
259 274
             };
260 275
 
261  
-            window.setTimeout(function () {
262  
-                var url = connection.url + "/negotiate";
263  
-                connection.log("Negotiating with '" + url + "'.");
264  
-                $.ajax({
265  
-                    url: url,
266  
-                    global: false,
267  
-                    cache: false,
268  
-                    type: "GET",
269  
-                    data: {},
270  
-                    dataType: connection.ajaxDataType,
271  
-                    error: function (error) {
272  
-                        $(connection).trigger(events.onError, [error.responseText]);
273  
-                        deferred.reject("SignalR: Error during negotiation request: " + error.responseText);
274  
-                        // Stop the connection if negotiate failed
275  
-                        connection.stop();
276  
-                    },
277  
-                    success: function (res) {
278  
-                        connection.appRelativeUrl = res.Url;
279  
-                        connection.id = res.ConnectionId;
280  
-                        connection.webSocketServerUrl = res.WebSocketServerUrl;
281  
-
282  
-                        if (!res.ProtocolVersion || res.ProtocolVersion !== "1.0") {
283  
-                            $(connection).trigger(events.onError, "SignalR: Incompatible protocol version.");
284  
-                            deferred.reject("SignalR: Incompatible protocol version.");
285  
-                            return;
286  
-                        }
  276
+            var url = connection.url + "/negotiate";
  277
+            connection.log("Negotiating with '" + url + "'.");
  278
+            $.ajax({
  279
+                url: url,
  280
+                global: false,
  281
+                cache: false,
  282
+                type: "GET",
  283
+                data: {},
  284
+                dataType: connection.ajaxDataType,
  285
+                error: function (error) {
  286
+                    $(connection).trigger(events.onError, [error.responseText]);
  287
+                    deferred.reject("SignalR: Error during negotiation request: " + error.responseText);
  288
+                    // Stop the connection if negotiate failed
  289
+                    connection.stop();
  290
+                },
  291
+                success: function (res) {
  292
+                    connection.appRelativeUrl = res.Url;
  293
+                    connection.id = res.ConnectionId;
  294
+                    connection.webSocketServerUrl = res.WebSocketServerUrl;
  295
+
  296
+                    if (!res.ProtocolVersion || res.ProtocolVersion !== "1.0") {
  297
+                        $(connection).trigger(events.onError, "SignalR: Incompatible protocol version.");
  298
+                        deferred.reject("SignalR: Incompatible protocol version.");
  299
+                        return;
  300
+                    }
287 301
 
288  
-                        $(connection).trigger(events.onStarting);
  302
+                    $(connection).trigger(events.onStarting);
289 303
 
290  
-                        var transports = [],
291  
-                            supportedTransports = [];
  304
+                    var transports = [],
  305
+                        supportedTransports = [];
292 306
 
293  
-                        $.each(signalR.transports, function (key) {
294  
-                            if (key === "webSockets" && !res.TryWebSockets) {
295  
-                                // Server said don't even try WebSockets, but keep processing the loop
296  
-                                return true;
  307
+                    $.each(signalR.transports, function (key) {
  308
+                        if (key === "webSockets" && !res.TryWebSockets) {
  309
+                            // Server said don't even try WebSockets, but keep processing the loop
  310
+                            return true;
  311
+                        }
  312
+                        supportedTransports.push(key);
  313
+                    });
  314
+
  315
+                    if ($.isArray(config.transport)) {
  316
+                        // ordered list provided
  317
+                        $.each(config.transport, function () {
  318
+                            var transport = this;
  319
+                            if ($.type(transport) === "object" || ($.type(transport) === "string" && $.inArray("" + transport, supportedTransports) >= 0)) {
  320
+                                transports.push($.type(transport) === "string" ? "" + transport : transport);
297 321
                             }
298  
-                            supportedTransports.push(key);
299 322
                         });
300  
-
301  
-                        if ($.isArray(config.transport)) {
302  
-                            // ordered list provided
303  
-                            $.each(config.transport, function () {
304  
-                                var transport = this;
305  
-                                if ($.type(transport) === "object" || ($.type(transport) === "string" && $.inArray("" + transport, supportedTransports) >= 0)) {
306  
-                                    transports.push($.type(transport) === "string" ? "" + transport : transport);
307  
-                                }
308  
-                            });
309  
-                        } else if ($.type(config.transport) === "object" ||
310  
-                                       $.inArray(config.transport, supportedTransports) >= 0) {
311  
-                                // specific transport provided, as object or a named transport, e.g. "longPolling"
312  
-                            transports.push(config.transport);
313  
-                        } else { // default "auto"
314  
-                            transports = supportedTransports;
315  
-                        }
316  
-                        initialize(transports);
  323
+                    } else if ($.type(config.transport) === "object" ||
  324
+                                    $.inArray(config.transport, supportedTransports) >= 0) {
  325
+                            // specific transport provided, as object or a named transport, e.g. "longPolling"
  326
+                        transports.push(config.transport);
  327
+                    } else { // default "auto"
  328
+                        transports = supportedTransports;
317 329
                     }
318  
-                });
319  
-            }, 0);
  330
+                    initialize(transports);
  331
+                }
  332
+            });
320 333
 
321 334
             return deferred.promise();
322 335
         },
2  samples/SignalR.Hosting.AspNet.Samples/Scripts/jquery.signalR.min.js
@@ -6,4 +6,4 @@
6 6
  * Licensed under the MIT.
7 7
  * https://github.com/SignalR/SignalR/blob/master/LICENSE.md
8 8
  */
9  
-(function(n,t){"use strict";if(typeof n!="function")throw"SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";if(!t.JSON)throw"SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";var i,f,r={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},o=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},s=function(i){var r;return(i=n.trim(i),i.indexOf("http")!==0)?!1:(r=t.document.createElement("a"),r.href=i,r.protocol+r.host!==t.location.protocol+t.location.host)},u=function(t,i,u){return i===t.state?(n(t).trigger(r.onStateChanged,[{oldState:t.state,newState:u}]),t.state=u,!0):!1},e=function(n){return n.state===i.connectionState.disconnected};i=function(n,t,r){return new i.fn.init(n,t,r)},i.events=r,i.changeState=u,i.isDisconnecting=e,i.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4},i.hub={start:function(){throw"SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/hubs'><\/script>.";}},i.fn=i.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},ajaxDataType:"json",logging:!1,state:i.connectionState.disconnected,reconnectDelay:2e3,start:function(f,e){var o=this,h={transport:"auto",jsonp:!1},a,l=n.Deferred(),c=t.document.createElement("a");return u(o,i.connectionState.disconnected,i.connectionState.connecting)===!1?(l.resolve(o),l.promise()):(n.type(f)==="function"?e=f:n.type(f)==="object"&&(n.extend(h,f),n.type(h.callback)==="function"&&(e=h.callback)),c.href=o.url,c.protocol&&c.protocol!==":"?(o.protocol=c.protocol,o.host=c.host,o.baseUrl=c.protocol+"//"+c.host):(o.protocol=t.document.location.protocol,o.host=t.document.location.host,o.baseUrl=o.protocol+"//"+o.host),o.wsProtocol=o.protocol==="https:"?"wss://":"ws://",s(o.url)&&(o.log("Auto detected cross domain url."),h.transport==="auto"&&(h.jsonp||(h.jsonp=!n.support.cors,h.jsonp&&o.log("Using jsonp because this browser doesn't support CORS")),h.transport=h.jsonp===!0?"longPolling":["webSockets","longPolling"])),o.ajaxDataType=h.jsonp?"jsonp":"json",n(o).bind(r.onStart,function(){n.type(e)==="function"&&e.call(o),l.resolve(o)}),a=function(f,e){if(e=e||0,e>=f.length){o.transport||(n(o).trigger(r.onError,"SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),l.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),o.stop());return}var s=f[e],h=n.type(s)==="object"?s:i.transports[s];if(s.indexOf("_")===0){a(f,e+1);return}h.start(o,function(){o.transport=h,u(o,i.connectionState.connecting,i.connectionState.connected),n(o).trigger(r.onStart),n(t).unload(function(){o.stop(!1)})},function(){a(f,e+1)})},t.setTimeout(function(){var t=o.url+"/negotiate";o.log("Negotiating with '"+t+"'."),n.ajax({url:t,global:!1,cache:!1,type:"GET",data:{},dataType:o.ajaxDataType,error:function(t){n(o).trigger(r.onError,[t.responseText]),l.reject("SignalR: Error during negotiation request: "+t.responseText),o.stop()},success:function(t){if(o.appRelativeUrl=t.Url,o.id=t.ConnectionId,o.webSocketServerUrl=t.WebSocketServerUrl,!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(o).trigger(r.onError,"SignalR: Incompatible protocol version."),l.reject("SignalR: Incompatible protocol version.");return}n(o).trigger(r.onStarting);var f=[],u=[];n.each(i.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;u.push(n)}),n.isArray(h.transport)?n.each(h.transport,function(){var t=this;(n.type(t)==="object"||n.type(t)==="string"&&n.inArray(""+t,u)>=0)&&f.push(n.type(t)==="string"?""+t:t)}):n.type(h.transport)==="object"||n.inArray(h.transport,u)>=0?f.push(h.transport):f=u,a(f)}})},0),l.promise())},starting:function(t){var i=this,u=n(i);return u.bind(r.onStarting,function(){t.call(i),u.unbind(r.onStarting)}),i},send:function(n){var t=this;if(t.state===i.connectionState.disconnected)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";if(t.state===i.connectionState.connecting)throw"SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.";return t.transport.send(t,n),t},sending:function(t){var i=this;return n(i).bind(r.onSending,function(){t.call(i)}),i},received:function(t){var i=this;return n(i).bind(r.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(r.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(r.onError,function(n,r){t.call(i,r)}),i},disconnected:function(t){var i=this;return n(i).bind(r.onDisconnect,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(r.onReconnect,function(){t.call(i)}),i},stop:function(t){var f=this;if(f.state!==i.connectionState.disconnected){try{f.transport&&(f.transport.abort(f,t),f.transport.stop(f),f.transport=null),n(f).trigger(r.onDisconnect),delete f.messageId,delete f.groups}finally{u(f,f.state,i.connectionState.disconnected)}return f}},log:function(n){o(n,this.logging)}},i.fn.init.prototype=i.fn,i.noConflict=function(){return n.connection===i&&(n.connection=f),i},n.connection&&(f=n.connection),n.connection=n.signalR=i})(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,i=n.signalR.events;r.transports={},r.transports._logic={addQs:function(i,r){return r.qs?typeof r.qs=="object"?i+"&"+n.param(r.qs):typeof r.qs=="string"?i+"&"+r.qs:i+"&"+t.escape(r.qs.toString()):i},getUrl:function(n,i,r,u){var o=i==="webSockets"?"":n.baseUrl,f=o+n.appRelativeUrl,e="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(e+="&connectionData="+t.escape(n.data)),r?(u&&(f=f+"/reconnect"),n.messageId&&(e+="&messageId="+n.messageId),n.groups&&(e+="&groups="+t.escape(JSON.stringify(n.groups)))):f=f+"/connect",f+="?"+e,f=this.addQs(f,n),f+="&tid="+Math.floor(Math.random()*11)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);return f=this.addQs(f,r),n.ajax({url:f,global:!1,type:"POST",dataType:r.ajaxDataType,data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){u!=="abort"&&(u!=="parsererror"||r.ajaxDataType!=="jsonp")&&n(r).trigger(i.onError,[t])}})},ajaxAbort:function(i,r){if(typeof i.transport!="undefined"){r=typeof r=="undefined"?!0:r;var u=i.url+"/abort?transport="+i.transport.name+"&connectionId="+t.escape(i.id);u=this.addQs(u,i),n.ajax({url:u,async:r,timeout:1e3,global:!1,type:"POST",dataType:i.ajaxDataType,data:{}}),i.log("Fired ajax abort async = "+r)}},processMessages:function(t,r){var u=n(t);if(r){if(r.Disconnect){t.log("Disconnect command received from server"),t.stop();return}r.Messages&&n.each(r.Messages,function(){try{u.trigger(i.onReceived,[this])}catch(r){t.log("Error raising received "+r),n(t).trigger(i.onError,[r])}}),r.MessageId&&(t.messageId=r.MessageId),r.TransportData&&(t.groups=r.TransportData.Groups)}},foreverFrame:{count:0,connections:{}}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,r=n.signalR.events,f=n.signalR.changeState,u=i.transports._logic;i.transports.webSockets={name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(e,o,s){var h,a=!1,l=this,c=!o,v=n(e);if(t.MozWebSocket&&(t.WebSocket=t.MozWebSocket),!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,n(e).trigger(r.onSending),h+=u.getUrl(e,this.name,c),e.log("Connecting to websocket endpoint '"+h+"'"),e.socket=new t.WebSocket(h),e.socket.onopen=function(){a=!0,e.log("Websocket opened"),o?o():f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&v.trigger(r.onReconnect)},e.socket.onclose=function(t){if(a)typeof t.wasClean!="undefined"&&t.wasClean===!1?(n(e).trigger(r.onError,[t.reason]),e.log("Unclean disconnect from websocket."+t.reason)):e.log("Websocket closed");else{s?s():c&&l.reconnect(e);return}l.reconnect(e)},e.socket.onmessage=function(i){var f=t.JSON.parse(i.data),o;f&&(o=n(e),f.Messages?u.processMessages(e,f):o.trigger(r.onReceived,[f]))})},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("Websocket reconnecting"),r.start(n))},n.reconnectDelay)},stop:function(n){n.socket!==null&&(n.log("Closing the Websocket"),n.socket.close(),n.socket=null)},abort:function(){}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,r=i.transports._logic;i.transports.serverSentEvents={name:"serverSentEvents",timeOut:3e3,start:function(e,o,s){var c=this,a=!1,l=n(e),h=!o,y,v;if(e.eventSource&&(e.log("The connection already has an event source. Stopping it."),e.stop()),!t.EventSource){s&&(e.log("This browser doesn't support SSE."),s());return}l.trigger(u.onSending),y=r.getUrl(e,this.name,h);try{e.log("Attempting to connect to SSE endpoint '"+y+"'"),e.eventSource=new t.EventSource(y)}catch(p){e.log("EventSource failed trying to connect with error "+p.Message),s?s():(l.trigger(u.onError,[p]),h&&c.reconnect(e));return}v=t.setTimeout(function(){a===!1&&(e.log("EventSource timed out trying to connect"),e.log("EventSource readyState: "+e.eventSource.readyState),h||c.stop(e),h?e.eventSource.readyState!==t.EventSource.CONNECTING&&e.eventSource.readyState!==t.EventSource.OPEN&&c.reconnect(e):s&&s())},c.timeOut),e.eventSource.addEventListener("open",function(){e.log("EventSource connected"),v&&t.clearTimeout(v),a===!1&&(a=!0,o&&o(),h&&f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&l.trigger(u.onReconnect))},!1),e.eventSource.addEventListener("message",function(n){n.data!=="initialized"&&r.processMessages(e,t.JSON.parse(n.data))},!1),e.eventSource.addEventListener("error",function(n){if(!a){s&&s();return}e.log("EventSource readyState: "+e.eventSource.readyState),n.eventPhase===t.EventSource.CLOSED?(e.log("EventSource reconnecting due to the server connection ending"),c.reconnect(e)):(e.log("EventSource error"),l.trigger(u.onError))},!1)},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("EventSource reconnecting"),r.start(n))},n.reconnectDelay)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.log("EventSource calling close()"),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.foreverFrame={name:"foreverFrame",timeOut:3e3,start:function(r,f,e){var s=this,h=i.foreverFrame.count+=1,c,l,o=n("<iframe data-signalr-connection-id='"+r.id+"' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''></iframe>");if(t.EventSource){e&&(r.log("This brower supports SSE, skipping Forever Frame."),e());return}n(r).trigger(u.onSending),c=i.getUrl(r,this.name),c+="&frameId="+h,o.prop("src",c),i.foreverFrame.connections[h]=r,r.log("Binding to iframe's readystatechange event."),o.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])>=0&&(r.log("Forever frame iframe readyState changed to "+this.readyState+", reconnecting"),s.reconnect(r))}),r.frame=o[0],r.frameId=h,f&&(r.onSuccess=f),n("body").append(o),l=t.setTimeout(function(){r.onSuccess&&(r.log("Failed to connect using forever frame source, it timed out after "+s.timeOut+"ms."),s.stop(r),e&&e())},s.timeOut)},reconnect:function(n){var u=this;t.setTimeout(function(){if(n.frame&&(n.state===r.connectionState.reconnecting||f(n,r.connectionState.connected,r.connectionState.reconnecting)===!0)){var e=n.frame,t=i.getUrl(n,u.name,!0)+"&frameId="+n.frameId;n.log("Upating iframe src to '"+t+"'."),e.src=t}},n.reconnectDelay)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,r){var u;i.processMessages(t,r),t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>50&&(t.frameMessageCount=0,u=t.frame.contentWindow||t.frame.contentDocument,u&&u.document&&n("body",u.document).empty())},stop:function(t){var r=null;t.frame&&(t.frame.stop?t.frame.stop():(r=t.frame.contentWindow||t.frame.contentDocument,r.document&&r.document.execCommand&&r.document.execCommand("Stop")),n(t.frame).remove(),delete i.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId,t.log("Stopping forever frame"))},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):f(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).trigger(u.onReconnect)}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,e=n.signalR.isDisconnecting,r=i.transports._logic;i.transports.longPolling={name:"longPolling",reconnectDelay:3e3,start:function(o,s){var l=this,c=!1;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop()),o.messageId=null,t.setTimeout(function(){(function h(a,v){n(a).trigger(u.onSending);var d=a.messageId,k=d===null,b=!k,w=r.getUrl(a,l.name,b,v),p=null,y=!1;(b!==!0||v!==!0||o.state===i.connectionState.reconnecting||f(o,i.connectionState.connected,i.connectionState.reconnecting)!==!1)&&(o.log("Attempting to connect to '"+w+"' using longPolling."),a.pollXhr=n.ajax({url:w,global:!1,cache:!1,type:"GET",dataType:o.ajaxDataType,success:function(l){var w=0,p=!1;(c===!1&&(s(),c=!0),v===!0&&y===!1&&(o.log("Raising the reconnect event"),f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)),r.processMessages(a,l),l&&l.TransportData&&n.type(l.TransportData.LongPollDelay)==="number"&&(w=l.TransportData.LongPollDelay),l&&l.TimedOut&&(p=l.TimedOut),l&&l.Disconnect)||e(a)!==!0&&(w>0?t.setTimeout(function(){h(a,p)},w):h(a,p))},error:function(i,r){if(r==="abort"){o.log("Aborted xhr requst.");return}o.log("An error occurred using longPolling. Status = "+r+". "+i.responseText),p&&t.clearTimeout(p),n(a).trigger(u.onError,[i.responseText]),t.setTimeout(function(){e(a)===!1&&h(a,!0)},o.reconnectDelay)}}),v===!0&&(p=t.setTimeout(function(){y===!1&&f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)},l.reconnectDelay)))})(o),t.setTimeout(function(){c===!1&&(s(),c=!0)},150)},250)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";function o(t){return n.isFunction(t)?null:n.type(t)==="undefined"?null:t}function r(n,t){return new r.fn.init(n,t)}function i(n){return n||(n="/signalr"),new i.fn.init(n)}var f=0,u={},e="proxy.";Array.prototype.hasOwnProperty("map")||(Array.prototype.map=function(n,t){for(var r=this,f=r.length,u=[],i=0;i<f;i+=1)r.hasOwnProperty(i)&&(u[i]=n.call(t,r[i],i,r));return u}),r.fn=r.prototype={init:function(n,t){this.state={},this.connection=n,this.hubName=t,this.subscribed=!1},on:function(t,i){var r=this;return t=t.toLowerCase(),n(r).bind(e+t,function(n,t){i.apply(r,t)}),r.subscribed=!0,r},invoke:function(i){var r=this,e=n.makeArray(arguments).slice(1),h=e[e.length-1],a=n.type(h)==="function"?e.slice(0,e.length-1):e,v=a.map(o),l={hub:r.hubName,method:i,args:v,state:r.state,id:f},s=n.Deferred(),c=function(t){n.extend(this.state,t.State),t.Error?(t.StackTrace&&r.connection.log(t.Error+"\n"+t.StackTrace),s.rejectWith(r,[t.Error])):(n.type(h)==="function"&&h.call(r,t.Result),s.resolveWith(r,[t.Result]))};return u[f.toString()]={scope:r,method:c},f+=1,r.connection.send(t.JSON.stringify(l)),s.promise()}},r.fn.init.prototype=r.fn,i.fn=i.prototype=n.connection(),i.fn.init=function(i,r,f){var o=this;n.signalR.fn.init.call(o,i,r,f),o.proxies={},o.sending(function(){var i=[];n.each(this.proxies,function(n){this.subscribed&&i.push({name:n})}),this.data=t.JSON.stringify(i)}),o.received(function(t){var f,r,i,s,o;t&&(typeof t.Id!="undefined"?(r=t.Id.toString(),i=u[r],i&&(u[r]=null,delete u[r],i.method.call(i.scope,t))):(s=t.Hub.toLowerCase(),o=t.Method.toLowerCase(),f=this.proxies[s],n.extend(f.state,t.State),n(f).trigger(e+o,[t.Args])))})},i.fn.createProxy=function(n){n=n.toLowerCase();var t=this.proxies[n];return t||(t=r(this,n),this.proxies[n]=t),t},i.fn.init.prototype=i.fn,n.hubConnection=i}(window.jQuery,window)
  9
+(function(n,t){"use strict";if(typeof n!="function")throw"SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";if(!t.JSON)throw"SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";var i,e,o=!1,f=n(t),r={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},h=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},c=function(i){var r;return(i=n.trim(i),i.indexOf("http")!==0)?!1:(r=t.document.createElement("a"),r.href=i,r.protocol+r.host!==t.location.protocol+t.location.host)},u=function(t,i,u){return i===t.state?(n(t).trigger(r.onStateChanged,[{oldState:t.state,newState:u}]),t.state=u,!0):!1},s=function(n){return n.state===i.connectionState.disconnected};i=function(n,t,r){return new i.fn.init(n,t,r)},i.events=r,i.changeState=u,i.isDisconnecting=s,i.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4},i.hub={start:function(){throw"SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/hubs'><\/script>.";}},f.load(function(){o=!0}),i.fn=i.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},ajaxDataType:"json",logging:!1,state:i.connectionState.disconnected,reconnectDelay:2e3,start:function(e,s){var h=this,l={waitForPageLoad:!0,transport:"auto",jsonp:!1},y,a=h.deferral||n.Deferred(),v=t.document.createElement("a"),p;return(n.type(e)==="function"?s=e:n.type(e)==="object"&&(n.extend(l,e),n.type(l.callback)==="function"&&(s=l.callback)),!o&&l.waitForPageLoad===!0)?(f.load(function(){h.deferral=a,h.start(e,s)}),a.promise()):u(h,i.connectionState.disconnected,i.connectionState.connecting)===!1?(a.resolve(h),a.promise()):(v.href=h.url,v.protocol&&v.protocol!==":"?(h.protocol=v.protocol,h.host=v.host,h.baseUrl=v.protocol+"//"+v.host):(h.protocol=t.document.location.protocol,h.host=t.document.location.host,h.baseUrl=h.protocol+"//"+h.host),h.wsProtocol=h.protocol==="https:"?"wss://":"ws://",c(h.url)&&(h.log("Auto detected cross domain url."),l.transport==="auto"&&(l.jsonp||(l.jsonp=!n.support.cors,l.jsonp&&h.log("Using jsonp because this browser doesn't support CORS")),l.transport=l.jsonp===!0?"longPolling":["webSockets","longPolling"])),h.ajaxDataType=l.jsonp?"jsonp":"json",n(h).bind(r.onStart,function(){n.type(s)==="function"&&s.call(h),a.resolve(h)}),y=function(t,e){if(e=e||0,e>=t.length){h.transport||(n(h).trigger(r.onError,"SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),a.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),h.stop());return}var o=t[e],s=n.type(o)==="object"?o:i.transports[o];if(o.indexOf("_")===0){y(t,e+1);return}s.start(h,function(){h.transport=s,u(h,i.connectionState.connecting,i.connectionState.connected),n(h).trigger(r.onStart),f.unload(function(){h.stop(!1)})},function(){y(t,e+1)})},p=h.url+"/negotiate",h.log("Negotiating with '"+p+"'."),n.ajax({url:p,global:!1,cache:!1,type:"GET",data:{},dataType:h.ajaxDataType,error:function(t){n(h).trigger(r.onError,[t.responseText]),a.reject("SignalR: Error during negotiation request: "+t.responseText),h.stop()},success:function(t){if(h.appRelativeUrl=t.Url,h.id=t.ConnectionId,h.webSocketServerUrl=t.WebSocketServerUrl,!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(h).trigger(r.onError,"SignalR: Incompatible protocol version."),a.reject("SignalR: Incompatible protocol version.");return}n(h).trigger(r.onStarting);var f=[],u=[];n.each(i.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;u.push(n)}),n.isArray(l.transport)?n.each(l.transport,function(){var t=this;(n.type(t)==="object"||n.type(t)==="string"&&n.inArray(""+t,u)>=0)&&f.push(n.type(t)==="string"?""+t:t)}):n.type(l.transport)==="object"||n.inArray(l.transport,u)>=0?f.push(l.transport):f=u,y(f)}}),a.promise())},starting:function(t){var i=this,u=n(i);return u.bind(r.onStarting,function(){t.call(i),u.unbind(r.onStarting)}),i},send:function(n){var t=this;if(t.state===i.connectionState.disconnected)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";if(t.state===i.connectionState.connecting)throw"SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.";return t.transport.send(t,n),t},sending:function(t){var i=this;return n(i).bind(r.onSending,function(){t.call(i)}),i},received:function(t){var i=this;return n(i).bind(r.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(r.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(r.onError,function(n,r){t.call(i,r)}),i},disconnected:function(t){var i=this;return n(i).bind(r.onDisconnect,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(r.onReconnect,function(){t.call(i)}),i},stop:function(t){var f=this;if(f.state!==i.connectionState.disconnected){try{f.transport&&(f.transport.abort(f,t),f.transport.stop(f),f.transport=null),n(f).trigger(r.onDisconnect),delete f.messageId,delete f.groups}finally{u(f,f.state,i.connectionState.disconnected)}return f}},log:function(n){h(n,this.logging)}},i.fn.init.prototype=i.fn,i.noConflict=function(){return n.connection===i&&(n.connection=e),i},n.connection&&(e=n.connection),n.connection=n.signalR=i})(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,i=n.signalR.events;r.transports={},r.transports._logic={addQs:function(i,r){return r.qs?typeof r.qs=="object"?i+"&"+n.param(r.qs):typeof r.qs=="string"?i+"&"+r.qs:i+"&"+t.escape(r.qs.toString()):i},getUrl:function(n,i,r,u){var o=i==="webSockets"?"":n.baseUrl,f=o+n.appRelativeUrl,e="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(e+="&connectionData="+t.escape(n.data)),r?(u&&(f=f+"/reconnect"),n.messageId&&(e+="&messageId="+n.messageId),n.groups&&(e+="&groups="+t.escape(JSON.stringify(n.groups)))):f=f+"/connect",f+="?"+e,f=this.addQs(f,n),f+="&tid="+Math.floor(Math.random()*11)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);return f=this.addQs(f,r),n.ajax({url:f,global:!1,type:"POST",dataType:r.ajaxDataType,data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){u!=="abort"&&(u!=="parsererror"||r.ajaxDataType!=="jsonp")&&n(r).trigger(i.onError,[t])}})},ajaxAbort:function(i,r){if(typeof i.transport!="undefined"){r=typeof r=="undefined"?!0:r;var u=i.url+"/abort?transport="+i.transport.name+"&connectionId="+t.escape(i.id);u=this.addQs(u,i),n.ajax({url:u,async:r,timeout:1e3,global:!1,type:"POST",dataType:i.ajaxDataType,data:{}}),i.log("Fired ajax abort async = "+r)}},processMessages:function(t,r){var u=n(t);if(r){if(r.Disconnect){t.log("Disconnect command received from server"),t.stop();return}r.Messages&&n.each(r.Messages,function(){try{u.trigger(i.onReceived,[this])}catch(r){t.log("Error raising received "+r),n(t).trigger(i.onError,[r])}}),r.MessageId&&(t.messageId=r.MessageId),r.TransportData&&(t.groups=r.TransportData.Groups)}},foreverFrame:{count:0,connections:{}}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,r=n.signalR.events,f=n.signalR.changeState,u=i.transports._logic;i.transports.webSockets={name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(e,o,s){var h,a=!1,l=this,c=!o,v=n(e);if(t.MozWebSocket&&(t.WebSocket=t.MozWebSocket),!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,n(e).trigger(r.onSending),h+=u.getUrl(e,this.name,c),e.log("Connecting to websocket endpoint '"+h+"'"),e.socket=new t.WebSocket(h),e.socket.onopen=function(){a=!0,e.log("Websocket opened"),o?o():f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&v.trigger(r.onReconnect)},e.socket.onclose=function(t){if(a)typeof t.wasClean!="undefined"&&t.wasClean===!1?(n(e).trigger(r.onError,[t.reason]),e.log("Unclean disconnect from websocket."+t.reason)):e.log("Websocket closed");else{s?s():c&&l.reconnect(e);return}l.reconnect(e)},e.socket.onmessage=function(i){var f=t.JSON.parse(i.data),o;f&&(o=n(e),f.Messages?u.processMessages(e,f):o.trigger(r.onReceived,[f]))})},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("Websocket reconnecting"),r.start(n))},n.reconnectDelay)},stop:function(n){n.socket!==null&&(n.log("Closing the Websocket"),n.socket.close(),n.socket=null)},abort:function(){}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,r=i.transports._logic;i.transports.serverSentEvents={name:"serverSentEvents",timeOut:3e3,start:function(e,o,s){var c=this,a=!1,l=n(e),h=!o,y,v;if(e.eventSource&&(e.log("The connection already has an event source. Stopping it."),e.stop()),!t.EventSource){s&&(e.log("This browser doesn't support SSE."),s());return}l.trigger(u.onSending),y=r.getUrl(e,this.name,h);try{e.log("Attempting to connect to SSE endpoint '"+y+"'"),e.eventSource=new t.EventSource(y)}catch(p){e.log("EventSource failed trying to connect with error "+p.Message),s?s():(l.trigger(u.onError,[p]),h&&c.reconnect(e));return}v=t.setTimeout(function(){a===!1&&(e.log("EventSource timed out trying to connect"),e.log("EventSource readyState: "+e.eventSource.readyState),h||c.stop(e),h?e.eventSource.readyState!==t.EventSource.CONNECTING&&e.eventSource.readyState!==t.EventSource.OPEN&&c.reconnect(e):s&&s())},c.timeOut),e.eventSource.addEventListener("open",function(){e.log("EventSource connected"),v&&t.clearTimeout(v),a===!1&&(a=!0,o&&o(),h&&f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&l.trigger(u.onReconnect))},!1),e.eventSource.addEventListener("message",function(n){n.data!=="initialized"&&r.processMessages(e,t.JSON.parse(n.data))},!1),e.eventSource.addEventListener("error",function(n){if(!a){s&&s();return}e.log("EventSource readyState: "+e.eventSource.readyState),n.eventPhase===t.EventSource.CLOSED?(e.log("EventSource reconnecting due to the server connection ending"),c.reconnect(e)):(e.log("EventSource error"),l.trigger(u.onError))},!1)},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("EventSource reconnecting"),r.start(n))},n.reconnectDelay)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.log("EventSource calling close()"),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.foreverFrame={name:"foreverFrame",timeOut:3e3,start:function(r,f,e){var s=this,h=i.foreverFrame.count+=1,c,l,o=n("<iframe data-signalr-connection-id='"+r.id+"' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''></iframe>");if(t.EventSource){e&&(r.log("This brower supports SSE, skipping Forever Frame."),e());return}n(r).trigger(u.onSending),c=i.getUrl(r,this.name),c+="&frameId="+h,o.prop("src",c),i.foreverFrame.connections[h]=r,r.log("Binding to iframe's readystatechange event."),o.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])>=0&&(r.log("Forever frame iframe readyState changed to "+this.readyState+", reconnecting"),s.reconnect(r))}),r.frame=o[0],r.frameId=h,f&&(r.onSuccess=f),n("body").append(o),l=t.setTimeout(function(){r.onSuccess&&(r.log("Failed to connect using forever frame source, it timed out after "+s.timeOut+"ms."),s.stop(r),e&&e())},s.timeOut)},reconnect:function(n){var u=this;t.setTimeout(function(){if(n.frame&&(n.state===r.connectionState.reconnecting||f(n,r.connectionState.connected,r.connectionState.reconnecting)===!0)){var e=n.frame,t=i.getUrl(n,u.name,!0)+"&frameId="+n.frameId;n.log("Upating iframe src to '"+t+"'."),e.src=t}},n.reconnectDelay)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,r){var u;i.processMessages(t,r),t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>50&&(t.frameMessageCount=0,u=t.frame.contentWindow||t.frame.contentDocument,u&&u.document&&n("body",u.document).empty())},stop:function(t){var r=null;t.frame&&(t.frame.stop?t.frame.stop():(r=t.frame.contentWindow||t.frame.contentDocument,r.document&&r.document.execCommand&&r.document.execCommand("Stop")),n(t.frame).remove(),delete i.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId,t.log("Stopping forever frame"))},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):f(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).trigger(u.onReconnect)}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,e=n.signalR.isDisconnecting,r=i.transports._logic;i.transports.longPolling={name:"longPolling",reconnectDelay:3e3,start:function(o,s){var l=this,c=!1;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop()),o.messageId=null,t.setTimeout(function(){(function h(a,v){n(a).trigger(u.onSending);var d=a.messageId,k=d===null,b=!k,w=r.getUrl(a,l.name,b,v),p=null,y=!1;(b!==!0||v!==!0||o.state===i.connectionState.reconnecting||f(o,i.connectionState.connected,i.connectionState.reconnecting)!==!1)&&(o.log("Attempting to connect to '"+w+"' using longPolling."),a.pollXhr=n.ajax({url:w,global:!1,cache:!1,type:"GET",dataType:o.ajaxDataType,success:function(l){var w=0,p=!1;(c===!1&&(s(),c=!0),v===!0&&y===!1&&(o.log("Raising the reconnect event"),f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)),r.processMessages(a,l),l&&l.TransportData&&n.type(l.TransportData.LongPollDelay)==="number"&&(w=l.TransportData.LongPollDelay),l&&l.TimedOut&&(p=l.TimedOut),l&&l.Disconnect)||e(a)!==!0&&(w>0?t.setTimeout(function(){h(a,p)},w):h(a,p))},error:function(i,r){if(r==="abort"){o.log("Aborted xhr requst.");return}o.log("An error occurred using longPolling. Status = "+r+". "+i.responseText),p&&t.clearTimeout(p),n(a).trigger(u.onError,[i.responseText]),t.setTimeout(function(){e(a)===!1&&h(a,!0)},o.reconnectDelay)}}),v===!0&&(p=t.setTimeout(function(){y===!1&&f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)},l.reconnectDelay)))})(o),t.setTimeout(function(){c===!1&&(s(),c=!0)},150)},250)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";function o(t){return n.isFunction(t)?null:n.type(t)==="undefined"?null:t}function r(n,t){return new r.fn.init(n,t)}function i(n){return n||(n="/signalr"),new i.fn.init(n)}var f=0,u={},e="proxy.";Array.prototype.hasOwnProperty("map")||(Array.prototype.map=function(n,t){for(var r=this,f=r.length,u=[],i=0;i<f;i+=1)r.hasOwnProperty(i)&&(u[i]=n.call(t,r[i],i,r));return u}),r.fn=r.prototype={init:function(n,t){this.state={},this.connection=n,this.hubName=t,this.subscribed=!1},on:function(t,i){var r=this;return t=t.toLowerCase(),n(r).bind(e+t,function(n,t){i.apply(r,t)}),r.subscribed=!0,r},invoke:function(i){var r=this,e=n.makeArray(arguments).slice(1),h=e[e.length-1],a=n.type(h)==="function"?e.slice(0,e.length-1):e,v=a.map(o),l={hub:r.hubName,method:i,args:v,state:r.state,id:f},s=n.Deferred(),c=function(t){n.extend(this.state,t.State),t.Error?(t.StackTrace&&r.connection.log(t.Error+"\n"+t.StackTrace),s.rejectWith(r,[t.Error])):(n.type(h)==="function"&&h.call(r,t.Result),s.resolveWith(r,[t.Result]))};return u[f.toString()]={scope:r,method:c},f+=1,r.connection.send(t.JSON.stringify(l)),s.promise()}},r.fn.init.prototype=r.fn,i.fn=i.prototype=n.connection(),i.fn.init=function(i,r,f){var o=this;n.signalR.fn.init.call(o,i,r,f),o.proxies={},o.sending(function(){var i=[];n.each(this.proxies,function(n){this.subscribed&&i.push({name:n})}),this.data=t.JSON.stringify(i)}),o.received(function(t){var f,r,i,s,o;t&&(typeof t.Id!="undefined"?(r=t.Id.toString(),i=u[r],i&&(u[r]=null,delete u[r],i.method.call(i.scope,t))):(s=t.Hub.toLowerCase(),o=t.Method.toLowerCase(),f=this.proxies[s],n.extend(f.state,t.State),n(f).trigger(e+o,[t.Args])))})},i.fn.createProxy=function(n){n=n.toLowerCase();var t=this.proxies[n];return t||(t=r(this,n),this.proxies[n]=t),t},i.fn.init.prototype=i.fn,n.hubConnection=i}(window.jQuery,window)
141  samples/SignalR.Hosting.AspNet45.Samples/Scripts/jquery.signalR.js
@@ -25,6 +25,8 @@
25 25
     
26 26
     var signalR,
27 27
         _connection,
  28
+        _pageLoaded = false,
  29
+        _pageWindow = $(window),
28 30
 
29 31
         events = {
30 32
             onStart: "onStart",
@@ -119,6 +121,8 @@
119 121
         }
120 122
     };
121 123
 
  124
+    _pageWindow.load(function () { _pageLoaded = true; });
  125
+
122 126
     signalR.fn = signalR.prototype = {
123 127
         init: function (url, qs, logging) {
124 128
             this.url = url;
@@ -142,20 +146,13 @@
142 146
             /// <param name="callback" type="Function">A callback function to execute when the connection has started</param>
143 147
             var connection = this,
144 148
                 config = {
  149
+                    waitForPageLoad: true,
145 150
                     transport: "auto",
146 151
                     jsonp: false
147 152
                 },
148 153
                 initialize,
149  
-                deferred = $.Deferred(),
150  
-                parser = window.document.createElement("a");
151  
-
152  
-            if (changeState(connection,
153  
-                            signalR.connectionState.disconnected,
154  
-                            signalR.connectionState.connecting) === false) {
155  
-                // Already started, just return
156  
-                deferred.resolve(connection);
157  
-                return deferred.promise();
158  
-            }
  154
+                deferred = connection.deferral || $.Deferred(),// Check to see if there is a pre-existing deferral that's being built on, if so we want to keep using it
  155
+                parser = window.document.createElement("a");            
159 156
 
160 157
             if ($.type(options) === "function") {
161 158
                 // Support calling with single callback parameter
@@ -167,6 +164,24 @@
167 164
                 }
168 165
             }
169 166
 
  167
+            // Check to see if start is being called prior to page load
  168
+            // If waitForPageLoad is true we then want to re-direct function call to the window load event
  169
+            if (!_pageLoaded && config.waitForPageLoad === true) {
  170
+                _pageWindow.load(function () {
  171
+                    connection.deferral = deferred;
  172
+                    connection.start(options, callback);
  173
+                });
  174
+                return deferred.promise();
  175
+            }
  176
+
  177
+            if (changeState(connection,
  178
+                            signalR.connectionState.disconnected,
  179
+                            signalR.connectionState.connecting) === false) {
  180
+                // Already started, just return
  181
+                deferred.resolve(connection);
  182
+                return deferred.promise();
  183
+            }
  184
+
170 185
             // Resolve the full url
171 186
             parser.href = connection.url;
172 187
             if (!parser.protocol || parser.protocol === ":") {
@@ -249,7 +264,7 @@
249 264
 
250 265
                     $(connection).trigger(events.onStart);
251 266
 
252  
-                    $(window).unload(function () { // failure
  267
+                    _pageWindow.unload(function () { // failure
253 268
                         connection.stop(false /* async */);
254 269
                     });
255 270
 
@@ -258,65 +273,63 @@
258 273
                 });
259 274
             };
260 275
 
261  
-            window.setTimeout(function () {
262  
-                var url = connection.url + "/negotiate";
263  
-                connection.log("Negotiating with '" + url + "'.");
264  
-                $.ajax({
265  
-                    url: url,
266  
-                    global: false,
267  
-                    cache: false,
268  
-                    type: "GET",
269  
-                    data: {},
270  
-                    dataType: connection.ajaxDataType,
271  
-                    error: function (error) {
272  
-                        $(connection).trigger(events.onError, [error.responseText]);
273  
-                        deferred.reject("SignalR: Error during negotiation request: " + error.responseText);
274  
-                        // Stop the connection if negotiate failed
275  
-                        connection.stop();
276  
-                    },
277  
-                    success: function (res) {
278  
-                        connection.appRelativeUrl = res.Url;
279  
-                        connection.id = res.ConnectionId;
280  
-                        connection.webSocketServerUrl = res.WebSocketServerUrl;
281  
-
282  
-                        if (!res.ProtocolVersion || res.ProtocolVersion !== "1.0") {
283  
-                            $(connection).trigger(events.onError, "SignalR: Incompatible protocol version.");
284  
-                            deferred.reject("SignalR: Incompatible protocol version.");
285  
-                            return;
286  
-                        }
  276
+            var url = connection.url + "/negotiate";
  277
+            connection.log("Negotiating with '" + url + "'.");
  278
+            $.ajax({
  279
+                url: url,
  280
+                global: false,
  281
+                cache: false,
  282
+                type: "GET",
  283
+                data: {},
  284
+                dataType: connection.ajaxDataType,
  285
+                error: function (error) {
  286
+                    $(connection).trigger(events.onError, [error.responseText]);
  287
+                    deferred.reject("SignalR: Error during negotiation request: " + error.responseText);
  288
+                    // Stop the connection if negotiate failed
  289
+                    connection.stop();
  290
+                },
  291
+                success: function (res) {
  292
+                    connection.appRelativeUrl = res.Url;
  293
+                    connection.id = res.ConnectionId;
  294
+                    connection.webSocketServerUrl = res.WebSocketServerUrl;
  295
+
  296
+                    if (!res.ProtocolVersion || res.ProtocolVersion !== "1.0") {
  297
+                        $(connection).trigger(events.onError, "SignalR: Incompatible protocol version.");
  298
+                        deferred.reject("SignalR: Incompatible protocol version.");
  299
+                        return;
  300
+                    }
287 301
 
288  
-                        $(connection).trigger(events.onStarting);
  302
+                    $(connection).trigger(events.onStarting);
289 303
 
290  
-                        var transports = [],
291  
-                            supportedTransports = [];
  304
+                    var transports = [],
  305
+                        supportedTransports = [];
292 306
 
293  
-                        $.each(signalR.transports, function (key) {
294  
-                            if (key === "webSockets" && !res.TryWebSockets) {
295  
-                                // Server said don't even try WebSockets, but keep processing the loop
296  
-                                return true;
  307
+                    $.each(signalR.transports, function (key) {
  308
+                        if (key === "webSockets" && !res.TryWebSockets) {
  309
+                            // Server said don't even try WebSockets, but keep processing the loop
  310
+                            return true;
  311
+                        }
  312
+                        supportedTransports.push(key);
  313
+                    });
  314
+
  315
+                    if ($.isArray(config.transport)) {
  316
+                        // ordered list provided
  317
+                        $.each(config.transport, function () {
  318
+                            var transport = this;
  319
+                            if ($.type(transport) === "object" || ($.type(transport) === "string" && $.inArray("" + transport, supportedTransports) >= 0)) {
  320
+                                transports.push($.type(transport) === "string" ? "" + transport : transport);
297 321
                             }
298  
-                            supportedTransports.push(key);
299 322
                         });
300  
-
301  
-                        if ($.isArray(config.transport)) {
302  
-                            // ordered list provided
303  
-                            $.each(config.transport, function () {
304  
-                                var transport = this;
305  
-                                if ($.type(transport) === "object" || ($.type(transport) === "string" && $.inArray("" + transport, supportedTransports) >= 0)) {
306  
-                                    transports.push($.type(transport) === "string" ? "" + transport : transport);
307  
-                                }
308  
-                            });
309  
-                        } else if ($.type(config.transport) === "object" ||
310  
-                                       $.inArray(config.transport, supportedTransports) >= 0) {
311  
-                                // specific transport provided, as object or a named transport, e.g. "longPolling"
312  
-                            transports.push(config.transport);
313  
-                        } else { // default "auto"
314  
-                            transports = supportedTransports;
315  
-                        }
316  
-                        initialize(transports);
  323
+                    } else if ($.type(config.transport) === "object" ||
  324
+                                    $.inArray(config.transport, supportedTransports) >= 0) {
  325
+                            // specific transport provided, as object or a named transport, e.g. "longPolling"
  326
+                        transports.push(config.transport);
  327
+                    } else { // default "auto"
  328
+                        transports = supportedTransports;
317 329
                     }
318  
-                });
319  
-            }, 0);
  330
+                    initialize(transports);
  331
+                }
  332
+            });
320 333
 
321 334
             return deferred.promise();
322 335
         },
2  samples/SignalR.Hosting.AspNet45.Samples/Scripts/jquery.signalR.min.js
@@ -6,4 +6,4 @@
6 6
  * Licensed under the MIT.
7 7
  * https://github.com/SignalR/SignalR/blob/master/LICENSE.md
8 8
  */
9  
-(function(n,t){"use strict";if(typeof n!="function")throw"SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";if(!t.JSON)throw"SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";var i,f,r={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},o=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},s=function(i){var r;return(i=n.trim(i),i.indexOf("http")!==0)?!1:(r=t.document.createElement("a"),r.href=i,r.protocol+r.host!==t.location.protocol+t.location.host)},u=function(t,i,u){return i===t.state?(n(t).trigger(r.onStateChanged,[{oldState:t.state,newState:u}]),t.state=u,!0):!1},e=function(n){return n.state===i.connectionState.disconnected};i=function(n,t,r){return new i.fn.init(n,t,r)},i.events=r,i.changeState=u,i.isDisconnecting=e,i.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4},i.hub={start:function(){throw"SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/hubs'><\/script>.";}},i.fn=i.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},ajaxDataType:"json",logging:!1,state:i.connectionState.disconnected,reconnectDelay:2e3,start:function(f,e){var o=this,h={transport:"auto",jsonp:!1},a,l=n.Deferred(),c=t.document.createElement("a");return u(o,i.connectionState.disconnected,i.connectionState.connecting)===!1?(l.resolve(o),l.promise()):(n.type(f)==="function"?e=f:n.type(f)==="object"&&(n.extend(h,f),n.type(h.callback)==="function"&&(e=h.callback)),c.href=o.url,c.protocol&&c.protocol!==":"?(o.protocol=c.protocol,o.host=c.host,o.baseUrl=c.protocol+"//"+c.host):(o.protocol=t.document.location.protocol,o.host=t.document.location.host,o.baseUrl=o.protocol+"//"+o.host),o.wsProtocol=o.protocol==="https:"?"wss://":"ws://",s(o.url)&&(o.log("Auto detected cross domain url."),h.transport==="auto"&&(h.jsonp||(h.jsonp=!n.support.cors,h.jsonp&&o.log("Using jsonp because this browser doesn't support CORS")),h.transport=h.jsonp===!0?"longPolling":["webSockets","longPolling"])),o.ajaxDataType=h.jsonp?"jsonp":"json",n(o).bind(r.onStart,function(){n.type(e)==="function"&&e.call(o),l.resolve(o)}),a=function(f,e){if(e=e||0,e>=f.length){o.transport||(n(o).trigger(r.onError,"SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),l.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),o.stop());return}var s=f[e],h=n.type(s)==="object"?s:i.transports[s];if(s.indexOf("_")===0){a(f,e+1);return}h.start(o,function(){o.transport=h,u(o,i.connectionState.connecting,i.connectionState.connected),n(o).trigger(r.onStart),n(t).unload(function(){o.stop(!1)})},function(){a(f,e+1)})},t.setTimeout(function(){var t=o.url+"/negotiate";o.log("Negotiating with '"+t+"'."),n.ajax({url:t,global:!1,cache:!1,type:"GET",data:{},dataType:o.ajaxDataType,error:function(t){n(o).trigger(r.onError,[t.responseText]),l.reject("SignalR: Error during negotiation request: "+t.responseText),o.stop()},success:function(t){if(o.appRelativeUrl=t.Url,o.id=t.ConnectionId,o.webSocketServerUrl=t.WebSocketServerUrl,!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(o).trigger(r.onError,"SignalR: Incompatible protocol version."),l.reject("SignalR: Incompatible protocol version.");return}n(o).trigger(r.onStarting);var f=[],u=[];n.each(i.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;u.push(n)}),n.isArray(h.transport)?n.each(h.transport,function(){var t=this;(n.type(t)==="object"||n.type(t)==="string"&&n.inArray(""+t,u)>=0)&&f.push(n.type(t)==="string"?""+t:t)}):n.type(h.transport)==="object"||n.inArray(h.transport,u)>=0?f.push(h.transport):f=u,a(f)}})},0),l.promise())},starting:function(t){var i=this,u=n(i);return u.bind(r.onStarting,function(){t.call(i),u.unbind(r.onStarting)}),i},send:function(n){var t=this;if(t.state===i.connectionState.disconnected)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";if(t.state===i.connectionState.connecting)throw"SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.";return t.transport.send(t,n),t},sending:function(t){var i=this;return n(i).bind(r.onSending,function(){t.call(i)}),i},received:function(t){var i=this;return n(i).bind(r.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(r.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(r.onError,function(n,r){t.call(i,r)}),i},disconnected:function(t){var i=this;return n(i).bind(r.onDisconnect,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(r.onReconnect,function(){t.call(i)}),i},stop:function(t){var f=this;if(f.state!==i.connectionState.disconnected){try{f.transport&&(f.transport.abort(f,t),f.transport.stop(f),f.transport=null),n(f).trigger(r.onDisconnect),delete f.messageId,delete f.groups}finally{u(f,f.state,i.connectionState.disconnected)}return f}},log:function(n){o(n,this.logging)}},i.fn.init.prototype=i.fn,i.noConflict=function(){return n.connection===i&&(n.connection=f),i},n.connection&&(f=n.connection),n.connection=n.signalR=i})(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,i=n.signalR.events;r.transports={},r.transports._logic={addQs:function(i,r){return r.qs?typeof r.qs=="object"?i+"&"+n.param(r.qs):typeof r.qs=="string"?i+"&"+r.qs:i+"&"+t.escape(r.qs.toString()):i},getUrl:function(n,i,r,u){var o=i==="webSockets"?"":n.baseUrl,f=o+n.appRelativeUrl,e="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(e+="&connectionData="+t.escape(n.data)),r?(u&&(f=f+"/reconnect"),n.messageId&&(e+="&messageId="+n.messageId),n.groups&&(e+="&groups="+t.escape(JSON.stringify(n.groups)))):f=f+"/connect",f+="?"+e,f=this.addQs(f,n),f+="&tid="+Math.floor(Math.random()*11)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);return f=this.addQs(f,r),n.ajax({url:f,global:!1,type:"POST",dataType:r.ajaxDataType,data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){u!=="abort"&&(u!=="parsererror"||r.ajaxDataType!=="jsonp")&&n(r).trigger(i.onError,[t])}})},ajaxAbort:function(i,r){if(typeof i.transport!="undefined"){r=typeof r=="undefined"?!0:r;var u=i.url+"/abort?transport="+i.transport.name+"&connectionId="+t.escape(i.id);u=this.addQs(u,i),n.ajax({url:u,async:r,timeout:1e3,global:!1,type:"POST",dataType:i.ajaxDataType,data:{}}),i.log("Fired ajax abort async = "+r)}},processMessages:function(t,r){var u=n(t);if(r){if(r.Disconnect){t.log("Disconnect command received from server"),t.stop();return}r.Messages&&n.each(r.Messages,function(){try{u.trigger(i.onReceived,[this])}catch(r){t.log("Error raising received "+r),n(t).trigger(i.onError,[r])}}),r.MessageId&&(t.messageId=r.MessageId),r.TransportData&&(t.groups=r.TransportData.Groups)}},foreverFrame:{count:0,connections:{}}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,r=n.signalR.events,f=n.signalR.changeState,u=i.transports._logic;i.transports.webSockets={name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(e,o,s){var h,a=!1,l=this,c=!o,v=n(e);if(t.MozWebSocket&&(t.WebSocket=t.MozWebSocket),!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,n(e).trigger(r.onSending),h+=u.getUrl(e,this.name,c),e.log("Connecting to websocket endpoint '"+h+"'"),e.socket=new t.WebSocket(h),e.socket.onopen=function(){a=!0,e.log("Websocket opened"),o?o():f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&v.trigger(r.onReconnect)},e.socket.onclose=function(t){if(a)typeof t.wasClean!="undefined"&&t.wasClean===!1?(n(e).trigger(r.onError,[t.reason]),e.log("Unclean disconnect from websocket."+t.reason)):e.log("Websocket closed");else{s?s():c&&l.reconnect(e);return}l.reconnect(e)},e.socket.onmessage=function(i){var f=t.JSON.parse(i.data),o;f&&(o=n(e),f.Messages?u.processMessages(e,f):o.trigger(r.onReceived,[f]))})},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("Websocket reconnecting"),r.start(n))},n.reconnectDelay)},stop:function(n){n.socket!==null&&(n.log("Closing the Websocket"),n.socket.close(),n.socket=null)},abort:function(){}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,r=i.transports._logic;i.transports.serverSentEvents={name:"serverSentEvents",timeOut:3e3,start:function(e,o,s){var c=this,a=!1,l=n(e),h=!o,y,v;if(e.eventSource&&(e.log("The connection already has an event source. Stopping it."),e.stop()),!t.EventSource){s&&(e.log("This browser doesn't support SSE."),s());return}l.trigger(u.onSending),y=r.getUrl(e,this.name,h);try{e.log("Attempting to connect to SSE endpoint '"+y+"'"),e.eventSource=new t.EventSource(y)}catch(p){e.log("EventSource failed trying to connect with error "+p.Message),s?s():(l.trigger(u.onError,[p]),h&&c.reconnect(e));return}v=t.setTimeout(function(){a===!1&&(e.log("EventSource timed out trying to connect"),e.log("EventSource readyState: "+e.eventSource.readyState),h||c.stop(e),h?e.eventSource.readyState!==t.EventSource.CONNECTING&&e.eventSource.readyState!==t.EventSource.OPEN&&c.reconnect(e):s&&s())},c.timeOut),e.eventSource.addEventListener("open",function(){e.log("EventSource connected"),v&&t.clearTimeout(v),a===!1&&(a=!0,o&&o(),h&&f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&l.trigger(u.onReconnect))},!1),e.eventSource.addEventListener("message",function(n){n.data!=="initialized"&&r.processMessages(e,t.JSON.parse(n.data))},!1),e.eventSource.addEventListener("error",function(n){if(!a){s&&s();return}e.log("EventSource readyState: "+e.eventSource.readyState),n.eventPhase===t.EventSource.CLOSED?(e.log("EventSource reconnecting due to the server connection ending"),c.reconnect(e)):(e.log("EventSource error"),l.trigger(u.onError))},!1)},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("EventSource reconnecting"),r.start(n))},n.reconnectDelay)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.log("EventSource calling close()"),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.foreverFrame={name:"foreverFrame",timeOut:3e3,start:function(r,f,e){var s=this,h=i.foreverFrame.count+=1,c,l,o=n("<iframe data-signalr-connection-id='"+r.id+"' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''></iframe>");if(t.EventSource){e&&(r.log("This brower supports SSE, skipping Forever Frame."),e());return}n(r).trigger(u.onSending),c=i.getUrl(r,this.name),c+="&frameId="+h,o.prop("src",c),i.foreverFrame.connections[h]=r,r.log("Binding to iframe's readystatechange event."),o.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])>=0&&(r.log("Forever frame iframe readyState changed to "+this.readyState+", reconnecting"),s.reconnect(r))}),r.frame=o[0],r.frameId=h,f&&(r.onSuccess=f),n("body").append(o),l=t.setTimeout(function(){r.onSuccess&&(r.log("Failed to connect using forever frame source, it timed out after "+s.timeOut+"ms."),s.stop(r),e&&e())},s.timeOut)},reconnect:function(n){var u=this;t.setTimeout(function(){if(n.frame&&(n.state===r.connectionState.reconnecting||f(n,r.connectionState.connected,r.connectionState.reconnecting)===!0)){var e=n.frame,t=i.getUrl(n,u.name,!0)+"&frameId="+n.frameId;n.log("Upating iframe src to '"+t+"'."),e.src=t}},n.reconnectDelay)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,r){var u;i.processMessages(t,r),t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>50&&(t.frameMessageCount=0,u=t.frame.contentWindow||t.frame.contentDocument,u&&u.document&&n("body",u.document).empty())},stop:function(t){var r=null;t.frame&&(t.frame.stop?t.frame.stop():(r=t.frame.contentWindow||t.frame.contentDocument,r.document&&r.document.execCommand&&r.document.execCommand("Stop")),n(t.frame).remove(),delete i.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId,t.log("Stopping forever frame"))},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):f(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).trigger(u.onReconnect)}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,e=n.signalR.isDisconnecting,r=i.transports._logic;i.transports.longPolling={name:"longPolling",reconnectDelay:3e3,start:function(o,s){var l=this,c=!1;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop()),o.messageId=null,t.setTimeout(function(){(function h(a,v){n(a).trigger(u.onSending);var d=a.messageId,k=d===null,b=!k,w=r.getUrl(a,l.name,b,v),p=null,y=!1;(b!==!0||v!==!0||o.state===i.connectionState.reconnecting||f(o,i.connectionState.connected,i.connectionState.reconnecting)!==!1)&&(o.log("Attempting to connect to '"+w+"' using longPolling."),a.pollXhr=n.ajax({url:w,global:!1,cache:!1,type:"GET",dataType:o.ajaxDataType,success:function(l){var w=0,p=!1;(c===!1&&(s(),c=!0),v===!0&&y===!1&&(o.log("Raising the reconnect event"),f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)),r.processMessages(a,l),l&&l.TransportData&&n.type(l.TransportData.LongPollDelay)==="number"&&(w=l.TransportData.LongPollDelay),l&&l.TimedOut&&(p=l.TimedOut),l&&l.Disconnect)||e(a)!==!0&&(w>0?t.setTimeout(function(){h(a,p)},w):h(a,p))},error:function(i,r){if(r==="abort"){o.log("Aborted xhr requst.");return}o.log("An error occurred using longPolling. Status = "+r+". "+i.responseText),p&&t.clearTimeout(p),n(a).trigger(u.onError,[i.responseText]),t.setTimeout(function(){e(a)===!1&&h(a,!0)},o.reconnectDelay)}}),v===!0&&(p=t.setTimeout(function(){y===!1&&f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)},l.reconnectDelay)))})(o),t.setTimeout(function(){c===!1&&(s(),c=!0)},150)},250)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";function o(t){return n.isFunction(t)?null:n.type(t)==="undefined"?null:t}function r(n,t){return new r.fn.init(n,t)}function i(n){return n||(n="/signalr"),new i.fn.init(n)}var f=0,u={},e="proxy.";Array.prototype.hasOwnProperty("map")||(Array.prototype.map=function(n,t){for(var r=this,f=r.length,u=[],i=0;i<f;i+=1)r.hasOwnProperty(i)&&(u[i]=n.call(t,r[i],i,r));return u}),r.fn=r.prototype={init:function(n,t){this.state={},this.connection=n,this.hubName=t,this.subscribed=!1},on:function(t,i){var r=this;return t=t.toLowerCase(),n(r).bind(e+t,function(n,t){i.apply(r,t)}),r.subscribed=!0,r},invoke:function(i){var r=this,e=n.makeArray(arguments).slice(1),h=e[e.length-1],a=n.type(h)==="function"?e.slice(0,e.length-1):e,v=a.map(o),l={hub:r.hubName,method:i,args:v,state:r.state,id:f},s=n.Deferred(),c=function(t){n.extend(this.state,t.State),t.Error?(t.StackTrace&&r.connection.log(t.Error+"\n"+t.StackTrace),s.rejectWith(r,[t.Error])):(n.type(h)==="function"&&h.call(r,t.Result),s.resolveWith(r,[t.Result]))};return u[f.toString()]={scope:r,method:c},f+=1,r.connection.send(t.JSON.stringify(l)),s.promise()}},r.fn.init.prototype=r.fn,i.fn=i.prototype=n.connection(),i.fn.init=function(i,r,f){var o=this;n.signalR.fn.init.call(o,i,r,f),o.proxies={},o.sending(function(){var i=[];n.each(this.proxies,function(n){this.subscribed&&i.push({name:n})}),this.data=t.JSON.stringify(i)}),o.received(function(t){var f,r,i,s,o;t&&(typeof t.Id!="undefined"?(r=t.Id.toString(),i=u[r],i&&(u[r]=null,delete u[r],i.method.call(i.scope,t))):(s=t.Hub.toLowerCase(),o=t.Method.toLowerCase(),f=this.proxies[s],n.extend(f.state,t.State),n(f).trigger(e+o,[t.Args])))})},i.fn.createProxy=function(n){n=n.toLowerCase();var t=this.proxies[n];return t||(t=r(this,n),this.proxies[n]=t),t},i.fn.init.prototype=i.fn,n.hubConnection=i}(window.jQuery,window)
  9
+(function(n,t){"use strict";if(typeof n!="function")throw"SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";if(!t.JSON)throw"SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";var i,e,o=!1,f=n(t),r={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},h=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},c=function(i){var r;return(i=n.trim(i),i.indexOf("http")!==0)?!1:(r=t.document.createElement("a"),r.href=i,r.protocol+r.host!==t.location.protocol+t.location.host)},u=function(t,i,u){return i===t.state?(n(t).trigger(r.onStateChanged,[{oldState:t.state,newState:u}]),t.state=u,!0):!1},s=function(n){return n.state===i.connectionState.disconnected};i=function(n,t,r){return new i.fn.init(n,t,r)},i.events=r,i.changeState=u,i.isDisconnecting=s,i.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4},i.hub={start:function(){throw"SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/hubs'><\/script>.";}},f.load(function(){o=!0}),i.fn=i.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},ajaxDataType:"json",logging:!1,state:i.connectionState.disconnected,reconnectDelay:2e3,start:function(e,s){var h=this,l={waitForPageLoad:!0,transport:"auto",jsonp:!1},y,a=h.deferral||n.Deferred(),v=t.document.createElement("a"),p;return(n.type(e)==="function"?s=e:n.type(e)==="object"&&(n.extend(l,e),n.type(l.callback)==="function"&&(s=l.callback)),!o&&l.waitForPageLoad===!0)?(f.load(function(){h.deferral=a,h.start(e,s)}),a.promise()):u(h,i.connectionState.disconnected,i.connectionState.connecting)===!1?(a.resolve(h),a.promise()):(v.href=h.url,v.protocol&&v.protocol!==":"?(h.protocol=v.protocol,h.host=v.host,h.baseUrl=v.protocol+"//"+v.host):(h.protocol=t.document.location.protocol,h.host=t.document.location.host,h.baseUrl=h.protocol+"//"+h.host),h.wsProtocol=h.protocol==="https:"?"wss://":"ws://",c(h.url)&&(h.log("Auto detected cross domain url."),l.transport==="auto"&&(l.jsonp||(l.jsonp=!n.support.cors,l.jsonp&&h.log("Using jsonp because this browser doesn't support CORS")),l.transport=l.jsonp===!0?"longPolling":["webSockets","longPolling"])),h.ajaxDataType=l.jsonp?"jsonp":"json",n(h).bind(r.onStart,function(){n.type(s)==="function"&&s.call(h),a.resolve(h)}),y=function(t,e){if(e=e||0,e>=t.length){h.transport||(n(h).trigger(r.onError,"SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),a.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),h.stop());return}var o=t[e],s=n.type(o)==="object"?o:i.transports[o];if(o.indexOf("_")===0){y(t,e+1);return}s.start(h,function(){h.transport=s,u(h,i.connectionState.connecting,i.connectionState.connected),n(h).trigger(r.onStart),f.unload(function(){h.stop(!1)})},function(){y(t,e+1)})},p=h.url+"/negotiate",h.log("Negotiating with '"+p+"'."),n.ajax({url:p,global:!1,cache:!1,type:"GET",data:{},dataType:h.ajaxDataType,error:function(t){n(h).trigger(r.onError,[t.responseText]),a.reject("SignalR: Error during negotiation request: "+t.responseText),h.stop()},success:function(t){if(h.appRelativeUrl=t.Url,h.id=t.ConnectionId,h.webSocketServerUrl=t.WebSocketServerUrl,!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(h).trigger(r.onError,"SignalR: Incompatible protocol version."),a.reject("SignalR: Incompatible protocol version.");return}n(h).trigger(r.onStarting);var f=[],u=[];n.each(i.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;u.push(n)}),n.isArray(l.transport)?n.each(l.transport,function(){var t=this;(n.type(t)==="object"||n.type(t)==="string"&&n.inArray(""+t,u)>=0)&&f.push(n.type(t)==="string"?""+t:t)}):n.type(l.transport)==="object"||n.inArray(l.transport,u)>=0?f.push(l.transport):f=u,y(f)}}),a.promise())},starting:function(t){var i=this,u=n(i);return u.bind(r.onStarting,function(){t.call(i),u.unbind(r.onStarting)}),i},send:function(n){var t=this;if(t.state===i.connectionState.disconnected)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";if(t.state===i.connectionState.connecting)throw"SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.";return t.transport.send(t,n),t},sending:function(t){var i=this;return n(i).bind(r.onSending,function(){t.call(i)}),i},received:function(t){var i=this;return n(i).bind(r.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(r.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(r.onError,function(n,r){t.call(i,r)}),i},disconnected:function(t){var i=this;return n(i).bind(r.onDisconnect,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(r.onReconnect,function(){t.call(i)}),i},stop:function(t){var f=this;if(f.state!==i.connectionState.disconnected){try{f.transport&&(f.transport.abort(f,t),f.transport.stop(f),f.transport=null),n(f).trigger(r.onDisconnect),delete f.messageId,delete f.groups}finally{u(f,f.state,i.connectionState.disconnected)}return f}},log:function(n){h(n,this.logging)}},i.fn.init.prototype=i.fn,i.noConflict=function(){return n.connection===i&&(n.connection=e),i},n.connection&&(e=n.connection),n.connection=n.signalR=i})(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,i=n.signalR.events;r.transports={},r.transports._logic={addQs:function(i,r){return r.qs?typeof r.qs=="object"?i+"&"+n.param(r.qs):typeof r.qs=="string"?i+"&"+r.qs:i+"&"+t.escape(r.qs.toString()):i},getUrl:function(n,i,r,u){var o=i==="webSockets"?"":n.baseUrl,f=o+n.appRelativeUrl,e="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(e+="&connectionData="+t.escape(n.data)),r?(u&&(f=f+"/reconnect"),n.messageId&&(e+="&messageId="+n.messageId),n.groups&&(e+="&groups="+t.escape(JSON.stringify(n.groups)))):f=f+"/connect",f+="?"+e,f=this.addQs(f,n),f+="&tid="+Math.floor(Math.random()*11)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);return f=this.addQs(f,r),n.ajax({url:f,global:!1,type:"POST",dataType:r.ajaxDataType,data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){u!=="abort"&&(u!=="parsererror"||r.ajaxDataType!=="jsonp")&&n(r).trigger(i.onError,[t])}})},ajaxAbort:function(i,r){if(typeof i.transport!="undefined"){r=typeof r=="undefined"?!0:r;var u=i.url+"/abort?transport="+i.transport.name+"&connectionId="+t.escape(i.id);u=this.addQs(u,i),n.ajax({url:u,async:r,timeout:1e3,global:!1,type:"POST",dataType:i.ajaxDataType,data:{}}),i.log("Fired ajax abort async = "+r)}},processMessages:function(t,r){var u=n(t);if(r){if(r.Disconnect){t.log("Disconnect command received from server"),t.stop();return}r.Messages&&n.each(r.Messages,function(){try{u.trigger(i.onReceived,[this])}catch(r){t.log("Error raising received "+r),n(t).trigger(i.onError,[r])}}),r.MessageId&&(t.messageId=r.MessageId),r.TransportData&&(t.groups=r.TransportData.Groups)}},foreverFrame:{count:0,connections:{}}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,r=n.signalR.events,f=n.signalR.changeState,u=i.transports._logic;i.transports.webSockets={name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(e,o,s){var h,a=!1,l=this,c=!o,v=n(e);if(t.MozWebSocket&&(t.WebSocket=t.MozWebSocket),!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,n(e).trigger(r.onSending),h+=u.getUrl(e,this.name,c),e.log("Connecting to websocket endpoint '"+h+"'"),e.socket=new t.WebSocket(h),e.socket.onopen=function(){a=!0,e.log("Websocket opened"),o?o():f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&v.trigger(r.onReconnect)},e.socket.onclose=function(t){if(a)typeof t.wasClean!="undefined"&&t.wasClean===!1?(n(e).trigger(r.onError,[t.reason]),e.log("Unclean disconnect from websocket."+t.reason)):e.log("Websocket closed");else{s?s():c&&l.reconnect(e);return}l.reconnect(e)},e.socket.onmessage=function(i){var f=t.JSON.parse(i.data),o;f&&(o=n(e),f.Messages?u.processMessages(e,f):o.trigger(r.onReceived,[f]))})},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("Websocket reconnecting"),r.start(n))},n.reconnectDelay)},stop:function(n){n.socket!==null&&(n.log("Closing the Websocket"),n.socket.close(),n.socket=null)},abort:function(){}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,r=i.transports._logic;i.transports.serverSentEvents={name:"serverSentEvents",timeOut:3e3,start:function(e,o,s){var c=this,a=!1,l=n(e),h=!o,y,v;if(e.eventSource&&(e.log("The connection already has an event source. Stopping it."),e.stop()),!t.EventSource){s&&(e.log("This browser doesn't support SSE."),s());return}l.trigger(u.onSending),y=r.getUrl(e,this.name,h);try{e.log("Attempting to connect to SSE endpoint '"+y+"'"),e.eventSource=new t.EventSource(y)}catch(p){e.log("EventSource failed trying to connect with error "+p.Message),s?s():(l.trigger(u.onError,[p]),h&&c.reconnect(e));return}v=t.setTimeout(function(){a===!1&&(e.log("EventSource timed out trying to connect"),e.log("EventSource readyState: "+e.eventSource.readyState),h||c.stop(e),h?e.eventSource.readyState!==t.EventSource.CONNECTING&&e.eventSource.readyState!==t.EventSource.OPEN&&c.reconnect(e):s&&s())},c.timeOut),e.eventSource.addEventListener("open",function(){e.log("EventSource connected"),v&&t.clearTimeout(v),a===!1&&(a=!0,o&&o(),h&&f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&l.trigger(u.onReconnect))},!1),e.eventSource.addEventListener("message",function(n){n.data!=="initialized"&&r.processMessages(e,t.JSON.parse(n.data))},!1),e.eventSource.addEventListener("error",function(n){if(!a){s&&s();return}e.log("EventSource readyState: "+e.eventSource.readyState),n.eventPhase===t.EventSource.CLOSED?(e.log("EventSource reconnecting due to the server connection ending"),c.reconnect(e)):(e.log("EventSource error"),l.trigger(u.onError))},!1)},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("EventSource reconnecting"),r.start(n))},n.reconnectDelay)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.log("EventSource calling close()"),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.foreverFrame={name:"foreverFrame",timeOut:3e3,start:function(r,f,e){var s=this,h=i.foreverFrame.count+=1,c,l,o=n("<iframe data-signalr-connection-id='"+r.id+"' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''></iframe>");if(t.EventSource){e&&(r.log("This brower supports SSE, skipping Forever Frame."),e());return}n(r).trigger(u.onSending),c=i.getUrl(r,this.name),c+="&frameId="+h,o.prop("src",c),i.foreverFrame.connections[h]=r,r.log("Binding to iframe's readystatechange event."),o.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])>=0&&(r.log("Forever frame iframe readyState changed to "+this.readyState+", reconnecting"),s.reconnect(r))}),r.frame=o[0],r.frameId=h,f&&(r.onSuccess=f),n("body").append(o),l=t.setTimeout(function(){r.onSuccess&&(r.log("Failed to connect using forever frame source, it timed out after "+s.timeOut+"ms."),s.stop(r),e&&e())},s.timeOut)},reconnect:function(n){var u=this;t.setTimeout(function(){if(n.frame&&(n.state===r.connectionState.reconnecting||f(n,r.connectionState.connected,r.connectionState.reconnecting)===!0)){var e=n.frame,t=i.getUrl(n,u.name,!0)+"&frameId="+n.frameId;n.log("Upating iframe src to '"+t+"'."),e.src=t}},n.reconnectDelay)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,r){var u;i.processMessages(t,r),t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>50&&(t.frameMessageCount=0,u=t.frame.contentWindow||t.frame.contentDocument,u&&u.document&&n("body",u.document).empty())},stop:function(t){var r=null;t.frame&&(t.frame.stop?t.frame.stop():(r=t.frame.contentWindow||t.frame.contentDocument,r.document&&r.document.execCommand&&r.document.execCommand("Stop")),n(t.frame).remove(),delete i.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId,t.log("Stopping forever frame"))},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):f(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).trigger(u.onReconnect)}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,e=n.signalR.isDisconnecting,r=i.transports._logic;i.transports.longPolling={name:"longPolling",reconnectDelay:3e3,start:function(o,s){var l=this,c=!1;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop()),o.messageId=null,t.setTimeout(function(){(function h(a,v){n(a).trigger(u.onSending);var d=a.messageId,k=d===null,b=!k,w=r.getUrl(a,l.name,b,v),p=null,y=!1;(b!==!0||v!==!0||o.state===i.connectionState.reconnecting||f(o,i.connectionState.connected,i.connectionState.reconnecting)!==!1)&&(o.log("Attempting to connect to '"+w+"' using longPolling."),a.pollXhr=n.ajax({url:w,global:!1,cache:!1,type:"GET",dataType:o.ajaxDataType,success:function(l){var w=0,p=!1;(c===!1&&(s(),c=!0),v===!0&&y===!1&&(o.log("Raising the reconnect event"),f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)),r.processMessages(a,l),l&&l.TransportData&&n.type(l.TransportData.LongPollDelay)==="number"&&(w=l.TransportData.LongPollDelay),l&&l.TimedOut&&(p=l.TimedOut),l&&l.Disconnect)||e(a)!==!0&&(w>0?t.setTimeout(function(){h(a,p)},w):h(a,p))},error:function(i,r){if(r==="abort"){o.log("Aborted xhr requst.");return}o.log("An error occurred using longPolling. Status = "+r+". "+i.responseText),p&&t.clearTimeout(p),n(a).trigger(u.onError,[i.responseText]),t.setTimeout(function(){e(a)===!1&&h(a,!0)},o.reconnectDelay)}}),v===!0&&(p=t.setTimeout(function(){y===!1&&f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)},l.reconnectDelay)))})(o),t.setTimeout(function(){c===!1&&(s(),c=!0)},150)},250)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";function o(t){return n.isFunction(t)?null:n.type(t)==="undefined"?null:t}function r(n,t){return new r.fn.init(n,t)}function i(n){return n||(n="/signalr"),new i.fn.init(n)}var f=0,u={},e="proxy.";Array.prototype.hasOwnProperty("map")||(Array.prototype.map=function(n,t){for(var r=this,f=r.length,u=[],i=0;i<f;i+=1)r.hasOwnProperty(i)&&(u[i]=n.call(t,r[i],i,r));return u}),r.fn=r.prototype={init:function(n,t){this.state={},this.connection=n,this.hubName=t,this.subscribed=!1},on:function(t,i){var r=this;return t=t.toLowerCase(),n(r).bind(e+t,function(n,t){i.apply(r,t)}),r.subscribed=!0,r},invoke:function(i){var r=this,e=n.makeArray(arguments).slice(1),h=e[e.length-1],a=n.type(h)==="function"?e.slice(0,e.length-1):e,v=a.map(o),l={hub:r.hubName,method:i,args:v,state:r.state,id:f},s=n.Deferred(),c=function(t){n.extend(this.state,t.State),t.Error?(t.StackTrace&&r.connection.log(t.Error+"\n"+t.StackTrace),s.rejectWith(r,[t.Error])):(n.type(h)==="function"&&h.call(r,t.Result),s.resolveWith(r,[t.Result]))};return u[f.toString()]={scope:r,method:c},f+=1,r.connection.send(t.JSON.stringify(l)),s.promise()}},r.fn.init.prototype=r.fn,i.fn=i.prototype=n.connection(),i.fn.init=function(i,r,f){var o=this;n.signalR.fn.init.call(o,i,r,f),o.proxies={},o.sending(function(){var i=[];n.each(this.proxies,function(n){this.subscribed&&i.push({name:n})}),this.data=t.JSON.stringify(i)}),o.received(function(t){var f,r,i,s,o;t&&(typeof t.Id!="undefined"?(r=t.Id.toString(),i=u[r],i&&(u[r]=null,delete u[r],i.method.call(i.scope,t))):(s=t.Hub.toLowerCase(),o=t.Method.toLowerCase(),f=this.proxies[s],n.extend(f.state,t.State),n(f).trigger(e+o,[t.Args])))})},i.fn.createProxy=function(n){n=n.toLowerCase();var t=this.proxies[n];return t||(t=r(this,n),this.proxies[n]=t),t},i.fn.init.prototype=i.fn,n.hubConnection=i}(window.jQuery,window)
141  samples/SignalR.Hosting.Owin.Samples/Content/Scripts/jquery.signalR.js
@@ -25,6 +25,8 @@
25 25
     
26 26
     var signalR,
27 27
         _connection,
  28
+        _pageLoaded = false,
  29
+        _pageWindow = $(window),
28 30
 
29 31
         events = {
30 32
             onStart: "onStart",
@@ -119,6 +121,8 @@
119 121
         }
120 122
     };
121 123
 
  124
+    _pageWindow.load(function () { _pageLoaded = true; });
  125
+
122 126
     signalR.fn = signalR.prototype = {
123 127
         init: function (url, qs, logging) {
124 128
             this.url = url;
@@ -142,20 +146,13 @@
142 146
             /// <param name="callback" type="Function">A callback function to execute when the connection has started</param>
143 147
             var connection = this,
144 148
                 config = {
  149
+                    waitForPageLoad: true,
145 150
                     transport: "auto",
146 151
                     jsonp: false
147 152
                 },
148 153
                 initialize,
149  
-                deferred = $.Deferred(),
150  
-                parser = window.document.createElement("a");
151  
-
152  
-            if (changeState(connection,
153  
-                            signalR.connectionState.disconnected,
154  
-                            signalR.connectionState.connecting) === false) {
155  
-                // Already started, just return
156  
-                deferred.resolve(connection);
157  
-                return deferred.promise();
158  
-            }
  154
+                deferred = connection.deferral || $.Deferred(),// Check to see if there is a pre-existing deferral that's being built on, if so we want to keep using it
  155
+                parser = window.document.createElement("a");            
159 156
 
160 157
             if ($.type(options) === "function") {
161 158
                 // Support calling with single callback parameter
@@ -167,6 +164,24 @@
167 164
                 }
168 165
             }
169 166
 
  167
+            // Check to see if start is being called prior to page load
  168
+            // If waitForPageLoad is true we then want to re-direct function call to the window load event
  169
+            if (!_pageLoaded && config.waitForPageLoad === true) {
  170
+                _pageWindow.load(function () {
  171
+                    connection.deferral = deferred;
  172
+                    connection.start(options, callback);
  173
+                });
  174
+                return deferred.promise();
  175
+            }
  176
+
  177
+            if (changeState(connection,
  178
+                            signalR.connectionState.disconnected,
  179
+                            signalR.connectionState.connecting) === false) {
  180
+                // Already started, just return
  181
+                deferred.resolve(connection);
  182
+                return deferred.promise();
  183
+            }
  184
+
170 185
             // Resolve the full url
171 186
             parser.href = connection.url;
172 187
             if (!parser.protocol || parser.protocol === ":") {
@@ -249,7 +264,7 @@
249 264
 
250 265
                     $(connection).trigger(events.onStart);
251 266
 
252  
-                    $(window).unload(function () { // failure
  267
+                    _pageWindow.unload(function () { // failure
253 268
                         connection.stop(false /* async */);
254 269
                     });
255 270
 
@@ -258,65 +273,63 @@
258 273
                 });
259 274
             };
260 275
 
261  
-            window.setTimeout(function () {
262  
-                var url = connection.url + "/negotiate";
263  
-                connection.log("Negotiating with '" + url + "'.");
264  
-                $.ajax({
265  
-                    url: url,
266  
-                    global: false,
267  
-                    cache: false,
268  
-                    type: "GET",
269  
-                    data: {},
270  
-                    dataType: connection.ajaxDataType,
271  
-                    error: function (error) {
272  
-                        $(connection).trigger(events.onError, [error.responseText]);
273  
-                        deferred.reject("SignalR: Error during negotiation request: " + error.responseText);
274  
-                        // Stop the connection if negotiate failed
275  
-                        connection.stop();
276  
-                    },
277  
-                    success: function (res) {
278  
-                        connection.appRelativeUrl = res.Url;
279  
-                        connection.id = res.ConnectionId;
280  
-                        connection.webSocketServerUrl = res.WebSocketServerUrl;
281  
-
282  
-                        if (!res.ProtocolVersion || res.ProtocolVersion !== "1.0") {
283  
-                            $(connection).trigger(events.onError, "SignalR: Incompatible protocol version.");
284  
-                            deferred.reject("SignalR: Incompatible protocol version.");
285  
-                            return;
286  
-                        }
  276
+            var url = connection.url + "/negotiate";
  277
+            connection.log("Negotiating with '" + url + "'.");
  278
+            $.ajax({
  279
+                url: url,
  280
+                global: false,
  281
+                cache: false,
  282
+                type: "GET",
  283
+                data: {},
  284
+                dataType: connection.ajaxDataType,
  285
+                error: function (error) {
  286
+                    $(connection).trigger(events.onError, [error.responseText]);
  287
+                    deferred.reject("SignalR: Error during negotiation request: " + error.responseText);
  288
+                    // Stop the connection if negotiate failed
  289
+                    connection.stop();
  290
+                },
  291
+                success: function (res) {
  292
+                    connection.appRelativeUrl = res.Url;
  293
+                    connection.id = res.ConnectionId;
  294
+                    connection.webSocketServerUrl = res.WebSocketServerUrl;
  295
+
  296
+                    if (!res.ProtocolVersion || res.ProtocolVersion !== "1.0") {
  297
+                        $(connection).trigger(events.onError, "SignalR: Incompatible protocol version.");
  298
+                        deferred.reject("SignalR: Incompatible protocol version.");
  299
+                        return;
  300
+                    }
287 301
 
288  
-                        $(connection).trigger(events.onStarting);
  302
+                    $(connection).trigger(events.onStarting);
289 303
 
290  
-                        var transports = [],
291  
-                            supportedTransports = [];
  304
+                    var transports = [],
  305
+                        supportedTransports = [];
292 306
 
293  
-                        $.each(signalR.transports, function (key) {
294  
-                            if (key === "webSockets" && !res.TryWebSockets) {
295  
-                                // Server said don't even try WebSockets, but keep processing the loop
296  
-                                return true;
  307
+                    $.each(signalR.transports, function (key) {
  308
+                        if (key === "webSockets" && !res.TryWebSockets) {
  309
+                            // Server said don't even try WebSockets, but keep processing the loop
  310
+                            return true;
  311
+                        }
  312
+                        supportedTransports.push(key);
  313
+                    });
  314
+
  315
+                    if ($.isArray(config.transport)) {
  316
+                        // ordered list provided
  317
+                        $.each(config.transport, function () {
  318
+                            var transport = this;
  319
+                            if ($.type(transport) === "object" || ($.type(transport) === "string" && $.inArray("" + transport, supportedTransports) >= 0)) {
  320
+                                transports.push($.type(transport) === "string" ? "" + transport : transport);
297 321
                             }
298  
-                            supportedTransports.push(key);
299 322
                         });
300  
-
301  
-                        if ($.isArray(config.transport)) {
302  
-                            // ordered list provided
303  
-                            $.each(config.transport, function () {
304  
-                                var transport = this;
305  
-                                if ($.type(transport) === "object" || ($.type(transport) === "string" && $.inArray("" + transport, supportedTransports) >= 0)) {
306  
-                                    transports.push($.type(transport) === "string" ? "" + transport : transport);
307  
-                                }
308  
-                            });
309  
-                        } else if ($.type(config.transport) === "object" ||
310  
-                                       $.inArray(config.transport, supportedTransports) >= 0) {
311  
-                                // specific transport provided, as object or a named transport, e.g. "longPolling"
312  
-                            transports.push(config.transport);
313  
-                        } else { // default "auto"
314  
-                            transports = supportedTransports;
315  
-                        }
316  
-                        initialize(transports);
  323
+                    } else if ($.type(config.transport) === "object" ||
  324
+                                    $.inArray(config.transport, supportedTransports) >= 0) {
  325
+                            // specific transport provided, as object or a named transport, e.g. "longPolling"
  326
+                        transports.push(config.transport);
  327
+                    } else { // default "auto"
  328
+                        transports = supportedTransports;
317 329
                     }
318  
-                });
319  
-            }, 0);
  330
+                    initialize(transports);
  331
+                }
  332
+            });
320 333
 
321 334
             return deferred.promise();
322 335
         },
2  samples/SignalR.Hosting.Owin.Samples/Content/Scripts/jquery.signalR.min.js
@@ -6,4 +6,4 @@
6 6
  * Licensed under the MIT.
7 7
  * https://github.com/SignalR/SignalR/blob/master/LICENSE.md
8 8
  */
9  
-(function(n,t){"use strict";if(typeof n!="function")throw"SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";if(!t.JSON)throw"SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";var i,f,r={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},o=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},s=function(i){var r;return(i=n.trim(i),i.indexOf("http")!==0)?!1:(r=t.document.createElement("a"),r.href=i,r.protocol+r.host!==t.location.protocol+t.location.host)},u=function(t,i,u){return i===t.state?(n(t).trigger(r.onStateChanged,[{oldState:t.state,newState:u}]),t.state=u,!0):!1},e=function(n){return n.state===i.connectionState.disconnected};i=function(n,t,r){return new i.fn.init(n,t,r)},i.events=r,i.changeState=u,i.isDisconnecting=e,i.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4},i.hub={start:function(){throw"SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/hubs'><\/script>.";}},i.fn=i.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},ajaxDataType:"json",logging:!1,state:i.connectionState.disconnected,reconnectDelay:2e3,start:function(f,e){var o=this,h={transport:"auto",jsonp:!1},a,l=n.Deferred(),c=t.document.createElement("a");return u(o,i.connectionState.disconnected,i.connectionState.connecting)===!1?(l.resolve(o),l.promise()):(n.type(f)==="function"?e=f:n.type(f)==="object"&&(n.extend(h,f),n.type(h.callback)==="function"&&(e=h.callback)),c.href=o.url,c.protocol&&c.protocol!==":"?(o.protocol=c.protocol,o.host=c.host,o.baseUrl=c.protocol+"//"+c.host):(o.protocol=t.document.location.protocol,o.host=t.document.location.host,o.baseUrl=o.protocol+"//"+o.host),o.wsProtocol=o.protocol==="https:"?"wss://":"ws://",s(o.url)&&(o.log("Auto detected cross domain url."),h.transport==="auto"&&(h.jsonp||(h.jsonp=!n.support.cors,h.jsonp&&o.log("Using jsonp because this browser doesn't support CORS")),h.transport=h.jsonp===!0?"longPolling":["webSockets","longPolling"])),o.ajaxDataType=h.jsonp?"jsonp":"json",n(o).bind(r.onStart,function(){n.type(e)==="function"&&e.call(o),l.resolve(o)}),a=function(f,e){if(e=e||0,e>=f.length){o.transport||(n(o).trigger(r.onError,"SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),l.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),o.stop());return}var s=f[e],h=n.type(s)==="object"?s:i.transports[s];if(s.indexOf("_")===0){a(f,e+1);return}h.start(o,function(){o.transport=h,u(o,i.connectionState.connecting,i.connectionState.connected),n(o).trigger(r.onStart),n(t).unload(function(){o.stop(!1)})},function(){a(f,e+1)})},t.setTimeout(function(){var t=o.url+"/negotiate";o.log("Negotiating with '"+t+"'."),n.ajax({url:t,global:!1,cache:!1,type:"GET",data:{},dataType:o.ajaxDataType,error:function(t){n(o).trigger(r.onError,[t.responseText]),l.reject("SignalR: Error during negotiation request: "+t.responseText),o.stop()},success:function(t){if(o.appRelativeUrl=t.Url,o.id=t.ConnectionId,o.webSocketServerUrl=t.WebSocketServerUrl,!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(o).trigger(r.onError,"SignalR: Incompatible protocol version."),l.reject("SignalR: Incompatible protocol version.");return}n(o).trigger(r.onStarting);var f=[],u=[];n.each(i.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;u.push(n)}),n.isArray(h.transport)?n.each(h.transport,function(){var t=this;(n.type(t)==="object"||n.type(t)==="string"&&n.inArray(""+t,u)>=0)&&f.push(n.type(t)==="string"?""+t:t)}):n.type(h.transport)==="object"||n.inArray(h.transport,u)>=0?f.push(h.transport):f=u,a(f)}})},0),l.promise())},starting:function(t){var i=this,u=n(i);return u.bind(r.onStarting,function(){t.call(i),u.unbind(r.onStarting)}),i},send:function(n){var t=this;if(t.state===i.connectionState.disconnected)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";if(t.state===i.connectionState.connecting)throw"SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.";return t.transport.send(t,n),t},sending:function(t){var i=this;return n(i).bind(r.onSending,function(){t.call(i)}),i},received:function(t){var i=this;return n(i).bind(r.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(r.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(r.onError,function(n,r){t.call(i,r)}),i},disconnected:function(t){var i=this;return n(i).bind(r.onDisconnect,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(r.onReconnect,function(){t.call(i)}),i},stop:function(t){var f=this;if(f.state!==i.connectionState.disconnected){try{f.transport&&(f.transport.abort(f,t),f.transport.stop(f),f.transport=null),n(f).trigger(r.onDisconnect),delete f.messageId,delete f.groups}finally{u(f,f.state,i.connectionState.disconnected)}return f}},log:function(n){o(n,this.logging)}},i.fn.init.prototype=i.fn,i.noConflict=function(){return n.connection===i&&(n.connection=f),i},n.connection&&(f=n.connection),n.connection=n.signalR=i})(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,i=n.signalR.events;r.transports={},r.transports._logic={addQs:function(i,r){return r.qs?typeof r.qs=="object"?i+"&"+n.param(r.qs):typeof r.qs=="string"?i+"&"+r.qs:i+"&"+t.escape(r.qs.toString()):i},getUrl:function(n,i,r,u){var o=i==="webSockets"?"":n.baseUrl,f=o+n.appRelativeUrl,e="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(e+="&connectionData="+t.escape(n.data)),r?(u&&(f=f+"/reconnect"),n.messageId&&(e+="&messageId="+n.messageId),n.groups&&(e+="&groups="+t.escape(JSON.stringify(n.groups)))):f=f+"/connect",f+="?"+e,f=this.addQs(f,n),f+="&tid="+Math.floor(Math.random()*11)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);return f=this.addQs(f,r),n.ajax({url:f,global:!1,type:"POST",dataType:r.ajaxDataType,data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){u!=="abort"&&(u!=="parsererror"||r.ajaxDataType!=="jsonp")&&n(r).trigger(i.onError,[t])}})},ajaxAbort:function(i,r){if(typeof i.transport!="undefined"){r=typeof r=="undefined"?!0:r;var u=i.url+"/abort?transport="+i.transport.name+"&connectionId="+t.escape(i.id);u=this.addQs(u,i),n.ajax({url:u,async:r,timeout:1e3,global:!1,type:"POST",dataType:i.ajaxDataType,data:{}}),i.log("Fired ajax abort async = "+r)}},processMessages:function(t,r){var u=n(t);if(r){if(r.Disconnect){t.log("Disconnect command received from server"),t.stop();return}r.Messages&&n.each(r.Messages,function(){try{u.trigger(i.onReceived,[this])}catch(r){t.log("Error raising received "+r),n(t).trigger(i.onError,[r])}}),r.MessageId&&(t.messageId=r.MessageId),r.TransportData&&(t.groups=r.TransportData.Groups)}},foreverFrame:{count:0,connections:{}}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,r=n.signalR.events,f=n.signalR.changeState,u=i.transports._logic;i.transports.webSockets={name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(e,o,s){var h,a=!1,l=this,c=!o,v=n(e);if(t.MozWebSocket&&(t.WebSocket=t.MozWebSocket),!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,n(e).trigger(r.onSending),h+=u.getUrl(e,this.name,c),e.log("Connecting to websocket endpoint '"+h+"'"),e.socket=new t.WebSocket(h),e.socket.onopen=function(){a=!0,e.log("Websocket opened"),o?o():f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&v.trigger(r.onReconnect)},e.socket.onclose=function(t){if(a)typeof t.wasClean!="undefined"&&t.wasClean===!1?(n(e).trigger(r.onError,[t.reason]),e.log("Unclean disconnect from websocket."+t.reason)):e.log("Websocket closed");else{s?s():c&&l.reconnect(e);return}l.reconnect(e)},e.socket.onmessage=function(i){var f=t.JSON.parse(i.data),o;f&&(o=n(e),f.Messages?u.processMessages(e,f):o.trigger(r.onReceived,[f]))})},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("Websocket reconnecting"),r.start(n))},n.reconnectDelay)},stop:function(n){n.socket!==null&&(n.log("Closing the Websocket"),n.socket.close(),n.socket=null)},abort:function(){}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,r=i.transports._logic;i.transports.serverSentEvents={name:"serverSentEvents",timeOut:3e3,start:function(e,o,s){var c=this,a=!1,l=n(e),h=!o,y,v;if(e.eventSource&&(e.log("The connection already has an event source. Stopping it."),e.stop()),!t.EventSource){s&&(e.log("This browser doesn't support SSE."),s());return}l.trigger(u.onSending),y=r.getUrl(e,this.name,h);try{e.log("Attempting to connect to SSE endpoint '"+y+"'"),e.eventSource=new t.EventSource(y)}catch(p){e.log("EventSource failed trying to connect with error "+p.Message),s?s():(l.trigger(u.onError,[p]),h&&c.reconnect(e));return}v=t.setTimeout(function(){a===!1&&(e.log("EventSource timed out trying to connect"),e.log("EventSource readyState: "+e.eventSource.readyState),h||c.stop(e),h?e.eventSource.readyState!==t.EventSource.CONNECTING&&e.eventSource.readyState!==t.EventSource.OPEN&&c.reconnect(e):s&&s())},c.timeOut),e.eventSource.addEventListener("open",function(){e.log("EventSource connected"),v&&t.clearTimeout(v),a===!1&&(a=!0,o&&o(),h&&f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&l.trigger(u.onReconnect))},!1),e.eventSource.addEventListener("message",function(n){n.data!=="initialized"&&r.processMessages(e,t.JSON.parse(n.data))},!1),e.eventSource.addEventListener("error",function(n){if(!a){s&&s();return}e.log("EventSource readyState: "+e.eventSource.readyState),n.eventPhase===t.EventSource.CLOSED?(e.log("EventSource reconnecting due to the server connection ending"),c.reconnect(e)):(e.log("EventSource error"),l.trigger(u.onError))},!1)},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("EventSource reconnecting"),r.start(n))},n.reconnectDelay)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.log("EventSource calling close()"),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.foreverFrame={name:"foreverFrame",timeOut:3e3,start:function(r,f,e){var s=this,h=i.foreverFrame.count+=1,c,l,o=n("<iframe data-signalr-connection-id='"+r.id+"' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''></iframe>");if(t.EventSource){e&&(r.log("This brower supports SSE, skipping Forever Frame."),e());return}n(r).trigger(u.onSending),c=i.getUrl(r,this.name),c+="&frameId="+h,o.prop("src",c),i.foreverFrame.connections[h]=r,r.log("Binding to iframe's readystatechange event."),o.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])>=0&&(r.log("Forever frame iframe readyState changed to "+this.readyState+", reconnecting"),s.reconnect(r))}),r.frame=o[0],r.frameId=h,f&&(r.onSuccess=f),n("body").append(o),l=t.setTimeout(function(){r.onSuccess&&(r.log("Failed to connect using forever frame source, it timed out after "+s.timeOut+"ms."),s.stop(r),e&&e())},s.timeOut)},reconnect:function(n){var u=this;t.setTimeout(function(){if(n.frame&&(n.state===r.connectionState.reconnecting||f(n,r.connectionState.connected,r.connectionState.reconnecting)===!0)){var e=n.frame,t=i.getUrl(n,u.name,!0)+"&frameId="+n.frameId;n.log("Upating iframe src to '"+t+"'."),e.src=t}},n.reconnectDelay)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,r){var u;i.processMessages(t,r),t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>50&&(t.frameMessageCount=0,u=t.frame.contentWindow||t.frame.contentDocument,u&&u.document&&n("body",u.document).empty())},stop:function(t){var r=null;t.frame&&(t.frame.stop?t.frame.stop():(r=t.frame.contentWindow||t.frame.contentDocument,r.document&&r.document.execCommand&&r.document.execCommand("Stop")),n(t.frame).remove(),delete i.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId,t.log("Stopping forever frame"))},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):f(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).trigger(u.onReconnect)}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,e=n.signalR.isDisconnecting,r=i.transports._logic;i.transports.longPolling={name:"longPolling",reconnectDelay:3e3,start:function(o,s){var l=this,c=!1;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop()),o.messageId=null,t.setTimeout(function(){(function h(a,v){n(a).trigger(u.onSending);var d=a.messageId,k=d===null,b=!k,w=r.getUrl(a,l.name,b,v),p=null,y=!1;(b!==!0||v!==!0||o.state===i.connectionState.reconnecting||f(o,i.connectionState.connected,i.connectionState.reconnecting)!==!1)&&(o.log("Attempting to connect to '"+w+"' using longPolling."),a.pollXhr=n.ajax({url:w,global:!1,cache:!1,type:"GET",dataType:o.ajaxDataType,success:function(l){var w=0,p=!1;(c===!1&&(s(),c=!0),v===!0&&y===!1&&(o.log("Raising the reconnect event"),f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)),r.processMessages(a,l),l&&l.TransportData&&n.type(l.TransportData.LongPollDelay)==="number"&&(w=l.TransportData.LongPollDelay),l&&l.TimedOut&&(p=l.TimedOut),l&&l.Disconnect)||e(a)!==!0&&(w>0?t.setTimeout(function(){h(a,p)},w):h(a,p))},error:function(i,r){if(r==="abort"){o.log("Aborted xhr requst.");return}o.log("An error occurred using longPolling. Status = "+r+". "+i.responseText),p&&t.clearTimeout(p),n(a).trigger(u.onError,[i.responseText]),t.setTimeout(function(){e(a)===!1&&h(a,!0)},o.reconnectDelay)}}),v===!0&&(p=t.setTimeout(function(){y===!1&&f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)},l.reconnectDelay)))})(o),t.setTimeout(function(){c===!1&&(s(),c=!0)},150)},250)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";function o(t){return n.isFunction(t)?null:n.type(t)==="undefined"?null:t}function r(n,t){return new r.fn.init(n,t)}function i(n){return n||(n="/signalr"),new i.fn.init(n)}var f=0,u={},e="proxy.";Array.prototype.hasOwnProperty("map")||(Array.prototype.map=function(n,t){for(var r=this,f=r.length,u=[],i=0;i<f;i+=1)r.hasOwnProperty(i)&&(u[i]=n.call(t,r[i],i,r));return u}),r.fn=r.prototype={init:function(n,t){this.state={},this.connection=n,this.hubName=t,this.subscribed=!1},on:function(t,i){var r=this;return t=t.toLowerCase(),n(r).bind(e+t,function(n,t){i.apply(r,t)}),r.subscribed=!0,r},invoke:function(i){var r=this,e=n.makeArray(arguments).slice(1),h=e[e.length-1],a=n.type(h)==="function"?e.slice(0,e.length-1):e,v=a.map(o),l={hub:r.hubName,method:i,args:v,state:r.state,id:f},s=n.Deferred(),c=function(t){n.extend(this.state,t.State),t.Error?(t.StackTrace&&r.connection.log(t.Error+"\n"+t.StackTrace),s.rejectWith(r,[t.Error])):(n.type(h)==="function"&&h.call(r,t.Result),s.resolveWith(r,[t.Result]))};return u[f.toString()]={scope:r,method:c},f+=1,r.connection.send(t.JSON.stringify(l)),s.promise()}},r.fn.init.prototype=r.fn,i.fn=i.prototype=n.connection(),i.fn.init=function(i,r,f){var o=this;n.signalR.fn.init.call(o,i,r,f),o.proxies={},o.sending(function(){var i=[];n.each(this.proxies,function(n){this.subscribed&&i.push({name:n})}),this.data=t.JSON.stringify(i)}),o.received(function(t){var f,r,i,s,o;t&&(typeof t.Id!="undefined"?(r=t.Id.toString(),i=u[r],i&&(u[r]=null,delete u[r],i.method.call(i.scope,t))):(s=t.Hub.toLowerCase(),o=t.Method.toLowerCase(),f=this.proxies[s],n.extend(f.state,t.State),n(f).trigger(e+o,[t.Args])))})},i.fn.createProxy=function(n){n=n.toLowerCase();var t=this.proxies[n];return t||(t=r(this,n),this.proxies[n]=t),t},i.fn.init.prototype=i.fn,n.hubConnection=i}(window.jQuery,window)
  9
+(function(n,t){"use strict";if(typeof n!="function")throw"SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";if(!t.JSON)throw"SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";var i,e,o=!1,f=n(t),r={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},h=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},c=function(i){var r;return(i=n.trim(i),i.indexOf("http")!==0)?!1:(r=t.document.createElement("a"),r.href=i,r.protocol+r.host!==t.location.protocol+t.location.host)},u=function(t,i,u){return i===t.state?(n(t).trigger(r.onStateChanged,[{oldState:t.state,newState:u}]),t.state=u,!0):!1},s=function(n){return n.state===i.connectionState.disconnected};i=function(n,t,r){return new i.fn.init(n,t,r)},i.events=r,i.changeState=u,i.isDisconnecting=s,i.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4},i.hub={start:function(){throw"SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/hubs'><\/script>.";}},f.load(function(){o=!0}),i.fn=i.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},ajaxDataType:"json",logging:!1,state:i.connectionState.disconnected,reconnectDelay:2e3,start:function(e,s){var h=this,l={waitForPageLoad:!0,transport:"auto",jsonp:!1},y,a=h.deferral||n.Deferred(),v=t.document.createElement("a"),p;return(n.type(e)==="function"?s=e:n.type(e)==="object"&&(n.extend(l,e),n.type(l.callback)==="function"&&(s=l.callback)),!o&&l.waitForPageLoad===!0)?(f.load(function(){h.deferral=a,h.start(e,s)}),a.promise()):u(h,i.connectionState.disconnected,i.connectionState.connecting)===!1?(a.resolve(h),a.promise()):(v.href=h.url,v.protocol&&v.protocol!==":"?(h.protocol=v.protocol,h.host=v.host,h.baseUrl=v.protocol+"//"+v.host):(h.protocol=t.document.location.protocol,h.host=t.document.location.host,h.baseUrl=h.protocol+"//"+h.host),h.wsProtocol=h.protocol==="https:"?"wss://":"ws://",c(h.url)&&(h.log("Auto detected cross domain url."),l.transport==="auto"&&(l.jsonp||(l.jsonp=!n.support.cors,l.jsonp&&h.log("Using jsonp because this browser doesn't support CORS")),l.transport=l.jsonp===!0?"longPolling":["webSockets","longPolling"])),h.ajaxDataType=l.jsonp?"jsonp":"json",n(h).bind(r.onStart,function(){n.type(s)==="function"&&s.call(h),a.resolve(h)}),y=function(t,e){if(e=e||0,e>=t.length){h.transport||(n(h).trigger(r.onError,"SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),a.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."),h.stop());return}var o=t[e],s=n.type(o)==="object"?o:i.transports[o];if(o.indexOf("_")===0){y(t,e+1);return}s.start(h,function(){h.transport=s,u(h,i.connectionState.connecting,i.connectionState.connected),n(h).trigger(r.onStart),f.unload(function(){h.stop(!1)})},function(){y(t,e+1)})},p=h.url+"/negotiate",h.log("Negotiating with '"+p+"'."),n.ajax({url:p,global:!1,cache:!1,type:"GET",data:{},dataType:h.ajaxDataType,error:function(t){n(h).trigger(r.onError,[t.responseText]),a.reject("SignalR: Error during negotiation request: "+t.responseText),h.stop()},success:function(t){if(h.appRelativeUrl=t.Url,h.id=t.ConnectionId,h.webSocketServerUrl=t.WebSocketServerUrl,!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(h).trigger(r.onError,"SignalR: Incompatible protocol version."),a.reject("SignalR: Incompatible protocol version.");return}n(h).trigger(r.onStarting);var f=[],u=[];n.each(i.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;u.push(n)}),n.isArray(l.transport)?n.each(l.transport,function(){var t=this;(n.type(t)==="object"||n.type(t)==="string"&&n.inArray(""+t,u)>=0)&&f.push(n.type(t)==="string"?""+t:t)}):n.type(l.transport)==="object"||n.inArray(l.transport,u)>=0?f.push(l.transport):f=u,y(f)}}),a.promise())},starting:function(t){var i=this,u=n(i);return u.bind(r.onStarting,function(){t.call(i),u.unbind(r.onStarting)}),i},send:function(n){var t=this;if(t.state===i.connectionState.disconnected)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";if(t.state===i.connectionState.connecting)throw"SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.";return t.transport.send(t,n),t},sending:function(t){var i=this;return n(i).bind(r.onSending,function(){t.call(i)}),i},received:function(t){var i=this;return n(i).bind(r.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(r.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(r.onError,function(n,r){t.call(i,r)}),i},disconnected:function(t){var i=this;return n(i).bind(r.onDisconnect,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(r.onReconnect,function(){t.call(i)}),i},stop:function(t){var f=this;if(f.state!==i.connectionState.disconnected){try{f.transport&&(f.transport.abort(f,t),f.transport.stop(f),f.transport=null),n(f).trigger(r.onDisconnect),delete f.messageId,delete f.groups}finally{u(f,f.state,i.connectionState.disconnected)}return f}},log:function(n){h(n,this.logging)}},i.fn.init.prototype=i.fn,i.noConflict=function(){return n.connection===i&&(n.connection=e),i},n.connection&&(e=n.connection),n.connection=n.signalR=i})(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,i=n.signalR.events;r.transports={},r.transports._logic={addQs:function(i,r){return r.qs?typeof r.qs=="object"?i+"&"+n.param(r.qs):typeof r.qs=="string"?i+"&"+r.qs:i+"&"+t.escape(r.qs.toString()):i},getUrl:function(n,i,r,u){var o=i==="webSockets"?"":n.baseUrl,f=o+n.appRelativeUrl,e="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(e+="&connectionData="+t.escape(n.data)),r?(u&&(f=f+"/reconnect"),n.messageId&&(e+="&messageId="+n.messageId),n.groups&&(e+="&groups="+t.escape(JSON.stringify(n.groups)))):f=f+"/connect",f+="?"+e,f=this.addQs(f,n),f+="&tid="+Math.floor(Math.random()*11)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);return f=this.addQs(f,r),n.ajax({url:f,global:!1,type:"POST",dataType:r.ajaxDataType,data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){u!=="abort"&&(u!=="parsererror"||r.ajaxDataType!=="jsonp")&&n(r).trigger(i.onError,[t])}})},ajaxAbort:function(i,r){if(typeof i.transport!="undefined"){r=typeof r=="undefined"?!0:r;var u=i.url+"/abort?transport="+i.transport.name+"&connectionId="+t.escape(i.id);u=this.addQs(u,i),n.ajax({url:u,async:r,timeout:1e3,global:!1,type:"POST",dataType:i.ajaxDataType,data:{}}),i.log("Fired ajax abort async = "+r)}},processMessages:function(t,r){var u=n(t);if(r){if(r.Disconnect){t.log("Disconnect command received from server"),t.stop();return}r.Messages&&n.each(r.Messages,function(){try{u.trigger(i.onReceived,[this])}catch(r){t.log("Error raising received "+r),n(t).trigger(i.onError,[r])}}),r.MessageId&&(t.messageId=r.MessageId),r.TransportData&&(t.groups=r.TransportData.Groups)}},foreverFrame:{count:0,connections:{}}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,r=n.signalR.events,f=n.signalR.changeState,u=i.transports._logic;i.transports.webSockets={name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(e,o,s){var h,a=!1,l=this,c=!o,v=n(e);if(t.MozWebSocket&&(t.WebSocket=t.MozWebSocket),!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,n(e).trigger(r.onSending),h+=u.getUrl(e,this.name,c),e.log("Connecting to websocket endpoint '"+h+"'"),e.socket=new t.WebSocket(h),e.socket.onopen=function(){a=!0,e.log("Websocket opened"),o?o():f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&v.trigger(r.onReconnect)},e.socket.onclose=function(t){if(a)typeof t.wasClean!="undefined"&&t.wasClean===!1?(n(e).trigger(r.onError,[t.reason]),e.log("Unclean disconnect from websocket."+t.reason)):e.log("Websocket closed");else{s?s():c&&l.reconnect(e);return}l.reconnect(e)},e.socket.onmessage=function(i){var f=t.JSON.parse(i.data),o;f&&(o=n(e),f.Messages?u.processMessages(e,f):o.trigger(r.onReceived,[f]))})},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("Websocket reconnecting"),r.start(n))},n.reconnectDelay)},stop:function(n){n.socket!==null&&(n.log("Closing the Websocket"),n.socket.close(),n.socket=null)},abort:function(){}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,r=i.transports._logic;i.transports.serverSentEvents={name:"serverSentEvents",timeOut:3e3,start:function(e,o,s){var c=this,a=!1,l=n(e),h=!o,y,v;if(e.eventSource&&(e.log("The connection already has an event source. Stopping it."),e.stop()),!t.EventSource){s&&(e.log("This browser doesn't support SSE."),s());return}l.trigger(u.onSending),y=r.getUrl(e,this.name,h);try{e.log("Attempting to connect to SSE endpoint '"+y+"'"),e.eventSource=new t.EventSource(y)}catch(p){e.log("EventSource failed trying to connect with error "+p.Message),s?s():(l.trigger(u.onError,[p]),h&&c.reconnect(e));return}v=t.setTimeout(function(){a===!1&&(e.log("EventSource timed out trying to connect"),e.log("EventSource readyState: "+e.eventSource.readyState),h||c.stop(e),h?e.eventSource.readyState!==t.EventSource.CONNECTING&&e.eventSource.readyState!==t.EventSource.OPEN&&c.reconnect(e):s&&s())},c.timeOut),e.eventSource.addEventListener("open",function(){e.log("EventSource connected"),v&&t.clearTimeout(v),a===!1&&(a=!0,o&&o(),h&&f(e,i.connectionState.reconnecting,i.connectionState.connected)===!0&&l.trigger(u.onReconnect))},!1),e.eventSource.addEventListener("message",function(n){n.data!=="initialized"&&r.processMessages(e,t.JSON.parse(n.data))},!1),e.eventSource.addEventListener("error",function(n){if(!a){s&&s();return}e.log("EventSource readyState: "+e.eventSource.readyState),n.eventPhase===t.EventSource.CLOSED?(e.log("EventSource reconnecting due to the server connection ending"),c.reconnect(e)):(e.log("EventSource error"),l.trigger(u.onError))},!1)},reconnect:function(n){var r=this;t.setTimeout(function(){r.stop(n),(n.state===i.connectionState.reconnecting||f(n,i.connectionState.connected,i.connectionState.reconnecting)===!0)&&(n.log("EventSource reconnecting"),r.start(n))},n.reconnectDelay)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.log("EventSource calling close()"),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";var r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.foreverFrame={name:"foreverFrame",timeOut:3e3,start:function(r,f,e){var s=this,h=i.foreverFrame.count+=1,c,l,o=n("<iframe data-signalr-connection-id='"+r.id+"' style='position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;' src=''></iframe>");if(t.EventSource){e&&(r.log("This brower supports SSE, skipping Forever Frame."),e());return}n(r).trigger(u.onSending),c=i.getUrl(r,this.name),c+="&frameId="+h,o.prop("src",c),i.foreverFrame.connections[h]=r,r.log("Binding to iframe's readystatechange event."),o.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])>=0&&(r.log("Forever frame iframe readyState changed to "+this.readyState+", reconnecting"),s.reconnect(r))}),r.frame=o[0],r.frameId=h,f&&(r.onSuccess=f),n("body").append(o),l=t.setTimeout(function(){r.onSuccess&&(r.log("Failed to connect using forever frame source, it timed out after "+s.timeOut+"ms."),s.stop(r),e&&e())},s.timeOut)},reconnect:function(n){var u=this;t.setTimeout(function(){if(n.frame&&(n.state===r.connectionState.reconnecting||f(n,r.connectionState.connected,r.connectionState.reconnecting)===!0)){var e=n.frame,t=i.getUrl(n,u.name,!0)+"&frameId="+n.frameId;n.log("Upating iframe src to '"+t+"'."),e.src=t}},n.reconnectDelay)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,r){var u;i.processMessages(t,r),t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>50&&(t.frameMessageCount=0,u=t.frame.contentWindow||t.frame.contentDocument,u&&u.document&&n("body",u.document).empty())},stop:function(t){var r=null;t.frame&&(t.frame.stop?t.frame.stop():(r=t.frame.contentWindow||t.frame.contentDocument,r.document&&r.document.execCommand&&r.document.execCommand("Stop")),n(t.frame).remove(),delete i.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId,t.log("Stopping forever frame"))},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):f(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).trigger(u.onReconnect)}}}(window.jQuery,window),function(n,t){"use strict";var i=n.signalR,u=n.signalR.events,f=n.signalR.changeState,e=n.signalR.isDisconnecting,r=i.transports._logic;i.transports.longPolling={name:"longPolling",reconnectDelay:3e3,start:function(o,s){var l=this,c=!1;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop()),o.messageId=null,t.setTimeout(function(){(function h(a,v){n(a).trigger(u.onSending);var d=a.messageId,k=d===null,b=!k,w=r.getUrl(a,l.name,b,v),p=null,y=!1;(b!==!0||v!==!0||o.state===i.connectionState.reconnecting||f(o,i.connectionState.connected,i.connectionState.reconnecting)!==!1)&&(o.log("Attempting to connect to '"+w+"' using longPolling."),a.pollXhr=n.ajax({url:w,global:!1,cache:!1,type:"GET",dataType:o.ajaxDataType,success:function(l){var w=0,p=!1;(c===!1&&(s(),c=!0),v===!0&&y===!1&&(o.log("Raising the reconnect event"),f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)),r.processMessages(a,l),l&&l.TransportData&&n.type(l.TransportData.LongPollDelay)==="number"&&(w=l.TransportData.LongPollDelay),l&&l.TimedOut&&(p=l.TimedOut),l&&l.Disconnect)||e(a)!==!0&&(w>0?t.setTimeout(function(){h(a,p)},w):h(a,p))},error:function(i,r){if(r==="abort"){o.log("Aborted xhr requst.");return}o.log("An error occurred using longPolling. Status = "+r+". "+i.responseText),p&&t.clearTimeout(p),n(a).trigger(u.onError,[i.responseText]),t.setTimeout(function(){e(a)===!1&&h(a,!0)},o.reconnectDelay)}}),v===!0&&(p=t.setTimeout(function(){y===!1&&f(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&(n(a).trigger(u.onReconnect),y=!0)},l.reconnectDelay)))})(o),t.setTimeout(function(){c===!1&&(s(),c=!0)},150)},250)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){"use strict";function o(t){return n.isFunction(t)?null:n.type(t)==="undefined"?null:t}function r(n,t){return new r.fn.init(n,t)}function i(n){return n||(n="/signalr"),new i.fn.init(n)}var f=0,u={},e="proxy.";Array.prototype.hasOwnProperty("map")||(Array.prototype.map=function(n,t){for(var r=this,f=r.length,u=[],i=0;i<f;i+=1)r.hasOwnProperty(i)&&(u[i]=n.call(t,r[i],i,r));return u}),r.fn=r.prototype={init:function(n,t){this.state={},this.connection=n,this.hubName=t,this.subscribed=!1},on:function(t,i){var r=this;return t=t.toLowerCase(),n(r).bind(e+t,function(n,t){i.apply(r,t)}),r.subscribed=!0,r},invoke:function(i){var r=this,e=n.makeArray(arguments).slice(1),h=e[e.length-1],a=n.type(h)==="function"?e.slice(0,e.length-1):e,v=a.map(o),l={hub:r.hubName,method:i,args:v,state:r.state,id:f},s=n.Deferred(),c=function(t){n.extend(this.state,t.State),t.Error?(t.StackTrace&&r.connection.log(t.Error+"\n"+t.StackTrace),s.rejectWith(r,[t.Error])):(n.type(h)==="function"&&h.call(r,t.Result),s.resolveWith(r,[t.Result]))};return u[f.toString()]={scope:r,method:c},f+=1,r.connection.send(t.JSON.stringify(l)),s.promise()}},r.fn.init.prototype=r.fn,i.fn=i.prototype=n.connection(),i.fn.init=function(i,r,f){var o=this;n.signalR.fn.init.call(o,i,r,f),o.proxies={},o.sending(function(){var i=[];n.each(this.proxies,function(n){this.subscribed&&i.push({name:n})}),this.data=t.JSON.stringify(i)}),o.received(function(t){var f,r,i,s,o;t&&(typeof t.Id!="undefined"?(r=t.Id.toString(),i=u[r],i&&(u[r]=null,delete u[r],i.method.call(i.scope,t))):(s=t.Hub.toLowerCase(),o=t.Method.toLowerCase(),f=this.proxies[s],n.extend(f.state,t.State),n(f).trigger(e+o,[t.Args])))})},i.fn.createProxy=function(n){n=n.toLowerCase();var t=this.proxies[n];return t||(t=r(this,n),this.proxies[n]=t),t},i.fn.init.prototype=i.fn,n.hubConnection=i}(window.jQuery,window)
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.