New Upstream Snapshot - ruby-rack-livereload

Ready changes

Summary

Merged new upstream version: 0.3.17+git20220209.1.5a743ff+dfsg (was: 0.3.17+dfsg).

Resulting package

Built on 2023-01-19T13:39 (took 6m16s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-snapshots ruby-rack-livereload

Lintian Result

Diff

diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index c5b08c6..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,7 +0,0 @@
-*.gem
-.bundle
-Gemfile.lock
-gemfiles/*.lock
-pkg/*
-*.orig
-tmp/
diff --git a/.ruby-version b/.ruby-version
deleted file mode 100644
index 73462a5..0000000
--- a/.ruby-version
+++ /dev/null
@@ -1 +0,0 @@
-2.5.1
diff --git a/.travis.yml b/.travis.yml
index 5a84c27..082a68f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,17 +1,15 @@
 rvm:
-  - 1.9.3
-  - 2.0.0
   - 2.5.1
+  - 2.7.1
 branches:
   only:
     - master
 gemfile:
-  - gemfiles/rails32.gemfile
-  - gemfiles/rails40.gemfile
   - gemfiles/rails51.gemfile
+  - gemfiles/rails602.gemfile
 matrix:
   exclude:
-    - rvm: 1.9.3
+    - rvm: 2.5.1
       gemfile: gemfiles/rails51.gemfile
-    - rvm: 2.0.0
-      gemfile: gemfiles/rails51.gemfile
\ No newline at end of file
+    - rvm: 2.7.1
+      gemfile: gemfiles/rails602.gemfile
diff --git a/README.md b/README.md
index 3c24b82..5940b56 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,4 @@
-# Rack::LiveReload
-
-<a href="http://travis-ci.org/onesupercoder/rack-livereload"><img src="https://secure.travis-ci.org/onesupercoder/rack-livereload.png" /></a>
-[![Code Climate](https://codeclimate.com/github/onesupercoder/rack-livereload.png)](https://codeclimate.com/github/onesupercoder/rack-livereload)
+# Rack::LiveReload [![Build Status](https://travis-ci.org/onesupercoder/rack-livereload.svg?branch=master)](https://travis-ci.org/onesupercoder/rack-livereload) [![Maintainability](https://api.codeclimate.com/v1/badges/6b3cafaf0d8752d0ac55/maintainability)](https://codeclimate.com/github/onesupercoder/rack-livereload/maintainability)
 
 Hey, you've got [LiveReload](http://livereload.com/) in my [Rack](http://rack.rubyforge.org/)!
 No need for browser extensions anymore! Just plug it in your middleware stack and go!
@@ -30,6 +27,9 @@ MyApp::Application.configure do
 
   # or, if you're using better_errors:
   config.middleware.insert_before Rack::Lock, Rack::LiveReload
+  
+  # or, if you're using better_errors with rails 6.
+  config.middleware.insert_before Rack::Runtime, Rack::LiveReload
 
   # ...
 end
@@ -43,13 +43,14 @@ config.middleware.use(Rack::LiveReload,
   min_delay        : 500,    # default 1000
   max_delay        : 10_000, # default 60_000
   live_reload_port : 56789,  # default 35729
+  live_reload_scheme : 'ws', # default ws, use wss for ssl
   host             : 'myhost.cool.wow',
   ignore           : [ %r{dont/modify\.html$} ]
 )
 ```
 
 In addition, Rack::LiveReload's position within middleware stack can be
-specified by inserting it relative to an exsiting middleware via
+specified by inserting it relative to an existing middleware via
 `insert_before` or `insert_after`. See the [Rails on Rack: Adding a
 Middleware](http://guides.rubyonrails.org/rails_on_rack.html#adding-a-middleware)
 section for more detail.
diff --git a/debian/changelog b/debian/changelog
index fafe64d..67d99b5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,10 +1,11 @@
-ruby-rack-livereload (0.3.17+dfsg-3) UNRELEASED; urgency=medium
+ruby-rack-livereload (0.3.17+git20220209.1.5a743ff+dfsg-1) UNRELEASED; urgency=medium
 
   * Update standards version to 4.5.1, no changes needed.
   * Set upstream metadata fields: Bug-Database, Repository-Browse.
   * Update standards version to 4.6.1, no changes needed.
+  * New upstream snapshot.
 
- -- Debian Janitor <janitor@jelmer.uk>  Tue, 21 Sep 2021 18:58:32 -0000
+ -- Debian Janitor <janitor@jelmer.uk>  Thu, 19 Jan 2023 13:35:37 -0000
 
 ruby-rack-livereload (0.3.17+dfsg-2) unstable; urgency=medium
 
diff --git a/gemfiles/rails32.gemfile b/gemfiles/rails32.gemfile
deleted file mode 100644
index 6f5dbe6..0000000
--- a/gemfiles/rails32.gemfile
+++ /dev/null
@@ -1,7 +0,0 @@
-# This file was generated by Appraisal
-
-source "http://rubygems.org"
-
-gem "rails", "~> 3.2.0"
-
-gemspec :path=>"../"
\ No newline at end of file
diff --git a/gemfiles/rails40.gemfile b/gemfiles/rails40.gemfile
deleted file mode 100644
index bb72bc2..0000000
--- a/gemfiles/rails40.gemfile
+++ /dev/null
@@ -1,7 +0,0 @@
-# This file was generated by Appraisal
-
-source "http://rubygems.org"
-
-gem "rails", "~> 4.0.0"
-
-gemspec :path=>"../"
\ No newline at end of file
diff --git a/gemfiles/rails602.gemfile b/gemfiles/rails602.gemfile
new file mode 100644
index 0000000..95ee38f
--- /dev/null
+++ b/gemfiles/rails602.gemfile
@@ -0,0 +1,5 @@
+source "http://rubygems.org"
+
+gem "rails", "~> 6.0.2"
+
+gemspec :path=>"../"
diff --git a/js/livereload.js b/js/livereload.js
index 0e9fbd6..ac96a9d 100644
--- a/js/livereload.js
+++ b/js/livereload.js
@@ -1,1055 +1,1056 @@
 (function() {
-var __customevents = {}, __protocol = {}, __connector = {}, __timer = {}, __options = {}, __reloader = {}, __livereload = {}, __less = {}, __startup = {};
+    var __customevents = {}, __protocol = {}, __connector = {}, __timer = {}, __options = {}, __reloader = {}, __livereload = {}, __less = {}, __startup = {};
 
 // customevents
-var CustomEvents;
-CustomEvents = {
-  bind: function(element, eventName, handler) {
-    if (element.addEventListener) {
-      return element.addEventListener(eventName, handler, false);
-    } else if (element.attachEvent) {
-      element[eventName] = 1;
-      return element.attachEvent('onpropertychange', function(event) {
-        if (event.propertyName === eventName) {
-          return handler();
+    var CustomEvents;
+    CustomEvents = {
+        bind: function(element, eventName, handler) {
+            if (element.addEventListener) {
+                return element.addEventListener(eventName, handler, false);
+            } else if (element.attachEvent) {
+                element[eventName] = 1;
+                return element.attachEvent('onpropertychange', function(event) {
+                    if (event.propertyName === eventName) {
+                        return handler();
+                    }
+                });
+            } else {
+                throw new Error("Attempt to attach custom event " + eventName + " to something which isn't a DOMElement");
+            }
+        },
+        fire: function(element, eventName) {
+            var event;
+            if (element.addEventListener) {
+                event = document.createEvent('HTMLEvents');
+                event.initEvent(eventName, true, true);
+                return document.dispatchEvent(event);
+            } else if (element.attachEvent) {
+                if (element[eventName]) {
+                    return element[eventName]++;
+                }
+            } else {
+                throw new Error("Attempt to fire custom event " + eventName + " on something which isn't a DOMElement");
+            }
         }
-      });
-    } else {
-      throw new Error("Attempt to attach custom event " + eventName + " to something which isn't a DOMElement");
-    }
-  },
-  fire: function(element, eventName) {
-    var event;
-    if (element.addEventListener) {
-      event = document.createEvent('HTMLEvents');
-      event.initEvent(eventName, true, true);
-      return document.dispatchEvent(event);
-    } else if (element.attachEvent) {
-      if (element[eventName]) {
-        return element[eventName]++;
-      }
-    } else {
-      throw new Error("Attempt to fire custom event " + eventName + " on something which isn't a DOMElement");
-    }
-  }
-};
-__customevents.bind = CustomEvents.bind;
-__customevents.fire = CustomEvents.fire;
+    };
+    __customevents.bind = CustomEvents.bind;
+    __customevents.fire = CustomEvents.fire;
 
 // protocol
-var PROTOCOL_6, PROTOCOL_7, Parser, ProtocolError;
-var __indexOf = Array.prototype.indexOf || function(item) {
-  for (var i = 0, l = this.length; i < l; i++) {
-    if (this[i] === item) return i;
-  }
-  return -1;
-};
-__protocol.PROTOCOL_6 = PROTOCOL_6 = 'http://livereload.com/protocols/official-6';
-__protocol.PROTOCOL_7 = PROTOCOL_7 = 'http://livereload.com/protocols/official-7';
-__protocol.ProtocolError = ProtocolError = (function() {
-  function ProtocolError(reason, data) {
-    this.message = "LiveReload protocol error (" + reason + ") after receiving data: \"" + data + "\".";
-  }
-  return ProtocolError;
-})();
-__protocol.Parser = Parser = (function() {
-  function Parser(handlers) {
-    this.handlers = handlers;
-    this.reset();
-  }
-  Parser.prototype.reset = function() {
-    return this.protocol = null;
-  };
-  Parser.prototype.process = function(data) {
-    var command, message, options, _ref;
-    try {
-      if (!(this.protocol != null)) {
-        if (data.match(/^!!ver:([\d.]+)$/)) {
-          this.protocol = 6;
-        } else if (message = this._parseMessage(data, ['hello'])) {
-          if (!message.protocols.length) {
-            throw new ProtocolError("no protocols specified in handshake message");
-          } else if (__indexOf.call(message.protocols, PROTOCOL_7) >= 0) {
-            this.protocol = 7;
-          } else if (__indexOf.call(message.protocols, PROTOCOL_6) >= 0) {
-            this.protocol = 6;
-          } else {
-            throw new ProtocolError("no supported protocols found");
-          }
+    var PROTOCOL_6, PROTOCOL_7, Parser, ProtocolError;
+    var __indexOf = Array.prototype.indexOf || function(item) {
+        for (var i = 0, l = this.length; i < l; i++) {
+            if (this[i] === item) return i;
         }
-        return this.handlers.connected(this.protocol);
-      } else if (this.protocol === 6) {
-        message = JSON.parse(data);
-        if (!message.length) {
-          throw new ProtocolError("protocol 6 messages must be arrays");
+        return -1;
+    };
+    __protocol.PROTOCOL_6 = PROTOCOL_6 = 'http://livereload.com/protocols/official-6';
+    __protocol.PROTOCOL_7 = PROTOCOL_7 = 'http://livereload.com/protocols/official-7';
+    __protocol.ProtocolError = ProtocolError = (function() {
+        function ProtocolError(reason, data) {
+            this.message = "LiveReload protocol error (" + reason + ") after receiving data: \"" + data + "\".";
         }
-        command = message[0], options = message[1];
-        if (command !== 'refresh') {
-          throw new ProtocolError("unknown protocol 6 command");
+        return ProtocolError;
+    })();
+    __protocol.Parser = Parser = (function() {
+        function Parser(handlers) {
+            this.handlers = handlers;
+            this.reset();
         }
-        return this.handlers.message({
-          command: 'reload',
-          path: options.path,
-          liveCSS: (_ref = options.apply_css_live) != null ? _ref : true
-        });
-      } else {
-        message = this._parseMessage(data, ['reload', 'alert']);
-        return this.handlers.message(message);
-      }
-    } catch (e) {
-      if (e instanceof ProtocolError) {
-        return this.handlers.error(e);
-      } else {
-        throw e;
-      }
-    }
-  };
-  Parser.prototype._parseMessage = function(data, validCommands) {
-    var message, _ref;
-    try {
-      message = JSON.parse(data);
-    } catch (e) {
-      throw new ProtocolError('unparsable JSON', data);
-    }
-    if (!message.command) {
-      throw new ProtocolError('missing "command" key', data);
-    }
-    if (_ref = message.command, __indexOf.call(validCommands, _ref) < 0) {
-      throw new ProtocolError("invalid command '" + message.command + "', only valid commands are: " + (validCommands.join(', ')) + ")", data);
-    }
-    return message;
-  };
-  return Parser;
-})();
+        Parser.prototype.reset = function() {
+            return this.protocol = null;
+        };
+        Parser.prototype.process = function(data) {
+            var command, message, options, _ref;
+            try {
+                if (!(this.protocol != null)) {
+                    if (data.match(/^!!ver:([\d.]+)$/)) {
+                        this.protocol = 6;
+                    } else if (message = this._parseMessage(data, ['hello'])) {
+                        if (!message.protocols.length) {
+                            throw new ProtocolError("no protocols specified in handshake message");
+                        } else if (__indexOf.call(message.protocols, PROTOCOL_7) >= 0) {
+                            this.protocol = 7;
+                        } else if (__indexOf.call(message.protocols, PROTOCOL_6) >= 0) {
+                            this.protocol = 6;
+                        } else {
+                            throw new ProtocolError("no supported protocols found");
+                        }
+                    }
+                    return this.handlers.connected(this.protocol);
+                } else if (this.protocol === 6) {
+                    message = JSON.parse(data);
+                    if (!message.length) {
+                        throw new ProtocolError("protocol 6 messages must be arrays");
+                    }
+                    command = message[0], options = message[1];
+                    if (command !== 'refresh') {
+                        throw new ProtocolError("unknown protocol 6 command");
+                    }
+                    return this.handlers.message({
+                        command: 'reload',
+                        path: options.path,
+                        liveCSS: (_ref = options.apply_css_live) != null ? _ref : true
+                    });
+                } else {
+                    message = this._parseMessage(data, ['reload', 'alert']);
+                    return this.handlers.message(message);
+                }
+            } catch (e) {
+                if (e instanceof ProtocolError) {
+                    return this.handlers.error(e);
+                } else {
+                    throw e;
+                }
+            }
+        };
+        Parser.prototype._parseMessage = function(data, validCommands) {
+            var message, _ref;
+            try {
+                message = JSON.parse(data);
+            } catch (e) {
+                throw new ProtocolError('unparsable JSON', data);
+            }
+            if (!message.command) {
+                throw new ProtocolError('missing "command" key', data);
+            }
+            if (_ref = message.command, __indexOf.call(validCommands, _ref) < 0) {
+                throw new ProtocolError("invalid command '" + message.command + "', only valid commands are: " + (validCommands.join(', ')) + ")", data);
+            }
+            return message;
+        };
+        return Parser;
+    })();
 
 // connector
 // Generated by CoffeeScript 1.3.3
-var Connector, PROTOCOL_6, PROTOCOL_7, Parser, Version, _ref;
-
-_ref = __protocol, Parser = _ref.Parser, PROTOCOL_6 = _ref.PROTOCOL_6, PROTOCOL_7 = _ref.PROTOCOL_7;
-
-Version = '2.0.8';
-
-__connector.Connector = Connector = (function() {
-
-  function Connector(options, WebSocket, Timer, handlers) {
-    var _this = this;
-    this.options = options;
-    this.WebSocket = WebSocket;
-    this.Timer = Timer;
-    this.handlers = handlers;
-    this._uri = "ws://" + this.options.host + ":" + this.options.port + "/livereload";
-    this._nextDelay = this.options.mindelay;
-    this._connectionDesired = false;
-    this.protocol = 0;
-    this.protocolParser = new Parser({
-      connected: function(protocol) {
-        _this.protocol = protocol;
-        _this._handshakeTimeout.stop();
-        _this._nextDelay = _this.options.mindelay;
-        _this._disconnectionReason = 'broken';
-        return _this.handlers.connected(protocol);
-      },
-      error: function(e) {
-        _this.handlers.error(e);
-        return _this._closeOnError();
-      },
-      message: function(message) {
-        return _this.handlers.message(message);
-      }
-    });
-    this._handshakeTimeout = new Timer(function() {
-      if (!_this._isSocketConnected()) {
-        return;
-      }
-      _this._disconnectionReason = 'handshake-timeout';
-      return _this.socket.close();
-    });
-    this._reconnectTimer = new Timer(function() {
-      if (!_this._connectionDesired) {
-        return;
-      }
-      return _this.connect();
-    });
-    this.connect();
-  }
-
-  Connector.prototype._isSocketConnected = function() {
-    return this.socket && this.socket.readyState === this.WebSocket.OPEN;
-  };
-
-  Connector.prototype.connect = function() {
-    var _this = this;
-    this._connectionDesired = true;
-    if (this._isSocketConnected()) {
-      return;
-    }
-    this._reconnectTimer.stop();
-    this._disconnectionReason = 'cannot-connect';
-    this.protocolParser.reset();
-    this.handlers.connecting();
-    this.socket = new this.WebSocket(this._uri);
-    this.socket.onopen = function(e) {
-      return _this._onopen(e);
-    };
-    this.socket.onclose = function(e) {
-      return _this._onclose(e);
-    };
-    this.socket.onmessage = function(e) {
-      return _this._onmessage(e);
-    };
-    return this.socket.onerror = function(e) {
-      return _this._onerror(e);
-    };
-  };
-
-  Connector.prototype.disconnect = function() {
-    this._connectionDesired = false;
-    this._reconnectTimer.stop();
-    if (!this._isSocketConnected()) {
-      return;
-    }
-    this._disconnectionReason = 'manual';
-    return this.socket.close();
-  };
-
-  Connector.prototype._scheduleReconnection = function() {
-    if (!this._connectionDesired) {
-      return;
-    }
-    if (!this._reconnectTimer.running) {
-      this._reconnectTimer.start(this._nextDelay);
-      return this._nextDelay = Math.min(this.options.maxdelay, this._nextDelay * 2);
-    }
-  };
-
-  Connector.prototype.sendCommand = function(command) {
-    if (this.protocol == null) {
-      return;
-    }
-    return this._sendCommand(command);
-  };
-
-  Connector.prototype._sendCommand = function(command) {
-    return this.socket.send(JSON.stringify(command));
-  };
-
-  Connector.prototype._closeOnError = function() {
-    this._handshakeTimeout.stop();
-    this._disconnectionReason = 'error';
-    return this.socket.close();
-  };
-
-  Connector.prototype._onopen = function(e) {
-    var hello;
-    this.handlers.socketConnected();
-    this._disconnectionReason = 'handshake-failed';
-    hello = {
-      command: 'hello',
-      protocols: [PROTOCOL_6, PROTOCOL_7]
-    };
-    hello.ver = Version;
-    if (this.options.ext) {
-      hello.ext = this.options.ext;
-    }
-    if (this.options.extver) {
-      hello.extver = this.options.extver;
-    }
-    if (this.options.snipver) {
-      hello.snipver = this.options.snipver;
-    }
-    this._sendCommand(hello);
-    return this._handshakeTimeout.start(this.options.handshake_timeout);
-  };
-
-  Connector.prototype._onclose = function(e) {
-    this.protocol = 0;
-    this.handlers.disconnected(this._disconnectionReason, this._nextDelay);
-    return this._scheduleReconnection();
-  };
+    var Connector, PROTOCOL_6, PROTOCOL_7, Parser, Version, _ref;
+
+    _ref = __protocol, Parser = _ref.Parser, PROTOCOL_6 = _ref.PROTOCOL_6, PROTOCOL_7 = _ref.PROTOCOL_7;
+
+    Version = '2.0.8';
+
+    __connector.Connector = Connector = (function() {
+
+        function Connector(options, WebSocket, Timer, handlers) {
+            var _this = this;
+            this.options = options;
+            this.WebSocket = WebSocket;
+            this.Timer = Timer;
+            this.handlers = handlers;
+            this._uri = this.options.scheme + "://" + this.options.host + ":" + this.options.port + "/livereload";
+            this._nextDelay = this.options.mindelay;
+            this._connectionDesired = false;
+            this.protocol = 0;
+            this.protocolParser = new Parser({
+                connected: function(protocol) {
+                    _this.protocol = protocol;
+                    _this._handshakeTimeout.stop();
+                    _this._nextDelay = _this.options.mindelay;
+                    _this._disconnectionReason = 'broken';
+                    return _this.handlers.connected(protocol);
+                },
+                error: function(e) {
+                    _this.handlers.error(e);
+                    return _this._closeOnError();
+                },
+                message: function(message) {
+                    return _this.handlers.message(message);
+                }
+            });
+            this._handshakeTimeout = new Timer(function() {
+                if (!_this._isSocketConnected()) {
+                    return;
+                }
+                _this._disconnectionReason = 'handshake-timeout';
+                return _this.socket.close();
+            });
+            this._reconnectTimer = new Timer(function() {
+                if (!_this._connectionDesired) {
+                    return;
+                }
+                return _this.connect();
+            });
+            this.connect();
+        }
 
-  Connector.prototype._onerror = function(e) {};
+        Connector.prototype._isSocketConnected = function() {
+            return this.socket && this.socket.readyState === this.WebSocket.OPEN;
+        };
 
-  Connector.prototype._onmessage = function(e) {
-    return this.protocolParser.process(e.data);
-  };
+        Connector.prototype.connect = function() {
+            var _this = this;
+            this._connectionDesired = true;
+            if (this._isSocketConnected()) {
+                return;
+            }
+            this._reconnectTimer.stop();
+            this._disconnectionReason = 'cannot-connect';
+            this.protocolParser.reset();
+            this.handlers.connecting();
+            this.socket = new this.WebSocket(this._uri);
+            this.socket.onopen = function(e) {
+                return _this._onopen(e);
+            };
+            this.socket.onclose = function(e) {
+                return _this._onclose(e);
+            };
+            this.socket.onmessage = function(e) {
+                return _this._onmessage(e);
+            };
+            return this.socket.onerror = function(e) {
+                return _this._onerror(e);
+            };
+        };
 
-  return Connector;
+        Connector.prototype.disconnect = function() {
+            this._connectionDesired = false;
+            this._reconnectTimer.stop();
+            if (!this._isSocketConnected()) {
+                return;
+            }
+            this._disconnectionReason = 'manual';
+            return this.socket.close();
+        };
 
-})();
+        Connector.prototype._scheduleReconnection = function() {
+            if (!this._connectionDesired) {
+                return;
+            }
+            if (!this._reconnectTimer.running) {
+                this._reconnectTimer.start(this._nextDelay);
+                return this._nextDelay = Math.min(this.options.maxdelay, this._nextDelay * 2);
+            }
+        };
 
-// timer
-var Timer;
-var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
-__timer.Timer = Timer = (function() {
-  function Timer(func) {
-    this.func = func;
-    this.running = false;
-    this.id = null;
-    this._handler = __bind(function() {
-      this.running = false;
-      this.id = null;
-      return this.func();
-    }, this);
-  }
-  Timer.prototype.start = function(timeout) {
-    if (this.running) {
-      clearTimeout(this.id);
-    }
-    this.id = setTimeout(this._handler, timeout);
-    return this.running = true;
-  };
-  Timer.prototype.stop = function() {
-    if (this.running) {
-      clearTimeout(this.id);
-      this.running = false;
-      return this.id = null;
-    }
-  };
-  return Timer;
-})();
-Timer.start = function(timeout, func) {
-  return setTimeout(func, timeout);
-};
+        Connector.prototype.sendCommand = function(command) {
+            if (this.protocol == null) {
+                return;
+            }
+            return this._sendCommand(command);
+        };
 
-// options
-var Options;
-__options.Options = Options = (function() {
-  function Options() {
-    this.host = null;
-    this.port = RACK_LIVERELOAD_PORT;
-    this.snipver = null;
-    this.ext = null;
-    this.extver = null;
-    this.mindelay = 1000;
-    this.maxdelay = 60000;
-    this.handshake_timeout = 5000;
-  }
-  Options.prototype.set = function(name, value) {
-    switch (typeof this[name]) {
-      case 'undefined':
-        break;
-      case 'number':
-        return this[name] = +value;
-      default:
-        return this[name] = value;
-    }
-  };
-  return Options;
-})();
-Options.extract = function(document) {
-  var element, keyAndValue, m, mm, options, pair, src, _i, _j, _len, _len2, _ref, _ref2;
-  _ref = document.getElementsByTagName('script');
-  for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-    element = _ref[_i];
-    if ((src = element.src) && (m = src.match(/^[^:]+:\/\/(.*)\/z?livereload\.js(?:\?(.*))?$/))) {
-      options = new Options();
-      if (mm = m[1].match(/^([^\/:]+)(?::(\d+))?$/)) {
-        options.host = mm[1];
-        if (mm[2]) {
-          options.port = parseInt(mm[2], 10);
-        }
-      }
-      if (m[2]) {
-        _ref2 = m[2].split('&');
-        for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
-          pair = _ref2[_j];
-          if ((keyAndValue = pair.split('=')).length > 1) {
-            options.set(keyAndValue[0].replace(/-/g, '_'), keyAndValue.slice(1).join('='));
-          }
-        }
-      }
-      return options;
-    }
-  }
-  return null;
-};
+        Connector.prototype._sendCommand = function(command) {
+            return this.socket.send(JSON.stringify(command));
+        };
 
-// reloader
-// Generated by CoffeeScript 1.3.1
-(function() {
-  var IMAGE_STYLES, Reloader, numberOfMatchingSegments, pathFromUrl, pathsMatch, pickBestMatch, splitUrl;
-
-  splitUrl = function(url) {
-    var hash, index, params;
-    if ((index = url.indexOf('#')) >= 0) {
-      hash = url.slice(index);
-      url = url.slice(0, index);
-    } else {
-      hash = '';
-    }
-    if ((index = url.indexOf('?')) >= 0) {
-      params = url.slice(index);
-      url = url.slice(0, index);
-    } else {
-      params = '';
-    }
-    return {
-      url: url,
-      params: params,
-      hash: hash
-    };
-  };
-
-  pathFromUrl = function(url) {
-    var path;
-    url = splitUrl(url).url;
-    if (url.indexOf('file://') === 0) {
-      path = url.replace(/^file:\/\/(localhost)?/, '');
-    } else {
-      path = url.replace(/^([^:]+:)?\/\/([^:\/]+)(:\d*)?\//, '/');
-    }
-    return decodeURIComponent(path);
-  };
+        Connector.prototype._closeOnError = function() {
+            this._handshakeTimeout.stop();
+            this._disconnectionReason = 'error';
+            return this.socket.close();
+        };
 
-  pickBestMatch = function(path, objects, pathFunc) {
-    var bestMatch, object, score, _i, _len;
-    bestMatch = {
-      score: 0
-    };
-    for (_i = 0, _len = objects.length; _i < _len; _i++) {
-      object = objects[_i];
-      score = numberOfMatchingSegments(path, pathFunc(object));
-      if (score > bestMatch.score) {
-        bestMatch = {
-          object: object,
-          score: score
+        Connector.prototype._onopen = function(e) {
+            var hello;
+            this.handlers.socketConnected();
+            this._disconnectionReason = 'handshake-failed';
+            hello = {
+                command: 'hello',
+                protocols: [PROTOCOL_6, PROTOCOL_7]
+            };
+            hello.ver = Version;
+            if (this.options.ext) {
+                hello.ext = this.options.ext;
+            }
+            if (this.options.extver) {
+                hello.extver = this.options.extver;
+            }
+            if (this.options.snipver) {
+                hello.snipver = this.options.snipver;
+            }
+            this._sendCommand(hello);
+            return this._handshakeTimeout.start(this.options.handshake_timeout);
         };
-      }
-    }
-    if (bestMatch.score > 0) {
-      return bestMatch;
-    } else {
-      return null;
-    }
-  };
-
-  numberOfMatchingSegments = function(path1, path2) {
-    var comps1, comps2, eqCount, len;
-    path1 = path1.replace(/^\/+/, '').toLowerCase();
-    path2 = path2.replace(/^\/+/, '').toLowerCase();
-    if (path1 === path2) {
-      return 10000;
-    }
-    comps1 = path1.split('/').reverse();
-    comps2 = path2.split('/').reverse();
-    len = Math.min(comps1.length, comps2.length);
-    eqCount = 0;
-    while (eqCount < len && comps1[eqCount] === comps2[eqCount]) {
-      ++eqCount;
-    }
-    return eqCount;
-  };
-
-  pathsMatch = function(path1, path2) {
-    return numberOfMatchingSegments(path1, path2) > 0;
-  };
-
-  IMAGE_STYLES = [
-    {
-      selector: 'background',
-      styleNames: ['backgroundImage']
-    }, {
-      selector: 'border',
-      styleNames: ['borderImage', 'webkitBorderImage', 'MozBorderImage']
-    }
-  ];
 
-  __reloader.Reloader = Reloader = (function() {
+        Connector.prototype._onclose = function(e) {
+            this.protocol = 0;
+            this.handlers.disconnected(this._disconnectionReason, this._nextDelay);
+            return this._scheduleReconnection();
+        };
 
-    Reloader.name = 'Reloader';
+        Connector.prototype._onerror = function(e) {};
 
-    function Reloader(window, console, Timer) {
-      this.window = window;
-      this.console = console;
-      this.Timer = Timer;
-      this.document = this.window.document;
-      this.importCacheWaitPeriod = 200;
-      this.plugins = [];
-    }
+        Connector.prototype._onmessage = function(e) {
+            return this.protocolParser.process(e.data);
+        };
 
-    Reloader.prototype.addPlugin = function(plugin) {
-      return this.plugins.push(plugin);
-    };
+        return Connector;
 
-    Reloader.prototype.analyze = function(callback) {
-      return results;
-    };
+    })();
 
-    Reloader.prototype.reload = function(path, options) {
-      var plugin, _base, _i, _len, _ref;
-      this.options = options;
-      if ((_base = this.options).stylesheetReloadTimeout == null) {
-        _base.stylesheetReloadTimeout = 15000;
-      }
-      _ref = this.plugins;
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        plugin = _ref[_i];
-        if (plugin.reload && plugin.reload(path, options)) {
-          return;
-        }
-      }
-      if (options.liveCSS) {
-        if (path.match(/\.css$/i)) {
-          if (this.reloadStylesheet(path)) {
-            return;
-          }
-        }
-      }
-      if (options.liveImg) {
-        if (path.match(/\.(jpe?g|png|gif)$/i)) {
-          this.reloadImages(path);
-          return;
+// timer
+    var Timer;
+    var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
+    __timer.Timer = Timer = (function() {
+        function Timer(func) {
+            this.func = func;
+            this.running = false;
+            this.id = null;
+            this._handler = __bind(function() {
+                this.running = false;
+                this.id = null;
+                return this.func();
+            }, this);
         }
-      }
-      return this.reloadPage();
-    };
-
-    Reloader.prototype.reloadPage = function() {
-      return this.window.document.location.reload();
+        Timer.prototype.start = function(timeout) {
+            if (this.running) {
+                clearTimeout(this.id);
+            }
+            this.id = setTimeout(this._handler, timeout);
+            return this.running = true;
+        };
+        Timer.prototype.stop = function() {
+            if (this.running) {
+                clearTimeout(this.id);
+                this.running = false;
+                return this.id = null;
+            }
+        };
+        return Timer;
+    })();
+    Timer.start = function(timeout, func) {
+        return setTimeout(func, timeout);
     };
 
-    Reloader.prototype.reloadImages = function(path) {
-      var expando, img, selector, styleNames, styleSheet, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _results;
-      expando = this.generateUniqueString();
-      _ref = this.document.images;
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        img = _ref[_i];
-        if (pathsMatch(path, pathFromUrl(img.src))) {
-          img.src = this.generateCacheBustUrl(img.src, expando);
-        }
-      }
-      if (this.document.querySelectorAll) {
-        for (_j = 0, _len1 = IMAGE_STYLES.length; _j < _len1; _j++) {
-          _ref1 = IMAGE_STYLES[_j], selector = _ref1.selector, styleNames = _ref1.styleNames;
-          _ref2 = this.document.querySelectorAll("[style*=" + selector + "]");
-          for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
-            img = _ref2[_k];
-            this.reloadStyleImages(img.style, styleNames, path, expando);
-          }
-        }
-      }
-      if (this.document.styleSheets) {
-        _ref3 = this.document.styleSheets;
-        _results = [];
-        for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
-          styleSheet = _ref3[_l];
-          _results.push(this.reloadStylesheetImages(styleSheet, path, expando));
+// options
+    var Options;
+    __options.Options = Options = (function() {
+        function Options() {
+            this.host = null;
+            this.port = RACK_LIVERELOAD_PORT;
+            this.scheme = RACK_LIVERELOAD_SCHEME;
+            this.snipver = null;
+            this.ext = null;
+            this.extver = null;
+            this.mindelay = 1000;
+            this.maxdelay = 60000;
+            this.handshake_timeout = 5000;
         }
-        return _results;
-      }
-    };
-
-    Reloader.prototype.reloadStylesheetImages = function(styleSheet, path, expando) {
-      var rule, rules, styleNames, _i, _j, _len, _len1;
-      try {
-        rules = styleSheet != null ? styleSheet.cssRules : void 0;
-      } catch (e) {
-
-      }
-      if (!rules) {
-        return;
-      }
-      for (_i = 0, _len = rules.length; _i < _len; _i++) {
-        rule = rules[_i];
-        switch (rule.type) {
-          case CSSRule.IMPORT_RULE:
-            this.reloadStylesheetImages(rule.styleSheet, path, expando);
-            break;
-          case CSSRule.STYLE_RULE:
-            for (_j = 0, _len1 = IMAGE_STYLES.length; _j < _len1; _j++) {
-              styleNames = IMAGE_STYLES[_j].styleNames;
-              this.reloadStyleImages(rule.style, styleNames, path, expando);
+        Options.prototype.set = function(name, value) {
+            switch (typeof this[name]) {
+                case 'undefined':
+                    break;
+                case 'number':
+                    return this[name] = +value;
+                default:
+                    return this[name] = value;
+            }
+        };
+        return Options;
+    })();
+    Options.extract = function(document) {
+        var element, keyAndValue, m, mm, options, pair, src, _i, _j, _len, _len2, _ref, _ref2;
+        _ref = document.getElementsByTagName('script');
+        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+            element = _ref[_i];
+            if ((src = element.src) && (m = src.match(/^[^:]+:\/\/(.*)\/z?livereload\.js(?:\?(.*))?$/))) {
+                options = new Options();
+                if (mm = m[1].match(/^([^\/:]+)(?::(\d+))?$/)) {
+                    options.host = mm[1];
+                    if (mm[2]) {
+                        options.port = parseInt(mm[2], 10);
+                    }
+                }
+                if (m[2]) {
+                    _ref2 = m[2].split('&');
+                    for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
+                        pair = _ref2[_j];
+                        if ((keyAndValue = pair.split('=')).length > 1) {
+                            options.set(keyAndValue[0].replace(/-/g, '_'), keyAndValue.slice(1).join('='));
+                        }
+                    }
+                }
+                return options;
             }
-            break;
-          case CSSRule.MEDIA_RULE:
-            this.reloadStylesheetImages(rule, path, expando);
         }
-      }
+        return null;
     };
 
-    Reloader.prototype.reloadStyleImages = function(style, styleNames, path, expando) {
-      var newValue, styleName, value, _i, _len,
-        _this = this;
-      for (_i = 0, _len = styleNames.length; _i < _len; _i++) {
-        styleName = styleNames[_i];
-        value = style[styleName];
-        if (typeof value === 'string') {
-          newValue = value.replace(/\burl\s*\(([^)]*)\)/, function(match, src) {
-            if (pathsMatch(path, pathFromUrl(src))) {
-              return "url(" + (_this.generateCacheBustUrl(src, expando)) + ")";
+// reloader
+// Generated by CoffeeScript 1.3.1
+    (function() {
+        var IMAGE_STYLES, Reloader, numberOfMatchingSegments, pathFromUrl, pathsMatch, pickBestMatch, splitUrl;
+
+        splitUrl = function(url) {
+            var hash, index, params;
+            if ((index = url.indexOf('#')) >= 0) {
+                hash = url.slice(index);
+                url = url.slice(0, index);
             } else {
-              return match;
+                hash = '';
             }
-          });
-          if (newValue !== value) {
-            style[styleName] = newValue;
-          }
-        }
-      }
-    };
+            if ((index = url.indexOf('?')) >= 0) {
+                params = url.slice(index);
+                url = url.slice(0, index);
+            } else {
+                params = '';
+            }
+            return {
+                url: url,
+                params: params,
+                hash: hash
+            };
+        };
 
-    Reloader.prototype.reloadStylesheet = function(path) {
-      var imported, link, links, match, style, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1,
-        _this = this;
-      links = (function() {
-        var _i, _len, _ref, _results;
-        _ref = this.document.getElementsByTagName('link');
-        _results = [];
-        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-          link = _ref[_i];
-          if (link.rel === 'stylesheet' && !link.__LiveReload_pendingRemoval) {
-            _results.push(link);
-          }
-        }
-        return _results;
-      }).call(this);
-      imported = [];
-      _ref = this.document.getElementsByTagName('style');
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        style = _ref[_i];
-        if (style.sheet) {
-          this.collectImportedStylesheets(style, style.sheet, imported);
-        }
-      }
-      for (_j = 0, _len1 = links.length; _j < _len1; _j++) {
-        link = links[_j];
-        this.collectImportedStylesheets(link, link.sheet, imported);
-      }
-      if (this.window.StyleFix && this.document.querySelectorAll) {
-        _ref1 = this.document.querySelectorAll('style[data-href]');
-        for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
-          style = _ref1[_k];
-          links.push(style);
-        }
-      }
-      this.console.log("LiveReload found " + links.length + " LINKed stylesheets, " + imported.length + " @imported stylesheets");
-      match = pickBestMatch(path, links.concat(imported), function(l) {
-        return pathFromUrl(_this.linkHref(l));
-      });
-      if (match) {
-        if (match.object.rule) {
-          this.console.log("LiveReload is reloading imported stylesheet: " + match.object.href);
-          this.reattachImportedRule(match.object);
-        } else {
-          this.console.log("LiveReload is reloading stylesheet: " + (this.linkHref(match.object)));
-          this.reattachStylesheetLink(match.object);
-        }
-      } else {
-        this.console.log("LiveReload will reload all stylesheets because path '" + path + "' did not match any specific one");
-        for (_l = 0, _len3 = links.length; _l < _len3; _l++) {
-          link = links[_l];
-          this.reattachStylesheetLink(link);
-        }
-      }
-      return true;
-    };
+        pathFromUrl = function(url) {
+            var path;
+            url = splitUrl(url).url;
+            if (url.indexOf('file://') === 0) {
+                path = url.replace(/^file:\/\/(localhost)?/, '');
+            } else {
+                path = url.replace(/^([^:]+:)?\/\/([^:\/]+)(:\d*)?\//, '/');
+            }
+            return decodeURIComponent(path);
+        };
 
-    Reloader.prototype.collectImportedStylesheets = function(link, styleSheet, result) {
-      var index, rule, rules, _i, _len;
-      try {
-        rules = styleSheet != null ? styleSheet.cssRules : void 0;
-      } catch (e) {
-
-      }
-      if (rules && rules.length) {
-        for (index = _i = 0, _len = rules.length; _i < _len; index = ++_i) {
-          rule = rules[index];
-          switch (rule.type) {
-            case CSSRule.CHARSET_RULE:
-              continue;
-            case CSSRule.IMPORT_RULE:
-              result.push({
-                link: link,
-                rule: rule,
-                index: index,
-                href: rule.href
-              });
-              this.collectImportedStylesheets(link, rule.styleSheet, result);
-              break;
-            default:
-              break;
-          }
-        }
-      }
-    };
+        pickBestMatch = function(path, objects, pathFunc) {
+            var bestMatch, object, score, _i, _len;
+            bestMatch = {
+                score: 0
+            };
+            for (_i = 0, _len = objects.length; _i < _len; _i++) {
+                object = objects[_i];
+                score = numberOfMatchingSegments(path, pathFunc(object));
+                if (score > bestMatch.score) {
+                    bestMatch = {
+                        object: object,
+                        score: score
+                    };
+                }
+            }
+            if (bestMatch.score > 0) {
+                return bestMatch;
+            } else {
+                return null;
+            }
+        };
 
-    Reloader.prototype.waitUntilCssLoads = function(clone, func) {
-      var callbackExecuted, executeCallback, poll,
-        _this = this;
-      callbackExecuted = false;
-      executeCallback = function() {
-        if (callbackExecuted) {
-          return;
-        }
-        callbackExecuted = true;
-        return func();
-      };
-      clone.onload = function() {
-        console.log("onload!");
-        _this.knownToSupportCssOnLoad = true;
-        return executeCallback();
-      };
-      if (!this.knownToSupportCssOnLoad) {
-        (poll = function() {
-          if (clone.sheet) {
-            console.log("polling!");
-            return executeCallback();
-          } else {
-            return _this.Timer.start(50, poll);
-          }
-        })();
-      }
-      return this.Timer.start(this.options.stylesheetReloadTimeout, executeCallback);
-    };
+        numberOfMatchingSegments = function(path1, path2) {
+            var comps1, comps2, eqCount, len;
+            path1 = path1.replace(/^\/+/, '').toLowerCase();
+            path2 = path2.replace(/^\/+/, '').toLowerCase();
+            if (path1 === path2) {
+                return 10000;
+            }
+            comps1 = path1.split('/').reverse();
+            comps2 = path2.split('/').reverse();
+            len = Math.min(comps1.length, comps2.length);
+            eqCount = 0;
+            while (eqCount < len && comps1[eqCount] === comps2[eqCount]) {
+                ++eqCount;
+            }
+            return eqCount;
+        };
 
-    Reloader.prototype.linkHref = function(link) {
-      return link.href || link.getAttribute('data-href');
-    };
+        pathsMatch = function(path1, path2) {
+            return numberOfMatchingSegments(path1, path2) > 0;
+        };
 
-    Reloader.prototype.reattachStylesheetLink = function(link) {
-      var clone, parent,
-        _this = this;
-      if (link.__LiveReload_pendingRemoval) {
-        return;
-      }
-      link.__LiveReload_pendingRemoval = true;
-      if (link.tagName === 'STYLE') {
-        clone = this.document.createElement('link');
-        clone.rel = 'stylesheet';
-        clone.media = link.media;
-        clone.disabled = link.disabled;
-      } else {
-        clone = link.cloneNode(false);
-      }
-      clone.href = this.generateCacheBustUrl(this.linkHref(link));
-      parent = link.parentNode;
-      if (parent.lastChild === link) {
-        parent.appendChild(clone);
-      } else {
-        parent.insertBefore(clone, link.nextSibling);
-      }
-      return this.waitUntilCssLoads(clone, function() {
-        var additionalWaitingTime;
-        if (/AppleWebKit/.test(navigator.userAgent)) {
-          additionalWaitingTime = 5;
-        } else {
-          additionalWaitingTime = 200;
-        }
-        return _this.Timer.start(additionalWaitingTime, function() {
-          var _ref;
-          if (!link.parentNode) {
-            return;
-          }
-          link.parentNode.removeChild(link);
-          clone.onreadystatechange = null;
-          return (_ref = _this.window.StyleFix) != null ? _ref.link(clone) : void 0;
-        });
-      });
-    };
+        IMAGE_STYLES = [
+            {
+                selector: 'background',
+                styleNames: ['backgroundImage']
+            }, {
+                selector: 'border',
+                styleNames: ['borderImage', 'webkitBorderImage', 'MozBorderImage']
+            }
+        ];
 
-    Reloader.prototype.reattachImportedRule = function(_arg) {
-      var href, index, link, media, newRule, parent, rule, tempLink,
-        _this = this;
-      rule = _arg.rule, index = _arg.index, link = _arg.link;
-      parent = rule.parentStyleSheet;
-      href = this.generateCacheBustUrl(rule.href);
-      media = rule.media.length ? [].join.call(rule.media, ', ') : '';
-      newRule = "@import url(\"" + href + "\") " + media + ";";
-      rule.__LiveReload_newHref = href;
-      tempLink = this.document.createElement("link");
-      tempLink.rel = 'stylesheet';
-      tempLink.href = href;
-      tempLink.__LiveReload_pendingRemoval = true;
-      if (link.parentNode) {
-        link.parentNode.insertBefore(tempLink, link);
-      }
-      return this.Timer.start(this.importCacheWaitPeriod, function() {
-        if (tempLink.parentNode) {
-          tempLink.parentNode.removeChild(tempLink);
-        }
-        if (rule.__LiveReload_newHref !== href) {
-          return;
-        }
-        parent.insertRule(newRule, index);
-        parent.deleteRule(index + 1);
-        rule = parent.cssRules[index];
-        rule.__LiveReload_newHref = href;
-        return _this.Timer.start(_this.importCacheWaitPeriod, function() {
-          if (rule.__LiveReload_newHref !== href) {
-            return;
-          }
-          parent.insertRule(newRule, index);
-          return parent.deleteRule(index + 1);
-        });
-      });
-    };
+        __reloader.Reloader = Reloader = (function() {
 
-    Reloader.prototype.generateUniqueString = function() {
-      return 'livereload=' + Date.now();
-    };
+            Reloader.name = 'Reloader';
 
-    Reloader.prototype.generateCacheBustUrl = function(url, expando) {
-      var hash, oldParams, params, _ref;
-      if (expando == null) {
-        expando = this.generateUniqueString();
-      }
-      _ref = splitUrl(url), url = _ref.url, hash = _ref.hash, oldParams = _ref.params;
-      if (this.options.overrideURL) {
-        if (url.indexOf(this.options.serverURL) < 0) {
-          url = this.options.serverURL + this.options.overrideURL + "?url=" + encodeURIComponent(url);
-        }
-      }
-      params = oldParams.replace(/(\?|&)livereload=(\d+)/, function(match, sep) {
-        return "" + sep + expando;
-      });
-      if (params === oldParams) {
-        if (oldParams.length === 0) {
-          params = "?" + expando;
-        } else {
-          params = "" + oldParams + "&" + expando;
-        }
-      }
-      return url + params + hash;
-    };
+            function Reloader(window, console, Timer) {
+                this.window = window;
+                this.console = console;
+                this.Timer = Timer;
+                this.document = this.window.document;
+                this.importCacheWaitPeriod = 200;
+                this.plugins = [];
+            }
 
-    return Reloader;
+            Reloader.prototype.addPlugin = function(plugin) {
+                return this.plugins.push(plugin);
+            };
+
+            Reloader.prototype.analyze = function(callback) {
+                return results;
+            };
+
+            Reloader.prototype.reload = function(path, options) {
+                var plugin, _base, _i, _len, _ref;
+                this.options = options;
+                if ((_base = this.options).stylesheetReloadTimeout == null) {
+                    _base.stylesheetReloadTimeout = 15000;
+                }
+                _ref = this.plugins;
+                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+                    plugin = _ref[_i];
+                    if (plugin.reload && plugin.reload(path, options)) {
+                        return;
+                    }
+                }
+                if (options.liveCSS) {
+                    if (path.match(/\.css$/i)) {
+                        if (this.reloadStylesheet(path)) {
+                            return;
+                        }
+                    }
+                }
+                if (options.liveImg) {
+                    if (path.match(/\.(jpe?g|png|gif)$/i)) {
+                        this.reloadImages(path);
+                        return;
+                    }
+                }
+                return this.reloadPage();
+            };
+
+            Reloader.prototype.reloadPage = function() {
+                return this.window.document.location.reload();
+            };
+
+            Reloader.prototype.reloadImages = function(path) {
+                var expando, img, selector, styleNames, styleSheet, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _results;
+                expando = this.generateUniqueString();
+                _ref = this.document.images;
+                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+                    img = _ref[_i];
+                    if (pathsMatch(path, pathFromUrl(img.src))) {
+                        img.src = this.generateCacheBustUrl(img.src, expando);
+                    }
+                }
+                if (this.document.querySelectorAll) {
+                    for (_j = 0, _len1 = IMAGE_STYLES.length; _j < _len1; _j++) {
+                        _ref1 = IMAGE_STYLES[_j], selector = _ref1.selector, styleNames = _ref1.styleNames;
+                        _ref2 = this.document.querySelectorAll("[style*=" + selector + "]");
+                        for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
+                            img = _ref2[_k];
+                            this.reloadStyleImages(img.style, styleNames, path, expando);
+                        }
+                    }
+                }
+                if (this.document.styleSheets) {
+                    _ref3 = this.document.styleSheets;
+                    _results = [];
+                    for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
+                        styleSheet = _ref3[_l];
+                        _results.push(this.reloadStylesheetImages(styleSheet, path, expando));
+                    }
+                    return _results;
+                }
+            };
+
+            Reloader.prototype.reloadStylesheetImages = function(styleSheet, path, expando) {
+                var rule, rules, styleNames, _i, _j, _len, _len1;
+                try {
+                    rules = styleSheet != null ? styleSheet.cssRules : void 0;
+                } catch (e) {
+
+                }
+                if (!rules) {
+                    return;
+                }
+                for (_i = 0, _len = rules.length; _i < _len; _i++) {
+                    rule = rules[_i];
+                    switch (rule.type) {
+                        case CSSRule.IMPORT_RULE:
+                            this.reloadStylesheetImages(rule.styleSheet, path, expando);
+                            break;
+                        case CSSRule.STYLE_RULE:
+                            for (_j = 0, _len1 = IMAGE_STYLES.length; _j < _len1; _j++) {
+                                styleNames = IMAGE_STYLES[_j].styleNames;
+                                this.reloadStyleImages(rule.style, styleNames, path, expando);
+                            }
+                            break;
+                        case CSSRule.MEDIA_RULE:
+                            this.reloadStylesheetImages(rule, path, expando);
+                    }
+                }
+            };
+
+            Reloader.prototype.reloadStyleImages = function(style, styleNames, path, expando) {
+                var newValue, styleName, value, _i, _len,
+                    _this = this;
+                for (_i = 0, _len = styleNames.length; _i < _len; _i++) {
+                    styleName = styleNames[_i];
+                    value = style[styleName];
+                    if (typeof value === 'string') {
+                        newValue = value.replace(/\burl\s*\(([^)]*)\)/, function(match, src) {
+                            if (pathsMatch(path, pathFromUrl(src))) {
+                                return "url(" + (_this.generateCacheBustUrl(src, expando)) + ")";
+                            } else {
+                                return match;
+                            }
+                        });
+                        if (newValue !== value) {
+                            style[styleName] = newValue;
+                        }
+                    }
+                }
+            };
+
+            Reloader.prototype.reloadStylesheet = function(path) {
+                var imported, link, links, match, style, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1,
+                    _this = this;
+                links = (function() {
+                    var _i, _len, _ref, _results;
+                    _ref = this.document.getElementsByTagName('link');
+                    _results = [];
+                    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+                        link = _ref[_i];
+                        if (link.rel === 'stylesheet' && !link.__LiveReload_pendingRemoval) {
+                            _results.push(link);
+                        }
+                    }
+                    return _results;
+                }).call(this);
+                imported = [];
+                _ref = this.document.getElementsByTagName('style');
+                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+                    style = _ref[_i];
+                    if (style.sheet) {
+                        this.collectImportedStylesheets(style, style.sheet, imported);
+                    }
+                }
+                for (_j = 0, _len1 = links.length; _j < _len1; _j++) {
+                    link = links[_j];
+                    this.collectImportedStylesheets(link, link.sheet, imported);
+                }
+                if (this.window.StyleFix && this.document.querySelectorAll) {
+                    _ref1 = this.document.querySelectorAll('style[data-href]');
+                    for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
+                        style = _ref1[_k];
+                        links.push(style);
+                    }
+                }
+                this.console.log("LiveReload found " + links.length + " LINKed stylesheets, " + imported.length + " @imported stylesheets");
+                match = pickBestMatch(path, links.concat(imported), function(l) {
+                    return pathFromUrl(_this.linkHref(l));
+                });
+                if (match) {
+                    if (match.object.rule) {
+                        this.console.log("LiveReload is reloading imported stylesheet: " + match.object.href);
+                        this.reattachImportedRule(match.object);
+                    } else {
+                        this.console.log("LiveReload is reloading stylesheet: " + (this.linkHref(match.object)));
+                        this.reattachStylesheetLink(match.object);
+                    }
+                } else {
+                    this.console.log("LiveReload will reload all stylesheets because path '" + path + "' did not match any specific one");
+                    for (_l = 0, _len3 = links.length; _l < _len3; _l++) {
+                        link = links[_l];
+                        this.reattachStylesheetLink(link);
+                    }
+                }
+                return true;
+            };
+
+            Reloader.prototype.collectImportedStylesheets = function(link, styleSheet, result) {
+                var index, rule, rules, _i, _len;
+                try {
+                    rules = styleSheet != null ? styleSheet.cssRules : void 0;
+                } catch (e) {
+
+                }
+                if (rules && rules.length) {
+                    for (index = _i = 0, _len = rules.length; _i < _len; index = ++_i) {
+                        rule = rules[index];
+                        switch (rule.type) {
+                            case CSSRule.CHARSET_RULE:
+                                continue;
+                            case CSSRule.IMPORT_RULE:
+                                result.push({
+                                    link: link,
+                                    rule: rule,
+                                    index: index,
+                                    href: rule.href
+                                });
+                                this.collectImportedStylesheets(link, rule.styleSheet, result);
+                                break;
+                            default:
+                                break;
+                        }
+                    }
+                }
+            };
+
+            Reloader.prototype.waitUntilCssLoads = function(clone, func) {
+                var callbackExecuted, executeCallback, poll,
+                    _this = this;
+                callbackExecuted = false;
+                executeCallback = function() {
+                    if (callbackExecuted) {
+                        return;
+                    }
+                    callbackExecuted = true;
+                    return func();
+                };
+                clone.onload = function() {
+                    console.log("onload!");
+                    _this.knownToSupportCssOnLoad = true;
+                    return executeCallback();
+                };
+                if (!this.knownToSupportCssOnLoad) {
+                    (poll = function() {
+                        if (clone.sheet) {
+                            console.log("polling!");
+                            return executeCallback();
+                        } else {
+                            return _this.Timer.start(50, poll);
+                        }
+                    })();
+                }
+                return this.Timer.start(this.options.stylesheetReloadTimeout, executeCallback);
+            };
+
+            Reloader.prototype.linkHref = function(link) {
+                return link.href || link.getAttribute('data-href');
+            };
+
+            Reloader.prototype.reattachStylesheetLink = function(link) {
+                var clone, parent,
+                    _this = this;
+                if (link.__LiveReload_pendingRemoval) {
+                    return;
+                }
+                link.__LiveReload_pendingRemoval = true;
+                if (link.tagName === 'STYLE') {
+                    clone = this.document.createElement('link');
+                    clone.rel = 'stylesheet';
+                    clone.media = link.media;
+                    clone.disabled = link.disabled;
+                } else {
+                    clone = link.cloneNode(false);
+                }
+                clone.href = this.generateCacheBustUrl(this.linkHref(link));
+                parent = link.parentNode;
+                if (parent.lastChild === link) {
+                    parent.appendChild(clone);
+                } else {
+                    parent.insertBefore(clone, link.nextSibling);
+                }
+                return this.waitUntilCssLoads(clone, function() {
+                    var additionalWaitingTime;
+                    if (/AppleWebKit/.test(navigator.userAgent)) {
+                        additionalWaitingTime = 5;
+                    } else {
+                        additionalWaitingTime = 200;
+                    }
+                    return _this.Timer.start(additionalWaitingTime, function() {
+                        var _ref;
+                        if (!link.parentNode) {
+                            return;
+                        }
+                        link.parentNode.removeChild(link);
+                        clone.onreadystatechange = null;
+                        return (_ref = _this.window.StyleFix) != null ? _ref.link(clone) : void 0;
+                    });
+                });
+            };
+
+            Reloader.prototype.reattachImportedRule = function(_arg) {
+                var href, index, link, media, newRule, parent, rule, tempLink,
+                    _this = this;
+                rule = _arg.rule, index = _arg.index, link = _arg.link;
+                parent = rule.parentStyleSheet;
+                href = this.generateCacheBustUrl(rule.href);
+                media = rule.media.length ? [].join.call(rule.media, ', ') : '';
+                newRule = "@import url(\"" + href + "\") " + media + ";";
+                rule.__LiveReload_newHref = href;
+                tempLink = this.document.createElement("link");
+                tempLink.rel = 'stylesheet';
+                tempLink.href = href;
+                tempLink.__LiveReload_pendingRemoval = true;
+                if (link.parentNode) {
+                    link.parentNode.insertBefore(tempLink, link);
+                }
+                return this.Timer.start(this.importCacheWaitPeriod, function() {
+                    if (tempLink.parentNode) {
+                        tempLink.parentNode.removeChild(tempLink);
+                    }
+                    if (rule.__LiveReload_newHref !== href) {
+                        return;
+                    }
+                    parent.insertRule(newRule, index);
+                    parent.deleteRule(index + 1);
+                    rule = parent.cssRules[index];
+                    rule.__LiveReload_newHref = href;
+                    return _this.Timer.start(_this.importCacheWaitPeriod, function() {
+                        if (rule.__LiveReload_newHref !== href) {
+                            return;
+                        }
+                        parent.insertRule(newRule, index);
+                        return parent.deleteRule(index + 1);
+                    });
+                });
+            };
+
+            Reloader.prototype.generateUniqueString = function() {
+                return 'livereload=' + Date.now();
+            };
+
+            Reloader.prototype.generateCacheBustUrl = function(url, expando) {
+                var hash, oldParams, params, _ref;
+                if (expando == null) {
+                    expando = this.generateUniqueString();
+                }
+                _ref = splitUrl(url), url = _ref.url, hash = _ref.hash, oldParams = _ref.params;
+                if (this.options.overrideURL) {
+                    if (url.indexOf(this.options.serverURL) < 0) {
+                        url = this.options.serverURL + this.options.overrideURL + "?url=" + encodeURIComponent(url);
+                    }
+                }
+                params = oldParams.replace(/(\?|&)livereload=(\d+)/, function(match, sep) {
+                    return "" + sep + expando;
+                });
+                if (params === oldParams) {
+                    if (oldParams.length === 0) {
+                        params = "?" + expando;
+                    } else {
+                        params = "" + oldParams + "&" + expando;
+                    }
+                }
+                return url + params + hash;
+            };
+
+            return Reloader;
 
-  })();
+        })();
 
-}).call(this);
+    }).call(this);
 
 // livereload
-var Connector, LiveReload, Options, Reloader, Timer;
+    var Connector, LiveReload, Options, Reloader, Timer;
 
-Connector = __connector.Connector;
+    Connector = __connector.Connector;
 
-Timer = __timer.Timer;
+    Timer = __timer.Timer;
 
-Options = __options.Options;
+    Options = __options.Options;
 
-Reloader = __reloader.Reloader;
+    Reloader = __reloader.Reloader;
 
-__livereload.LiveReload = LiveReload = (function() {
+    __livereload.LiveReload = LiveReload = (function() {
 
-  function LiveReload(window) {
-    var _this = this;
-    this.window = window;
-    this.listeners = {};
-    this.plugins = [];
-    this.pluginIdentifiers = {};
-    this.console = this.window.location.href.match(/LR-verbose/) && this.window.console && this.window.console.log && this.window.console.error ? this.window.console : {
-      log: function() {},
-      error: function() {}
-    };
-    if (!(this.WebSocket = this.window.WebSocket || this.window.MozWebSocket)) {
-      console.error("LiveReload disabled because the browser does not seem to support web sockets");
-      return;
-    }
-    if (!(this.options = Options.extract(this.window.document))) {
-      console.error("LiveReload disabled because it could not find its own <SCRIPT> tag");
-      return;
-    }
-    this.reloader = new Reloader(this.window, this.console, Timer);
-    this.connector = new Connector(this.options, this.WebSocket, Timer, {
-      connecting: function() {},
-      socketConnected: function() {},
-      connected: function(protocol) {
-        var _base;
-        if (typeof (_base = _this.listeners).connect === "function") {
-          _base.connect();
-        }
-        _this.log("LiveReload is connected to " + _this.options.host + ":" + _this.options.port + " (protocol v" + protocol + ").");
-        return _this.analyze();
-      },
-      error: function(e) {
-        if (e instanceof ProtocolError) {
-          return console.log("" + e.message + ".");
-        } else {
-          return console.log("LiveReload internal error: " + e.message);
-        }
-      },
-      disconnected: function(reason, nextDelay) {
-        var _base;
-        if (typeof (_base = _this.listeners).disconnect === "function") {
-          _base.disconnect();
-        }
-        switch (reason) {
-          case 'cannot-connect':
-            return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + ", will retry in " + nextDelay + " sec.");
-          case 'broken':
-            return _this.log("LiveReload disconnected from " + _this.options.host + ":" + _this.options.port + ", reconnecting in " + nextDelay + " sec.");
-          case 'handshake-timeout':
-            return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + " (handshake timeout), will retry in " + nextDelay + " sec.");
-          case 'handshake-failed':
-            return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + " (handshake failed), will retry in " + nextDelay + " sec.");
-          case 'manual':
-            break;
-          case 'error':
-            break;
-          default:
-            return _this.log("LiveReload disconnected from " + _this.options.host + ":" + _this.options.port + " (" + reason + "), reconnecting in " + nextDelay + " sec.");
-        }
-      },
-      message: function(message) {
-        switch (message.command) {
-          case 'reload':
-            return _this.performReload(message);
-          case 'alert':
-            return _this.performAlert(message);
+        function LiveReload(window) {
+            var _this = this;
+            this.window = window;
+            this.listeners = {};
+            this.plugins = [];
+            this.pluginIdentifiers = {};
+            this.console = this.window.location.href.match(/LR-verbose/) && this.window.console && this.window.console.log && this.window.console.error ? this.window.console : {
+                log: function() {},
+                error: function() {}
+            };
+            if (!(this.WebSocket = this.window.WebSocket || this.window.MozWebSocket)) {
+                console.error("LiveReload disabled because the browser does not seem to support web sockets");
+                return;
+            }
+            if (!(this.options = Options.extract(this.window.document))) {
+                console.error("LiveReload disabled because it could not find its own <SCRIPT> tag");
+                return;
+            }
+            this.reloader = new Reloader(this.window, this.console, Timer);
+            this.connector = new Connector(this.options, this.WebSocket, Timer, {
+                connecting: function() {},
+                socketConnected: function() {},
+                connected: function(protocol) {
+                    var _base;
+                    if (typeof (_base = _this.listeners).connect === "function") {
+                        _base.connect();
+                    }
+                    _this.log("LiveReload is connected to " + _this.options.host + ":" + _this.options.port + " (protocol v" + protocol + ").");
+                    return _this.analyze();
+                },
+                error: function(e) {
+                    if (e instanceof ProtocolError) {
+                        return console.log("" + e.message + ".");
+                    } else {
+                        return console.log("LiveReload internal error: " + e.message);
+                    }
+                },
+                disconnected: function(reason, nextDelay) {
+                    var _base;
+                    if (typeof (_base = _this.listeners).disconnect === "function") {
+                        _base.disconnect();
+                    }
+                    switch (reason) {
+                        case 'cannot-connect':
+                            return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + ", will retry in " + nextDelay + " sec.");
+                        case 'broken':
+                            return _this.log("LiveReload disconnected from " + _this.options.host + ":" + _this.options.port + ", reconnecting in " + nextDelay + " sec.");
+                        case 'handshake-timeout':
+                            return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + " (handshake timeout), will retry in " + nextDelay + " sec.");
+                        case 'handshake-failed':
+                            return _this.log("LiveReload cannot connect to " + _this.options.host + ":" + _this.options.port + " (handshake failed), will retry in " + nextDelay + " sec.");
+                        case 'manual':
+                            break;
+                        case 'error':
+                            break;
+                        default:
+                            return _this.log("LiveReload disconnected from " + _this.options.host + ":" + _this.options.port + " (" + reason + "), reconnecting in " + nextDelay + " sec.");
+                    }
+                },
+                message: function(message) {
+                    switch (message.command) {
+                        case 'reload':
+                            return _this.performReload(message);
+                        case 'alert':
+                            return _this.performAlert(message);
+                    }
+                }
+            });
         }
-      }
-    });
-  }
-
-  LiveReload.prototype.on = function(eventName, handler) {
-    return this.listeners[eventName] = handler;
-  };
-
-  LiveReload.prototype.log = function(message) {
-    return this.console.log("" + message);
-  };
-
-  LiveReload.prototype.performReload = function(message) {
-    var _ref, _ref2;
-    this.log("LiveReload received reload request for " + message.path + ".");
-    return this.reloader.reload(message.path, {
-      liveCSS: (_ref = message.liveCSS) != null ? _ref : true,
-      liveImg: (_ref2 = message.liveImg) != null ? _ref2 : true,
-      originalPath: message.originalPath || '',
-      overrideURL: message.overrideURL || '',
-      serverURL: "http://" + this.options.host + ":" + this.options.port
-    });
-  };
-
-  LiveReload.prototype.performAlert = function(message) {
-    return alert(message.message);
-  };
-
-  LiveReload.prototype.shutDown = function() {
-    var _base;
-    this.connector.disconnect();
-    this.log("LiveReload disconnected.");
-    return typeof (_base = this.listeners).shutdown === "function" ? _base.shutdown() : void 0;
-  };
-
-  LiveReload.prototype.hasPlugin = function(identifier) {
-    return !!this.pluginIdentifiers[identifier];
-  };
-
-  LiveReload.prototype.addPlugin = function(pluginClass) {
-    var plugin;
-    var _this = this;
-    if (this.hasPlugin(pluginClass.identifier)) return;
-    this.pluginIdentifiers[pluginClass.identifier] = true;
-    plugin = new pluginClass(this.window, {
-      _livereload: this,
-      _reloader: this.reloader,
-      _connector: this.connector,
-      console: this.console,
-      Timer: Timer,
-      generateCacheBustUrl: function(url) {
-        return _this.reloader.generateCacheBustUrl(url);
-      }
-    });
-    this.plugins.push(plugin);
-    this.reloader.addPlugin(plugin);
-  };
-
-  LiveReload.prototype.analyze = function() {
-    var plugin, pluginData, pluginsData, _i, _len, _ref;
-    if (!(this.connector.protocol >= 7)) return;
-    pluginsData = {};
-    _ref = this.plugins;
-    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-      plugin = _ref[_i];
-      pluginsData[plugin.constructor.identifier] = pluginData = (typeof plugin.analyze === "function" ? plugin.analyze() : void 0) || {};
-      pluginData.version = plugin.constructor.version;
-    }
-    this.connector.sendCommand({
-      command: 'info',
-      plugins: pluginsData,
-      url: this.window.location.href
-    });
-  };
 
-  return LiveReload;
+        LiveReload.prototype.on = function(eventName, handler) {
+            return this.listeners[eventName] = handler;
+        };
+
+        LiveReload.prototype.log = function(message) {
+            return this.console.log("" + message);
+        };
+
+        LiveReload.prototype.performReload = function(message) {
+            var _ref, _ref2;
+            this.log("LiveReload received reload request for " + message.path + ".");
+            return this.reloader.reload(message.path, {
+                liveCSS: (_ref = message.liveCSS) != null ? _ref : true,
+                liveImg: (_ref2 = message.liveImg) != null ? _ref2 : true,
+                originalPath: message.originalPath || '',
+                overrideURL: message.overrideURL || '',
+                serverURL: "http://" + this.options.host + ":" + this.options.port
+            });
+        };
+
+        LiveReload.prototype.performAlert = function(message) {
+            return alert(message.message);
+        };
+
+        LiveReload.prototype.shutDown = function() {
+            var _base;
+            this.connector.disconnect();
+            this.log("LiveReload disconnected.");
+            return typeof (_base = this.listeners).shutdown === "function" ? _base.shutdown() : void 0;
+        };
+
+        LiveReload.prototype.hasPlugin = function(identifier) {
+            return !!this.pluginIdentifiers[identifier];
+        };
+
+        LiveReload.prototype.addPlugin = function(pluginClass) {
+            var plugin;
+            var _this = this;
+            if (this.hasPlugin(pluginClass.identifier)) return;
+            this.pluginIdentifiers[pluginClass.identifier] = true;
+            plugin = new pluginClass(this.window, {
+                _livereload: this,
+                _reloader: this.reloader,
+                _connector: this.connector,
+                console: this.console,
+                Timer: Timer,
+                generateCacheBustUrl: function(url) {
+                    return _this.reloader.generateCacheBustUrl(url);
+                }
+            });
+            this.plugins.push(plugin);
+            this.reloader.addPlugin(plugin);
+        };
+
+        LiveReload.prototype.analyze = function() {
+            var plugin, pluginData, pluginsData, _i, _len, _ref;
+            if (!(this.connector.protocol >= 7)) return;
+            pluginsData = {};
+            _ref = this.plugins;
+            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+                plugin = _ref[_i];
+                pluginsData[plugin.constructor.identifier] = pluginData = (typeof plugin.analyze === "function" ? plugin.analyze() : void 0) || {};
+                pluginData.version = plugin.constructor.version;
+            }
+            this.connector.sendCommand({
+                command: 'info',
+                plugins: pluginsData,
+                url: this.window.location.href
+            });
+        };
 
-})();
+        return LiveReload;
+
+    })();
 
 // less
-var LessPlugin;
-__less = LessPlugin = (function() {
-  LessPlugin.identifier = 'less';
-  LessPlugin.version = '1.0';
-  function LessPlugin(window, host) {
-    this.window = window;
-    this.host = host;
-  }
-  LessPlugin.prototype.reload = function(path, options) {
-    if (this.window.less && this.window.less.refresh) {
-      if (path.match(/\.less$/i)) {
-        return this.reloadLess(path);
-      }
-      if (options.originalPath.match(/\.less$/i)) {
-        return this.reloadLess(options.originalPath);
-      }
-    }
-    return false;
-  };
-  LessPlugin.prototype.reloadLess = function(path) {
-    var link, links, _i, _len;
-    links = (function() {
-      var _i, _len, _ref, _results;
-      _ref = document.getElementsByTagName('link');
-      _results = [];
-      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
-        link = _ref[_i];
-        if (link.href && link.rel === 'stylesheet/less' || (link.rel.match(/stylesheet/) && link.type.match(/^text\/(x-)?less$/))) {
-          _results.push(link);
+    var LessPlugin;
+    __less = LessPlugin = (function() {
+        LessPlugin.identifier = 'less';
+        LessPlugin.version = '1.0';
+        function LessPlugin(window, host) {
+            this.window = window;
+            this.host = host;
         }
-      }
-      return _results;
+        LessPlugin.prototype.reload = function(path, options) {
+            if (this.window.less && this.window.less.refresh) {
+                if (path.match(/\.less$/i)) {
+                    return this.reloadLess(path);
+                }
+                if (options.originalPath.match(/\.less$/i)) {
+                    return this.reloadLess(options.originalPath);
+                }
+            }
+            return false;
+        };
+        LessPlugin.prototype.reloadLess = function(path) {
+            var link, links, _i, _len;
+            links = (function() {
+                var _i, _len, _ref, _results;
+                _ref = document.getElementsByTagName('link');
+                _results = [];
+                for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+                    link = _ref[_i];
+                    if (link.href && link.rel === 'stylesheet/less' || (link.rel.match(/stylesheet/) && link.type.match(/^text\/(x-)?less$/))) {
+                        _results.push(link);
+                    }
+                }
+                return _results;
+            })();
+            if (links.length === 0) {
+                return false;
+            }
+            for (_i = 0, _len = links.length; _i < _len; _i++) {
+                link = links[_i];
+                link.href = this.host.generateCacheBustUrl(link.href);
+            }
+            this.host.console.log("LiveReload is asking LESS to recompile all stylesheets");
+            this.window.less.refresh(true);
+            return true;
+        };
+        LessPlugin.prototype.analyze = function() {
+            return {
+                disable: !!(this.window.less && this.window.less.refresh)
+            };
+        };
+        return LessPlugin;
     })();
-    if (links.length === 0) {
-      return false;
-    }
-    for (_i = 0, _len = links.length; _i < _len; _i++) {
-      link = links[_i];
-      link.href = this.host.generateCacheBustUrl(link.href);
-    }
-    this.host.console.log("LiveReload is asking LESS to recompile all stylesheets");
-    this.window.less.refresh(true);
-    return true;
-  };
-  LessPlugin.prototype.analyze = function() {
-    return {
-      disable: !!(this.window.less && this.window.less.refresh)
-    };
-  };
-  return LessPlugin;
-})();
 
 // startup
-var CustomEvents, LiveReload, k;
-CustomEvents = __customevents;
-LiveReload = window.LiveReload = new (__livereload.LiveReload)(window);
-for (k in window) {
-  if (k.match(/^LiveReloadPlugin/)) {
-    LiveReload.addPlugin(window[k]);
-  }
-}
-LiveReload.addPlugin(__less);
-LiveReload.on('shutdown', function() {
-  return delete window.LiveReload;
-});
-LiveReload.on('connect', function() {
-  return CustomEvents.fire(document, 'LiveReloadConnect');
-});
-LiveReload.on('disconnect', function() {
-  return CustomEvents.fire(document, 'LiveReloadDisconnect');
-});
-CustomEvents.bind(document, 'LiveReloadShutDown', function() {
-  return LiveReload.shutDown();
-});
-})();
+    var CustomEvents, LiveReload, k;
+    CustomEvents = __customevents;
+    LiveReload = window.LiveReload = new (__livereload.LiveReload)(window);
+    for (k in window) {
+        if (k.match(/^LiveReloadPlugin/)) {
+            LiveReload.addPlugin(window[k]);
+        }
+    }
+    LiveReload.addPlugin(__less);
+    LiveReload.on('shutdown', function() {
+        return delete window.LiveReload;
+    });
+    LiveReload.on('connect', function() {
+        return CustomEvents.fire(document, 'LiveReloadConnect');
+    });
+    LiveReload.on('disconnect', function() {
+        return CustomEvents.fire(document, 'LiveReloadDisconnect');
+    });
+    CustomEvents.bind(document, 'LiveReloadShutDown', function() {
+        return LiveReload.shutDown();
+    });
+})();
\ No newline at end of file
diff --git a/lib/rack-livereload.rb b/lib/rack-livereload.rb
index 63c3126..86ca377 100644
--- a/lib/rack-livereload.rb
+++ b/lib/rack-livereload.rb
@@ -1,6 +1,6 @@
 require "rack/livereload"
 
 class Rack::LiveReload
-  VERSION = '0.3.17'
+  VERSION = '0.4.2'
 end
 
diff --git a/lib/rack/livereload/body_processor.rb b/lib/rack/livereload/body_processor.rb
index df7a268..8524a22 100644
--- a/lib/rack/livereload/body_processor.rb
+++ b/lib/rack/livereload/body_processor.rb
@@ -4,8 +4,9 @@ module Rack
   class LiveReload
     class BodyProcessor
       LIVERELOAD_JS_PATH = '/__rack/livereload.js'
-      HEAD_TAG_REGEX = /<head>|<head[^(er)][^<]*>/
+      HEAD_TAG_REGEX = /<head( [^<]+)?>/
       LIVERELOAD_PORT = 35729
+      LIVERELOAD_SCHEME = "ws"
 
       attr_reader :content_length, :new_body, :livereload_added
 
@@ -14,12 +15,14 @@ module Rack
       end
 
       def livereload_local_uri
-        "#{protocol}://localhost:#{@options[:live_reload_port]}/livereload.js"
+        "#{protocol}://localhost:#{@options[:live_reload_port]}/" +
+          'livereload.js'
       end
 
       def initialize(body, options)
         @body, @options = body, options
         @options[:live_reload_port] ||= LIVERELOAD_PORT
+        @options[:live_reload_scheme] ||= LIVERELOAD_SCHEME
 
         @processed = false
       end
diff --git a/lib/rack/livereload/processing_skip_analyzer.rb b/lib/rack/livereload/processing_skip_analyzer.rb
index ec2b654..9218342 100644
--- a/lib/rack/livereload/processing_skip_analyzer.rb
+++ b/lib/rack/livereload/processing_skip_analyzer.rb
@@ -37,7 +37,7 @@ module Rack
       end
 
       def html?
-        @headers['Content-Type'] =~ %r{text/html}
+        @headers['Content-Type'] =~ %r{text/html|application/xhtml\+xml}
       end
 
       def get?
diff --git a/skel/livereload.html.erb b/skel/livereload.html.erb
index 6721c43..1c0a1ef 100644
--- a/skel/livereload.html.erb
+++ b/skel/livereload.html.erb
@@ -10,6 +10,7 @@
 <% end %>
 <script type="text/javascript">
   RACK_LIVERELOAD_PORT = <%= @options[:live_reload_port] %>;
+  RACK_LIVERELOAD_SCHEME = "<%= @options[:live_reload_scheme] %>";
 </script>
 <script type="text/javascript" src="<%= livereload_source %>"></script>
 
diff --git a/spec/rack/livereload/processing_skip_analyzer_spec.rb b/spec/rack/livereload/processing_skip_analyzer_spec.rb
index 35c19e4..8221815 100644
--- a/spec/rack/livereload/processing_skip_analyzer_spec.rb
+++ b/spec/rack/livereload/processing_skip_analyzer_spec.rb
@@ -95,6 +95,12 @@ describe Rack::LiveReload::ProcessingSkipAnalyzer do
       it { should be_html }
     end
 
+    context 'XHTML content' do
+      let(:headers) { { 'Content-Type' => 'application/xhtml+xml' } }
+
+      it { should be_html }
+    end
+
     context 'PDF content' do
       let(:headers) { { 'Content-Type' => 'application/pdf' } }
 

Debdiff

[The following lists of changes regard files as different if they have different names, permissions or owners.]

Files in second set of .debs but not in first

-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rack-livereload-0.4.2/js/livereload.js
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rack-livereload-0.4.2/lib/rack-livereload.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rack-livereload-0.4.2/lib/rack/livereload.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rack-livereload-0.4.2/lib/rack/livereload/body_processor.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rack-livereload-0.4.2/lib/rack/livereload/processing_skip_analyzer.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rack-livereload-0.4.2/skel/livereload.html.erb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/specifications/rack-livereload-0.4.2.gemspec

Files in first set of .debs but not in second

-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rack-livereload-0.3.17/js/livereload.js
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rack-livereload-0.3.17/lib/rack-livereload.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rack-livereload-0.3.17/lib/rack/livereload.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rack-livereload-0.3.17/lib/rack/livereload/body_processor.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rack-livereload-0.3.17/lib/rack/livereload/processing_skip_analyzer.rb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/gems/rack-livereload-0.3.17/skel/livereload.html.erb
-rw-r--r--  root/root   /usr/share/rubygems-integration/all/specifications/rack-livereload-0.3.17.gemspec

No differences were encountered in the control files

More details

Full run details