/**
 * @license
 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */
// @version 0.7.23
if (typeof WeakMap === "undefined") {
  (function() {
    var defineProperty = Object.defineProperty;
    var counter = Date.now() % 1e9;
    var WeakMap = function() {
      this.name = "__st" + (Math.random() * 1e9 >>> 0) + (counter++ + "__");
    };
    WeakMap.prototype = {
      set: function(key, value) {
        var entry = key[this.name];
        if (entry && entry[0] === key) entry[1] = value; else defineProperty(key, this.name, {
          value: [ key, value ],
          writable: true
        });
        return this;
      },
      get: function(key) {
        var entry;
        return (entry = key[this.name]) && entry[0] === key ? entry[1] : undefined;
      },
      "delete": function(key) {
        var entry = key[this.name];
        if (!entry || entry[0] !== key) return false;
        entry[0] = entry[1] = undefined;
        return true;
      },
      has: function(key) {
        var entry = key[this.name];
        if (!entry) return false;
        return entry[0] === key;
      }
    };
    window.WeakMap = WeakMap;
  })();
}

window.ShadowDOMPolyfill = {};

(function(scope) {
  "use strict";
  var constructorTable = new WeakMap();
  var nativePrototypeTable = new WeakMap();
  var wrappers = Object.create(null);
  function detectEval() {
    if (typeof chrome !== "undefined" && chrome.app && chrome.app.runtime) {
      return false;
    }
    if (navigator.getDeviceStorage) {
      return false;
    }
    try {
      var f = new Function("return true;");
      return f();
    } catch (ex) {
      return false;
    }
  }
  var hasEval = detectEval();
  function assert(b) {
    if (!b) throw new Error("Assertion failed");
  }
  var defineProperty = Object.defineProperty;
  var getOwnPropertyNames = Object.getOwnPropertyNames;
  var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
  function mixin(to, from) {
    var names = getOwnPropertyNames(from);
    for (var i = 0; i < names.length; i++) {
      var name = names[i];
      defineProperty(to, name, getOwnPropertyDescriptor(from, name));
    }
    return to;
  }
  function mixinStatics(to, from) {
    var names = getOwnPropertyNames(from);
    for (var i = 0; i < names.length; i++) {
      var name = names[i];
      switch (name) {
       case "arguments":
       case "caller":
       case "length":
       case "name":
       case "prototype":
       case "toString":
        continue;
      }
      defineProperty(to, name, getOwnPropertyDescriptor(from, name));
    }
    return to;
  }
  function oneOf(object, propertyNames) {
    for (var i = 0; i < propertyNames.length; i++) {
      if (propertyNames[i] in object) return propertyNames[i];
    }
  }
  var nonEnumerableDataDescriptor = {
    value: undefined,
    configurable: true,
    enumerable: false,
    writable: true
  };
  function defineNonEnumerableDataProperty(object, name, value) {
    nonEnumerableDataDescriptor.value = value;
    defineProperty(object, name, nonEnumerableDataDescriptor);
  }
  getOwnPropertyNames(window);
  function getWrapperConstructor(node, opt_instance) {
    var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);
    if (isFirefox) {
      try {
        getOwnPropertyNames(nativePrototype);
      } catch (error) {
        nativePrototype = nativePrototype.__proto__;
      }
    }
    var wrapperConstructor = constructorTable.get(nativePrototype);
    if (wrapperConstructor) return wrapperConstructor;
    var parentWrapperConstructor = getWrapperConstructor(nativePrototype);
    var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);
    registerInternal(nativePrototype, GeneratedWrapper, opt_instance);
    return GeneratedWrapper;
  }
  function addForwardingProperties(nativePrototype, wrapperPrototype) {
    installProperty(nativePrototype, wrapperPrototype, true);
  }
  function registerInstanceProperties(wrapperPrototype, instanceObject) {
    installProperty(instanceObject, wrapperPrototype, false);
  }
  var isFirefox = /Firefox/.test(navigator.userAgent);
  var dummyDescriptor = {
    get: function() {},
    set: function(v) {},
    configurable: true,
    enumerable: true
  };
  function isEventHandlerName(name) {
    return /^on[a-z]+$/.test(name);
  }
  function isIdentifierName(name) {
    return /^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name);
  }
  function getGetter(name) {
    return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name) : function() {
      return this.__impl4cf1e782hg__[name];
    };
  }
  function getSetter(name) {
    return hasEval && isIdentifierName(name) ? new Function("v", "this.__impl4cf1e782hg__." + name + " = v") : function(v) {
      this.__impl4cf1e782hg__[name] = v;
    };
  }
  function getMethod(name) {
    return hasEval && isIdentifierName(name) ? new Function("return this.__impl4cf1e782hg__." + name + ".apply(this.__impl4cf1e782hg__, arguments)") : function() {
      return this.__impl4cf1e782hg__[name].apply(this.__impl4cf1e782hg__, arguments);
    };
  }
  function getDescriptor(source, name) {
    try {
      if (source === window && name === "showModalDialog") {
        return dummyDescriptor;
      }
      return Object.getOwnPropertyDescriptor(source, name);
    } catch (ex) {
      return dummyDescriptor;
    }
  }
  var isBrokenSafari = function() {
    var descr = Object.getOwnPropertyDescriptor(Node.prototype, "nodeType");
    return descr && !descr.get && !descr.set;
  }();
  function installProperty(source, target, allowMethod, opt_blacklist) {
    var names = getOwnPropertyNames(source);
    for (var i = 0; i < names.length; i++) {
      var name = names[i];
      if (name === "polymerBlackList_") continue;
      if (name in target) continue;
      if (source.polymerBlackList_ && source.polymerBlackList_[name]) continue;
      if (isFirefox) {
        source.__lookupGetter__(name);
      }
      var descriptor = getDescriptor(source, name);
      var getter, setter;
      if (typeof descriptor.value === "function") {
        if (allowMethod) {
          target[name] = getMethod(name);
        }
        continue;
      }
      var isEvent = isEventHandlerName(name);
      if (isEvent) getter = scope.getEventHandlerGetter(name); else getter = getGetter(name);
      if (descriptor.writable || descriptor.set || isBrokenSafari) {
        if (isEvent) setter = scope.getEventHandlerSetter(name); else setter = getSetter(name);
      }
      var configurable = isBrokenSafari || descriptor.configurable;
      defineProperty(target, name, {
        get: getter,
        set: setter,
        configurable: configurable,
        enumerable: descriptor.enumerable
      });
    }
  }
  function register(nativeConstructor, wrapperConstructor, opt_instance) {
    if (nativeConstructor == null) {
      return;
    }
    var nativePrototype = nativeConstructor.prototype;
    registerInternal(nativePrototype, wrapperConstructor, opt_instance);
    mixinStatics(wrapperConstructor, nativeConstructor);
  }
  function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {
    var wrapperPrototype = wrapperConstructor.prototype;
    assert(constructorTable.get(nativePrototype) === undefined);
    constructorTable.set(nativePrototype, wrapperConstructor);
    nativePrototypeTable.set(wrapperPrototype, nativePrototype);
    addForwardingProperties(nativePrototype, wrapperPrototype);
    if (opt_instance) registerInstanceProperties(wrapperPrototype, opt_instance);
    defineNonEnumerableDataProperty(wrapperPrototype, "constructor", wrapperConstructor);
    wrapperConstructor.prototype = wrapperPrototype;
  }
  function isWrapperFor(wrapperConstructor, nativeConstructor) {
    return constructorTable.get(nativeConstructor.prototype) === wrapperConstructor;
  }
  function registerObject(object) {
    var nativePrototype = Object.getPrototypeOf(object);
    var superWrapperConstructor = getWrapperConstructor(nativePrototype);
    var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);
    registerInternal(nativePrototype, GeneratedWrapper, object);
    return GeneratedWrapper;
  }
  function createWrapperConstructor(superWrapperConstructor) {
    function GeneratedWrapper(node) {
      superWrapperConstructor.call(this, node);
    }
    var p = Object.create(superWrapperConstructor.prototype);
    p.constructor = GeneratedWrapper;
    GeneratedWrapper.prototype = p;
    return GeneratedWrapper;
  }
  function isWrapper(object) {
    return object && object.__impl4cf1e782hg__;
  }
  function isNative(object) {
    return !isWrapper(object);
  }
  function wrap(impl) {
    if (impl === null) return null;
    assert(isNative(impl));
    var wrapper = impl.__wrapper8e3dd93a60__;
    if (wrapper != null) {
      return wrapper;
    }
    return impl.__wrapper8e3dd93a60__ = new (getWrapperConstructor(impl, impl))(impl);
  }
  function unwrap(wrapper) {
    if (wrapper === null) return null;
    assert(isWrapper(wrapper));
    return wrapper.__impl4cf1e782hg__;
  }
  function unsafeUnwrap(wrapper) {
    return wrapper.__impl4cf1e782hg__;
  }
  function setWrapper(impl, wrapper) {
    wrapper.__impl4cf1e782hg__ = impl;
    impl.__wrapper8e3dd93a60__ = wrapper;
  }
  function unwrapIfNeeded(object) {
    return object && isWrapper(object) ? unwrap(object) : object;
  }
  function wrapIfNeeded(object) {
    return object && !isWrapper(object) ? wrap(object) : object;
  }
  function rewrap(node, wrapper) {
    if (wrapper === null) return;
    assert(isNative(node));
    assert(wrapper === undefined || isWrapper(wrapper));
    node.__wrapper8e3dd93a60__ = wrapper;
  }
  var getterDescriptor = {
    get: undefined,
    configurable: true,
    enumerable: true
  };
  function defineGetter(constructor, name, getter) {
    getterDescriptor.get = getter;
    defineProperty(constructor.prototype, name, getterDescriptor);
  }
  function defineWrapGetter(constructor, name) {
    defineGetter(constructor, name, function() {
      return wrap(this.__impl4cf1e782hg__[name]);
    });
  }
  function forwardMethodsToWrapper(constructors, names) {
    constructors.forEach(function(constructor) {
      names.forEach(function(name) {
        constructor.prototype[name] = function() {
          var w = wrapIfNeeded(this);
          return w[name].apply(w, arguments);
        };
      });
    });
  }
  scope.addForwardingProperties = addForwardingProperties;
  scope.assert = assert;
  scope.constructorTable = constructorTable;
  scope.defineGetter = defineGetter;
  scope.defineWrapGetter = defineWrapGetter;
  scope.forwardMethodsToWrapper = forwardMethodsToWrapper;
  scope.isIdentifierName = isIdentifierName;
  scope.isWrapper = isWrapper;
  scope.isWrapperFor = isWrapperFor;
  scope.mixin = mixin;
  scope.nativePrototypeTable = nativePrototypeTable;
  scope.oneOf = oneOf;
  scope.registerObject = registerObject;
  scope.registerWrapper = register;
  scope.rewrap = rewrap;
  scope.setWrapper = setWrapper;
  scope.unsafeUnwrap = unsafeUnwrap;
  scope.unwrap = unwrap;
  scope.unwrapIfNeeded = unwrapIfNeeded;
  scope.wrap = wrap;
  scope.wrapIfNeeded = wrapIfNeeded;
  scope.wrappers = wrappers;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  function newSplice(index, removed, addedCount) {
    return {
      index: index,
      removed: removed,
      addedCount: addedCount
    };
  }
  var EDIT_LEAVE = 0;
  var EDIT_UPDATE = 1;
  var EDIT_ADD = 2;
  var EDIT_DELETE = 3;
  function ArraySplice() {}
  ArraySplice.prototype = {
    calcEditDistances: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {
      var rowCount = oldEnd - oldStart + 1;
      var columnCount = currentEnd - currentStart + 1;
      var distances = new Array(rowCount);
      for (var i = 0; i < rowCount; i++) {
        distances[i] = new Array(columnCount);
        distances[i][0] = i;
      }
      for (var j = 0; j < columnCount; j++) distances[0][j] = j;
      for (var i = 1; i < rowCount; i++) {
        for (var j = 1; j < columnCount; j++) {
          if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1])) distances[i][j] = distances[i - 1][j - 1]; else {
            var north = distances[i - 1][j] + 1;
            var west = distances[i][j - 1] + 1;
            distances[i][j] = north < west ? north : west;
          }
        }
      }
      return distances;
    },
    spliceOperationsFromEditDistances: function(distances) {
      var i = distances.length - 1;
      var j = distances[0].length - 1;
      var current = distances[i][j];
      var edits = [];
      while (i > 0 || j > 0) {
        if (i == 0) {
          edits.push(EDIT_ADD);
          j--;
          continue;
        }
        if (j == 0) {
          edits.push(EDIT_DELETE);
          i--;
          continue;
        }
        var northWest = distances[i - 1][j - 1];
        var west = distances[i - 1][j];
        var north = distances[i][j - 1];
        var min;
        if (west < north) min = west < northWest ? west : northWest; else min = north < northWest ? north : northWest;
        if (min == northWest) {
          if (northWest == current) {
            edits.push(EDIT_LEAVE);
          } else {
            edits.push(EDIT_UPDATE);
            current = northWest;
          }
          i--;
          j--;
        } else if (min == west) {
          edits.push(EDIT_DELETE);
          i--;
          current = west;
        } else {
          edits.push(EDIT_ADD);
          j--;
          current = north;
        }
      }
      edits.reverse();
      return edits;
    },
    calcSplices: function(current, currentStart, currentEnd, old, oldStart, oldEnd) {
      var prefixCount = 0;
      var suffixCount = 0;
      var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
      if (currentStart == 0 && oldStart == 0) prefixCount = this.sharedPrefix(current, old, minLength);
      if (currentEnd == current.length && oldEnd == old.length) suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);
      currentStart += prefixCount;
      oldStart += prefixCount;
      currentEnd -= suffixCount;
      oldEnd -= suffixCount;
      if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) return [];
      if (currentStart == currentEnd) {
        var splice = newSplice(currentStart, [], 0);
        while (oldStart < oldEnd) splice.removed.push(old[oldStart++]);
        return [ splice ];
      } else if (oldStart == oldEnd) return [ newSplice(currentStart, [], currentEnd - currentStart) ];
      var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));
      var splice = undefined;
      var splices = [];
      var index = currentStart;
      var oldIndex = oldStart;
      for (var i = 0; i < ops.length; i++) {
        switch (ops[i]) {
         case EDIT_LEAVE:
          if (splice) {
            splices.push(splice);
            splice = undefined;
          }
          index++;
          oldIndex++;
          break;

         case EDIT_UPDATE:
          if (!splice) splice = newSplice(index, [], 0);
          splice.addedCount++;
          index++;
          splice.removed.push(old[oldIndex]);
          oldIndex++;
          break;

         case EDIT_ADD:
          if (!splice) splice = newSplice(index, [], 0);
          splice.addedCount++;
          index++;
          break;

         case EDIT_DELETE:
          if (!splice) splice = newSplice(index, [], 0);
          splice.removed.push(old[oldIndex]);
          oldIndex++;
          break;
        }
      }
      if (splice) {
        splices.push(splice);
      }
      return splices;
    },
    sharedPrefix: function(current, old, searchLength) {
      for (var i = 0; i < searchLength; i++) if (!this.equals(current[i], old[i])) return i;
      return searchLength;
    },
    sharedSuffix: function(current, old, searchLength) {
      var index1 = current.length;
      var index2 = old.length;
      var count = 0;
      while (count < searchLength && this.equals(current[--index1], old[--index2])) count++;
      return count;
    },
    calculateSplices: function(current, previous) {
      return this.calcSplices(current, 0, current.length, previous, 0, previous.length);
    },
    equals: function(currentValue, previousValue) {
      return currentValue === previousValue;
    }
  };
  scope.ArraySplice = ArraySplice;
})(window.ShadowDOMPolyfill);

(function(context) {
  "use strict";
  var OriginalMutationObserver = window.MutationObserver;
  var callbacks = [];
  var pending = false;
  var timerFunc;
  function handle() {
    pending = false;
    var copies = callbacks.slice(0);
    callbacks = [];
    for (var i = 0; i < copies.length; i++) {
      (0, copies[i])();
    }
  }
  if (OriginalMutationObserver) {
    var counter = 1;
    var observer = new OriginalMutationObserver(handle);
    var textNode = document.createTextNode(counter);
    observer.observe(textNode, {
      characterData: true
    });
    timerFunc = function() {
      counter = (counter + 1) % 2;
      textNode.data = counter;
    };
  } else {
    timerFunc = window.setTimeout;
  }
  function setEndOfMicrotask(func) {
    callbacks.push(func);
    if (pending) return;
    pending = true;
    timerFunc(handle, 0);
  }
  context.setEndOfMicrotask = setEndOfMicrotask;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var setEndOfMicrotask = scope.setEndOfMicrotask;
  var wrapIfNeeded = scope.wrapIfNeeded;
  var wrappers = scope.wrappers;
  var registrationsTable = new WeakMap();
  var globalMutationObservers = [];
  var isScheduled = false;
  function scheduleCallback(observer) {
    if (observer.scheduled_) return;
    observer.scheduled_ = true;
    globalMutationObservers.push(observer);
    if (isScheduled) return;
    setEndOfMicrotask(notifyObservers);
    isScheduled = true;
  }
  function notifyObservers() {
    isScheduled = false;
    while (globalMutationObservers.length) {
      var notifyList = globalMutationObservers;
      globalMutationObservers = [];
      notifyList.sort(function(x, y) {
        return x.uid_ - y.uid_;
      });
      for (var i = 0; i < notifyList.length; i++) {
        var mo = notifyList[i];
        mo.scheduled_ = false;
        var queue = mo.takeRecords();
        removeTransientObserversFor(mo);
        if (queue.length) {
          mo.callback_(queue, mo);
        }
      }
    }
  }
  function MutationRecord(type, target) {
    this.type = type;
    this.target = target;
    this.addedNodes = new wrappers.NodeList();
    this.removedNodes = new wrappers.NodeList();
    this.previousSibling = null;
    this.nextSibling = null;
    this.attributeName = null;
    this.attributeNamespace = null;
    this.oldValue = null;
  }
  function registerTransientObservers(ancestor, node) {
    for (;ancestor; ancestor = ancestor.parentNode) {
      var registrations = registrationsTable.get(ancestor);
      if (!registrations) continue;
      for (var i = 0; i < registrations.length; i++) {
        var registration = registrations[i];
        if (registration.options.subtree) registration.addTransientObserver(node);
      }
    }
  }
  function removeTransientObserversFor(observer) {
    for (var i = 0; i < observer.nodes_.length; i++) {
      var node = observer.nodes_[i];
      var registrations = registrationsTable.get(node);
      if (!registrations) return;
      for (var j = 0; j < registrations.length; j++) {
        var registration = registrations[j];
        if (registration.observer === observer) registration.removeTransientObservers();
      }
    }
  }
  function enqueueMutation(target, type, data) {
    var interestedObservers = Object.create(null);
    var associatedStrings = Object.create(null);
    for (var node = target; node; node = node.parentNode) {
      var registrations = registrationsTable.get(node);
      if (!registrations) continue;
      for (var j = 0; j < registrations.length; j++) {
        var registration = registrations[j];
        var options = registration.options;
        if (node !== target && !options.subtree) continue;
        if (type === "attributes" && !options.attributes) continue;
        if (type === "attributes" && options.attributeFilter && (data.namespace !== null || options.attributeFilter.indexOf(data.name) === -1)) {
          continue;
        }
        if (type === "characterData" && !options.characterData) continue;
        if (type === "childList" && !options.childList) continue;
        var observer = registration.observer;
        interestedObservers[observer.uid_] = observer;
        if (type === "attributes" && options.attributeOldValue || type === "characterData" && options.characterDataOldValue) {
          associatedStrings[observer.uid_] = data.oldValue;
        }
      }
    }
    for (var uid in interestedObservers) {
      var observer = interestedObservers[uid];
      var record = new MutationRecord(type, target);
      if ("name" in data && "namespace" in data) {
        record.attributeName = data.name;
        record.attributeNamespace = data.namespace;
      }
      if (data.addedNodes) record.addedNodes = data.addedNodes;
      if (data.removedNodes) record.removedNodes = data.removedNodes;
      if (data.previousSibling) record.previousSibling = data.previousSibling;
      if (data.nextSibling) record.nextSibling = data.nextSibling;
      if (associatedStrings[uid] !== undefined) record.oldValue = associatedStrings[uid];
      scheduleCallback(observer);
      observer.records_.push(record);
    }
  }
  var slice = Array.prototype.slice;
  function MutationObserverOptions(options) {
    this.childList = !!options.childList;
    this.subtree = !!options.subtree;
    if (!("attributes" in options) && ("attributeOldValue" in options || "attributeFilter" in options)) {
      this.attributes = true;
    } else {
      this.attributes = !!options.attributes;
    }
    if ("characterDataOldValue" in options && !("characterData" in options)) this.characterData = true; else this.characterData = !!options.characterData;
    if (!this.attributes && (options.attributeOldValue || "attributeFilter" in options) || !this.characterData && options.characterDataOldValue) {
      throw new TypeError();
    }
    this.characterData = !!options.characterData;
    this.attributeOldValue = !!options.attributeOldValue;
    this.characterDataOldValue = !!options.characterDataOldValue;
    if ("attributeFilter" in options) {
      if (options.attributeFilter == null || typeof options.attributeFilter !== "object") {
        throw new TypeError();
      }
      this.attributeFilter = slice.call(options.attributeFilter);
    } else {
      this.attributeFilter = null;
    }
  }
  var uidCounter = 0;
  function MutationObserver(callback) {
    this.callback_ = callback;
    this.nodes_ = [];
    this.records_ = [];
    this.uid_ = ++uidCounter;
    this.scheduled_ = false;
  }
  MutationObserver.prototype = {
    constructor: MutationObserver,
    observe: function(target, options) {
      target = wrapIfNeeded(target);
      var newOptions = new MutationObserverOptions(options);
      var registration;
      var registrations = registrationsTable.get(target);
      if (!registrations) registrationsTable.set(target, registrations = []);
      for (var i = 0; i < registrations.length; i++) {
        if (registrations[i].observer === this) {
          registration = registrations[i];
          registration.removeTransientObservers();
          registration.options = newOptions;
        }
      }
      if (!registration) {
        registration = new Registration(this, target, newOptions);
        registrations.push(registration);
        this.nodes_.push(target);
      }
    },
    disconnect: function() {
      this.nodes_.forEach(function(node) {
        var registrations = registrationsTable.get(node);
        for (var i = 0; i < registrations.length; i++) {
          var registration = registrations[i];
          if (registration.observer === this) {
            registrations.splice(i, 1);
            break;
          }
        }
      }, this);
      this.records_ = [];
    },
    takeRecords: function() {
      var copyOfRecords = this.records_;
      this.records_ = [];
      return copyOfRecords;
    }
  };
  function Registration(observer, target, options) {
    this.observer = observer;
    this.target = target;
    this.options = options;
    this.transientObservedNodes = [];
  }
  Registration.prototype = {
    addTransientObserver: function(node) {
      if (node === this.target) return;
      scheduleCallback(this.observer);
      this.transientObservedNodes.push(node);
      var registrations = registrationsTable.get(node);
      if (!registrations) registrationsTable.set(node, registrations = []);
      registrations.push(this);
    },
    removeTransientObservers: function() {
      var transientObservedNodes = this.transientObservedNodes;
      this.transientObservedNodes = [];
      for (var i = 0; i < transientObservedNodes.length; i++) {
        var node = transientObservedNodes[i];
        var registrations = registrationsTable.get(node);
        for (var j = 0; j < registrations.length; j++) {
          if (registrations[j] === this) {
            registrations.splice(j, 1);
            break;
          }
        }
      }
    }
  };
  scope.enqueueMutation = enqueueMutation;
  scope.registerTransientObservers = registerTransientObservers;
  scope.wrappers.MutationObserver = MutationObserver;
  scope.wrappers.MutationRecord = MutationRecord;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  function TreeScope(root, parent) {
    this.root = root;
    this.parent = parent;
  }
  TreeScope.prototype = {
    get renderer() {
      if (this.root instanceof scope.wrappers.ShadowRoot) {
        return scope.getRendererForHost(this.root.host);
      }
      return null;
    },
    contains: function(treeScope) {
      for (;treeScope; treeScope = treeScope.parent) {
        if (treeScope === this) return true;
      }
      return false;
    }
  };
  function setTreeScope(node, treeScope) {
    if (node.treeScope_ !== treeScope) {
      node.treeScope_ = treeScope;
      for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) {
        sr.treeScope_.parent = treeScope;
      }
      for (var child = node.firstChild; child; child = child.nextSibling) {
        setTreeScope(child, treeScope);
      }
    }
  }
  function getTreeScope(node) {
    if (node instanceof scope.wrappers.Window) {
      debugger;
    }
    if (node.treeScope_) return node.treeScope_;
    var parent = node.parentNode;
    var treeScope;
    if (parent) treeScope = getTreeScope(parent); else treeScope = new TreeScope(node, null);
    return node.treeScope_ = treeScope;
  }
  scope.TreeScope = TreeScope;
  scope.getTreeScope = getTreeScope;
  scope.setTreeScope = setTreeScope;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
  var getTreeScope = scope.getTreeScope;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var setWrapper = scope.setWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var wrappers = scope.wrappers;
  var wrappedFuns = new WeakMap();
  var listenersTable = new WeakMap();
  var handledEventsTable = new WeakMap();
  var currentlyDispatchingEvents = new WeakMap();
  var targetTable = new WeakMap();
  var currentTargetTable = new WeakMap();
  var relatedTargetTable = new WeakMap();
  var eventPhaseTable = new WeakMap();
  var stopPropagationTable = new WeakMap();
  var stopImmediatePropagationTable = new WeakMap();
  var eventHandlersTable = new WeakMap();
  var eventPathTable = new WeakMap();
  function isShadowRoot(node) {
    return node instanceof wrappers.ShadowRoot;
  }
  function rootOfNode(node) {
    return getTreeScope(node).root;
  }
  function getEventPath(node, event) {
    var path = [];
    var current = node;
    path.push(current);
    while (current) {
      var destinationInsertionPoints = getDestinationInsertionPoints(current);
      if (destinationInsertionPoints && destinationInsertionPoints.length > 0) {
        for (var i = 0; i < destinationInsertionPoints.length; i++) {
          var insertionPoint = destinationInsertionPoints[i];
          if (isShadowInsertionPoint(insertionPoint)) {
            var shadowRoot = rootOfNode(insertionPoint);
            var olderShadowRoot = shadowRoot.olderShadowRoot;
            if (olderShadowRoot) path.push(olderShadowRoot);
          }
          path.push(insertionPoint);
        }
        current = destinationInsertionPoints[destinationInsertionPoints.length - 1];
      } else {
        if (isShadowRoot(current)) {
          if (inSameTree(node, current) && eventMustBeStopped(event)) {
            break;
          }
          current = current.host;
          path.push(current);
        } else {
          current = current.parentNode;
          if (current) path.push(current);
        }
      }
    }
    return path;
  }
  function eventMustBeStopped(event) {
    if (!event) return false;
    switch (event.type) {
     case "abort":
     case "error":
     case "select":
     case "change":
     case "load":
     case "reset":
     case "resize":
     case "scroll":
     case "selectstart":
      return true;
    }
    return false;
  }
  function isShadowInsertionPoint(node) {
    return node instanceof HTMLShadowElement;
  }
  function getDestinationInsertionPoints(node) {
    return scope.getDestinationInsertionPoints(node);
  }
  function eventRetargetting(path, currentTarget) {
    if (path.length === 0) return currentTarget;
    if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
    var currentTargetTree = getTreeScope(currentTarget);
    var originalTarget = path[0];
    var originalTargetTree = getTreeScope(originalTarget);
    var relativeTargetTree = lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree);
    for (var i = 0; i < path.length; i++) {
      var node = path[i];
      if (getTreeScope(node) === relativeTargetTree) return node;
    }
    return path[path.length - 1];
  }
  function getTreeScopeAncestors(treeScope) {
    var ancestors = [];
    for (;treeScope; treeScope = treeScope.parent) {
      ancestors.push(treeScope);
    }
    return ancestors;
  }
  function lowestCommonInclusiveAncestor(tsA, tsB) {
    var ancestorsA = getTreeScopeAncestors(tsA);
    var ancestorsB = getTreeScopeAncestors(tsB);
    var result = null;
    while (ancestorsA.length > 0 && ancestorsB.length > 0) {
      var a = ancestorsA.pop();
      var b = ancestorsB.pop();
      if (a === b) result = a; else break;
    }
    return result;
  }
  function getTreeScopeRoot(ts) {
    if (!ts.parent) return ts;
    return getTreeScopeRoot(ts.parent);
  }
  function relatedTargetResolution(event, currentTarget, relatedTarget) {
    if (currentTarget instanceof wrappers.Window) currentTarget = currentTarget.document;
    var currentTargetTree = getTreeScope(currentTarget);
    var relatedTargetTree = getTreeScope(relatedTarget);
    var relatedTargetEventPath = getEventPath(relatedTarget, event);
    var lowestCommonAncestorTree;
    var lowestCommonAncestorTree = lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree);
    if (!lowestCommonAncestorTree) lowestCommonAncestorTree = relatedTargetTree.root;
    for (var commonAncestorTree = lowestCommonAncestorTree; commonAncestorTree; commonAncestorTree = commonAncestorTree.parent) {
      var adjustedRelatedTarget;
      for (var i = 0; i < relatedTargetEventPath.length; i++) {
        var node = relatedTargetEventPath[i];
        if (getTreeScope(node) === commonAncestorTree) return node;
      }
    }
    return null;
  }
  function inSameTree(a, b) {
    return getTreeScope(a) === getTreeScope(b);
  }
  var NONE = 0;
  var CAPTURING_PHASE = 1;
  var AT_TARGET = 2;
  var BUBBLING_PHASE = 3;
  var pendingError;
  function dispatchOriginalEvent(originalEvent) {
    if (handledEventsTable.get(originalEvent)) return;
    handledEventsTable.set(originalEvent, true);
    dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
    if (pendingError) {
      var err = pendingError;
      pendingError = null;
      throw err;
    }
  }
  function isLoadLikeEvent(event) {
    switch (event.type) {
     case "load":
     case "beforeunload":
     case "unload":
      return true;
    }
    return false;
  }
  function dispatchEvent(event, originalWrapperTarget) {
    if (currentlyDispatchingEvents.get(event)) throw new Error("InvalidStateError");
    currentlyDispatchingEvents.set(event, true);
    scope.renderAllPending();
    var eventPath;
    var overrideTarget;
    var win;
    if (isLoadLikeEvent(event) && !event.bubbles) {
      var doc = originalWrapperTarget;
      if (doc instanceof wrappers.Document && (win = doc.defaultView)) {
        overrideTarget = doc;
        eventPath = [];
      }
    }
    if (!eventPath) {
      if (originalWrapperTarget instanceof wrappers.Window) {
        win = originalWrapperTarget;
        eventPath = [];
      } else {
        eventPath = getEventPath(originalWrapperTarget, event);
        if (!isLoadLikeEvent(event)) {
          var doc = eventPath[eventPath.length - 1];
          if (doc instanceof wrappers.Document) win = doc.defaultView;
        }
      }
    }
    eventPathTable.set(event, eventPath);
    if (dispatchCapturing(event, eventPath, win, overrideTarget)) {
      if (dispatchAtTarget(event, eventPath, win, overrideTarget)) {
        dispatchBubbling(event, eventPath, win, overrideTarget);
      }
    }
    eventPhaseTable.set(event, NONE);
    currentTargetTable.delete(event, null);
    currentlyDispatchingEvents.delete(event);
    return event.defaultPrevented;
  }
  function dispatchCapturing(event, eventPath, win, overrideTarget) {
    var phase = CAPTURING_PHASE;
    if (win) {
      if (!invoke(win, event, phase, eventPath, overrideTarget)) return false;
    }
    for (var i = eventPath.length - 1; i > 0; i--) {
      if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return false;
    }
    return true;
  }
  function dispatchAtTarget(event, eventPath, win, overrideTarget) {
    var phase = AT_TARGET;
    var currentTarget = eventPath[0] || win;
    return invoke(currentTarget, event, phase, eventPath, overrideTarget);
  }
  function dispatchBubbling(event, eventPath, win, overrideTarget) {
    var phase = BUBBLING_PHASE;
    for (var i = 1; i < eventPath.length; i++) {
      if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget)) return;
    }
    if (win && eventPath.length > 0) {
      invoke(win, event, phase, eventPath, overrideTarget);
    }
  }
  function invoke(currentTarget, event, phase, eventPath, overrideTarget) {
    var listeners = listenersTable.get(currentTarget);
    if (!listeners) return true;
    var target = overrideTarget || eventRetargetting(eventPath, currentTarget);
    if (target === currentTarget) {
      if (phase === CAPTURING_PHASE) return true;
      if (phase === BUBBLING_PHASE) phase = AT_TARGET;
    } else if (phase === BUBBLING_PHASE && !event.bubbles) {
      return true;
    }
    if ("relatedTarget" in event) {
      var originalEvent = unwrap(event);
      var unwrappedRelatedTarget = originalEvent.relatedTarget;
      if (unwrappedRelatedTarget) {
        if (unwrappedRelatedTarget instanceof Object && unwrappedRelatedTarget.addEventListener) {
          var relatedTarget = wrap(unwrappedRelatedTarget);
          var adjusted = relatedTargetResolution(event, currentTarget, relatedTarget);
          if (adjusted === target) return true;
        } else {
          adjusted = null;
        }
        relatedTargetTable.set(event, adjusted);
      }
    }
    eventPhaseTable.set(event, phase);
    var type = event.type;
    var anyRemoved = false;
    targetTable.set(event, target);
    currentTargetTable.set(event, currentTarget);
    listeners.depth++;
    for (var i = 0, len = listeners.length; i < len; i++) {
      var listener = listeners[i];
      if (listener.removed) {
        anyRemoved = true;
        continue;
      }
      if (listener.type !== type || !listener.capture && phase === CAPTURING_PHASE || listener.capture && phase === BUBBLING_PHASE) {
        continue;
      }
      try {
        if (typeof listener.handler === "function") listener.handler.call(currentTarget, event); else listener.handler.handleEvent(event);
        if (stopImmediatePropagationTable.get(event)) return false;
      } catch (ex) {
        if (!pendingError) pendingError = ex;
      }
    }
    listeners.depth--;
    if (anyRemoved && listeners.depth === 0) {
      var copy = listeners.slice();
      listeners.length = 0;
      for (var i = 0; i < copy.length; i++) {
        if (!copy[i].removed) listeners.push(copy[i]);
      }
    }
    return !stopPropagationTable.get(event);
  }
  function Listener(type, handler, capture) {
    this.type = type;
    this.handler = handler;
    this.capture = Boolean(capture);
  }
  Listener.prototype = {
    equals: function(that) {
      return this.handler === that.handler && this.type === that.type && this.capture === that.capture;
    },
    get removed() {
      return this.handler === null;
    },
    remove: function() {
      this.handler = null;
    }
  };
  var OriginalEvent = window.Event;
  OriginalEvent.prototype.polymerBlackList_ = {
    returnValue: true,
    keyLocation: true
  };
  function Event(type, options) {
    if (type instanceof OriginalEvent) {
      var impl = type;
      if (!OriginalBeforeUnloadEvent && impl.type === "beforeunload" && !(this instanceof BeforeUnloadEvent)) {
        return new BeforeUnloadEvent(impl);
      }
      setWrapper(impl, this);
    } else {
      return wrap(constructEvent(OriginalEvent, "Event", type, options));
    }
  }
  Event.prototype = {
    get target() {
      return targetTable.get(this);
    },
    get currentTarget() {
      return currentTargetTable.get(this);
    },
    get eventPhase() {
      return eventPhaseTable.get(this);
    },
    get path() {
      var eventPath = eventPathTable.get(this);
      if (!eventPath) return [];
      return eventPath.slice();
    },
    stopPropagation: function() {
      stopPropagationTable.set(this, true);
    },
    stopImmediatePropagation: function() {
      stopPropagationTable.set(this, true);
      stopImmediatePropagationTable.set(this, true);
    }
  };
  var supportsDefaultPrevented = function() {
    var e = document.createEvent("Event");
    e.initEvent("test", true, true);
    e.preventDefault();
    return e.defaultPrevented;
  }();
  if (!supportsDefaultPrevented) {
    Event.prototype.preventDefault = function() {
      if (!this.cancelable) return;
      unsafeUnwrap(this).preventDefault();
      Object.defineProperty(this, "defaultPrevented", {
        get: function() {
          return true;
        },
        configurable: true
      });
    };
  }
  registerWrapper(OriginalEvent, Event, document.createEvent("Event"));
  function unwrapOptions(options) {
    if (!options || !options.relatedTarget) return options;
    return Object.create(options, {
      relatedTarget: {
        value: unwrap(options.relatedTarget)
      }
    });
  }
  function registerGenericEvent(name, SuperEvent, prototype) {
    var OriginalEvent = window[name];
    var GenericEvent = function(type, options) {
      if (type instanceof OriginalEvent) setWrapper(type, this); else return wrap(constructEvent(OriginalEvent, name, type, options));
    };
    GenericEvent.prototype = Object.create(SuperEvent.prototype);
    if (prototype) mixin(GenericEvent.prototype, prototype);
    if (OriginalEvent) {
      try {
        registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent("temp"));
      } catch (ex) {
        registerWrapper(OriginalEvent, GenericEvent, document.createEvent(name));
      }
    }
    return GenericEvent;
  }
  var UIEvent = registerGenericEvent("UIEvent", Event);
  var CustomEvent = registerGenericEvent("CustomEvent", Event);
  var relatedTargetProto = {
    get relatedTarget() {
      var relatedTarget = relatedTargetTable.get(this);
      if (relatedTarget !== undefined) return relatedTarget;
      return wrap(unwrap(this).relatedTarget);
    }
  };
  function getInitFunction(name, relatedTargetIndex) {
    return function() {
      arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);
      var impl = unwrap(this);
      impl[name].apply(impl, arguments);
    };
  }
  var mouseEventProto = mixin({
    initMouseEvent: getInitFunction("initMouseEvent", 14)
  }, relatedTargetProto);
  var focusEventProto = mixin({
    initFocusEvent: getInitFunction("initFocusEvent", 5)
  }, relatedTargetProto);
  var MouseEvent = registerGenericEvent("MouseEvent", UIEvent, mouseEventProto);
  var FocusEvent = registerGenericEvent("FocusEvent", UIEvent, focusEventProto);
  var defaultInitDicts = Object.create(null);
  var supportsEventConstructors = function() {
    try {
      new window.FocusEvent("focus");
    } catch (ex) {
      return false;
    }
    return true;
  }();
  function constructEvent(OriginalEvent, name, type, options) {
    if (supportsEventConstructors) return new OriginalEvent(type, unwrapOptions(options));
    var event = unwrap(document.createEvent(name));
    var defaultDict = defaultInitDicts[name];
    var args = [ type ];
    Object.keys(defaultDict).forEach(function(key) {
      var v = options != null && key in options ? options[key] : defaultDict[key];
      if (key === "relatedTarget") v = unwrap(v);
      args.push(v);
    });
    event["init" + name].apply(event, args);
    return event;
  }
  if (!supportsEventConstructors) {
    var configureEventConstructor = function(name, initDict, superName) {
      if (superName) {
        var superDict = defaultInitDicts[superName];
        initDict = mixin(mixin({}, superDict), initDict);
      }
      defaultInitDicts[name] = initDict;
    };
    configureEventConstructor("Event", {
      bubbles: false,
      cancelable: false
    });
    configureEventConstructor("CustomEvent", {
      detail: null
    }, "Event");
    configureEventConstructor("UIEvent", {
      view: null,
      detail: 0
    }, "Event");
    configureEventConstructor("MouseEvent", {
      screenX: 0,
      screenY: 0,
      clientX: 0,
      clientY: 0,
      ctrlKey: false,
      altKey: false,
      shiftKey: false,
      metaKey: false,
      button: 0,
      relatedTarget: null
    }, "UIEvent");
    configureEventConstructor("FocusEvent", {
      relatedTarget: null
    }, "UIEvent");
  }
  var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent;
  function BeforeUnloadEvent(impl) {
    Event.call(this, impl);
  }
  BeforeUnloadEvent.prototype = Object.create(Event.prototype);
  mixin(BeforeUnloadEvent.prototype, {
    get returnValue() {
      return unsafeUnwrap(this).returnValue;
    },
    set returnValue(v) {
      unsafeUnwrap(this).returnValue = v;
    }
  });
  if (OriginalBeforeUnloadEvent) registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent);
  function isValidListener(fun) {
    if (typeof fun === "function") return true;
    return fun && fun.handleEvent;
  }
  function isMutationEvent(type) {
    switch (type) {
     case "DOMAttrModified":
     case "DOMAttributeNameChanged":
     case "DOMCharacterDataModified":
     case "DOMElementNameChanged":
     case "DOMNodeInserted":
     case "DOMNodeInsertedIntoDocument":
     case "DOMNodeRemoved":
     case "DOMNodeRemovedFromDocument":
     case "DOMSubtreeModified":
      return true;
    }
    return false;
  }
  var OriginalEventTarget = window.EventTarget;
  function EventTarget(impl) {
    setWrapper(impl, this);
  }
  var methodNames = [ "addEventListener", "removeEventListener", "dispatchEvent" ];
  [ Node, Window ].forEach(function(constructor) {
    var p = constructor.prototype;
    methodNames.forEach(function(name) {
      Object.defineProperty(p, name + "_", {
        value: p[name]
      });
    });
  });
  function getTargetToListenAt(wrapper) {
    if (wrapper instanceof wrappers.ShadowRoot) wrapper = wrapper.host;
    return unwrap(wrapper);
  }
  EventTarget.prototype = {
    addEventListener: function(type, fun, capture) {
      if (!isValidListener(fun) || isMutationEvent(type)) return;
      var listener = new Listener(type, fun, capture);
      var listeners = listenersTable.get(this);
      if (!listeners) {
        listeners = [];
        listeners.depth = 0;
        listenersTable.set(this, listeners);
      } else {
        for (var i = 0; i < listeners.length; i++) {
          if (listener.equals(listeners[i])) return;
        }
      }
      listeners.push(listener);
      var target = getTargetToListenAt(this);
      target.addEventListener_(type, dispatchOriginalEvent, true);
    },
    removeEventListener: function(type, fun, capture) {
      capture = Boolean(capture);
      var listeners = listenersTable.get(this);
      if (!listeners) return;
      var count = 0, found = false;
      for (var i = 0; i < listeners.length; i++) {
        if (listeners[i].type === type && listeners[i].capture === capture) {
          count++;
          if (listeners[i].handler === fun) {
            found = true;
            listeners[i].remove();
          }
        }
      }
      if (found && count === 1) {
        var target = getTargetToListenAt(this);
        target.removeEventListener_(type, dispatchOriginalEvent, true);
      }
    },
    dispatchEvent: function(event) {
      var nativeEvent = unwrap(event);
      var eventType = nativeEvent.type;
      handledEventsTable.set(nativeEvent, false);
      scope.renderAllPending();
      var tempListener;
      if (!hasListenerInAncestors(this, eventType)) {
        tempListener = function() {};
        this.addEventListener(eventType, tempListener, true);
      }
      try {
        return unwrap(this).dispatchEvent_(nativeEvent);
      } finally {
        if (tempListener) this.removeEventListener(eventType, tempListener, true);
      }
    }
  };
  function hasListener(node, type) {
    var listeners = listenersTable.get(node);
    if (listeners) {
      for (var i = 0; i < listeners.length; i++) {
        if (!listeners[i].removed && listeners[i].type === type) return true;
      }
    }
    return false;
  }
  function hasListenerInAncestors(target, type) {
    for (var node = unwrap(target); node; node = node.parentNode) {
      if (hasListener(wrap(node), type)) return true;
    }
    return false;
  }
  if (OriginalEventTarget) registerWrapper(OriginalEventTarget, EventTarget);
  function wrapEventTargetMethods(constructors) {
    forwardMethodsToWrapper(constructors, methodNames);
  }
  var originalElementFromPoint = document.elementFromPoint;
  function elementFromPoint(self, document, x, y) {
    scope.renderAllPending();
    var element = wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));
    if (!element) return null;
    var path = getEventPath(element, null);
    var idx = path.lastIndexOf(self);
    if (idx == -1) return null; else path = path.slice(0, idx);
    return eventRetargetting(path, self);
  }
  function getEventHandlerGetter(name) {
    return function() {
      var inlineEventHandlers = eventHandlersTable.get(this);
      return inlineEventHandlers && inlineEventHandlers[name] && inlineEventHandlers[name].value || null;
    };
  }
  function getEventHandlerSetter(name) {
    var eventType = name.slice(2);
    return function(value) {
      var inlineEventHandlers = eventHandlersTable.get(this);
      if (!inlineEventHandlers) {
        inlineEventHandlers = Object.create(null);
        eventHandlersTable.set(this, inlineEventHandlers);
      }
      var old = inlineEventHandlers[name];
      if (old) this.removeEventListener(eventType, old.wrapped, false);
      if (typeof value === "function") {
        var wrapped = function(e) {
          var rv = value.call(this, e);
          if (rv === false) e.preventDefault(); else if (name === "onbeforeunload" && typeof rv === "string") e.returnValue = rv;
        };
        this.addEventListener(eventType, wrapped, false);
        inlineEventHandlers[name] = {
          value: value,
          wrapped: wrapped
        };
      }
    };
  }
  scope.elementFromPoint = elementFromPoint;
  scope.getEventHandlerGetter = getEventHandlerGetter;
  scope.getEventHandlerSetter = getEventHandlerSetter;
  scope.wrapEventTargetMethods = wrapEventTargetMethods;
  scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;
  scope.wrappers.CustomEvent = CustomEvent;
  scope.wrappers.Event = Event;
  scope.wrappers.EventTarget = EventTarget;
  scope.wrappers.FocusEvent = FocusEvent;
  scope.wrappers.MouseEvent = MouseEvent;
  scope.wrappers.UIEvent = UIEvent;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var UIEvent = scope.wrappers.UIEvent;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var setWrapper = scope.setWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var wrap = scope.wrap;
  var OriginalTouchEvent = window.TouchEvent;
  if (!OriginalTouchEvent) return;
  var nativeEvent;
  try {
    nativeEvent = document.createEvent("TouchEvent");
  } catch (ex) {
    return;
  }
  var nonEnumDescriptor = {
    enumerable: false
  };
  function nonEnum(obj, prop) {
    Object.defineProperty(obj, prop, nonEnumDescriptor);
  }
  function Touch(impl) {
    setWrapper(impl, this);
  }
  Touch.prototype = {
    get target() {
      return wrap(unsafeUnwrap(this).target);
    }
  };
  var descr = {
    configurable: true,
    enumerable: true,
    get: null
  };
  [ "clientX", "clientY", "screenX", "screenY", "pageX", "pageY", "identifier", "webkitRadiusX", "webkitRadiusY", "webkitRotationAngle", "webkitForce" ].forEach(function(name) {
    descr.get = function() {
      return unsafeUnwrap(this)[name];
    };
    Object.defineProperty(Touch.prototype, name, descr);
  });
  function TouchList() {
    this.length = 0;
    nonEnum(this, "length");
  }
  TouchList.prototype = {
    item: function(index) {
      return this[index];
    }
  };
  function wrapTouchList(nativeTouchList) {
    var list = new TouchList();
    for (var i = 0; i < nativeTouchList.length; i++) {
      list[i] = new Touch(nativeTouchList[i]);
    }
    list.length = i;
    return list;
  }
  function TouchEvent(impl) {
    UIEvent.call(this, impl);
  }
  TouchEvent.prototype = Object.create(UIEvent.prototype);
  mixin(TouchEvent.prototype, {
    get touches() {
      return wrapTouchList(unsafeUnwrap(this).touches);
    },
    get targetTouches() {
      return wrapTouchList(unsafeUnwrap(this).targetTouches);
    },
    get changedTouches() {
      return wrapTouchList(unsafeUnwrap(this).changedTouches);
    },
    initTouchEvent: function() {
      throw new Error("Not implemented");
    }
  });
  registerWrapper(OriginalTouchEvent, TouchEvent, nativeEvent);
  scope.wrappers.Touch = Touch;
  scope.wrappers.TouchEvent = TouchEvent;
  scope.wrappers.TouchList = TouchList;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var unsafeUnwrap = scope.unsafeUnwrap;
  var wrap = scope.wrap;
  var nonEnumDescriptor = {
    enumerable: false
  };
  function nonEnum(obj, prop) {
    Object.defineProperty(obj, prop, nonEnumDescriptor);
  }
  function NodeList() {
    this.length = 0;
    nonEnum(this, "length");
  }
  NodeList.prototype = {
    item: function(index) {
      return this[index];
    }
  };
  nonEnum(NodeList.prototype, "item");
  function wrapNodeList(list) {
    if (list == null) return list;
    var wrapperList = new NodeList();
    for (var i = 0, length = list.length; i < length; i++) {
      wrapperList[i] = wrap(list[i]);
    }
    wrapperList.length = length;
    return wrapperList;
  }
  function addWrapNodeListMethod(wrapperConstructor, name) {
    wrapperConstructor.prototype[name] = function() {
      return wrapNodeList(unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
    };
  }
  scope.wrappers.NodeList = NodeList;
  scope.addWrapNodeListMethod = addWrapNodeListMethod;
  scope.wrapNodeList = wrapNodeList;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  scope.wrapHTMLCollection = scope.wrapNodeList;
  scope.wrappers.HTMLCollection = scope.wrappers.NodeList;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var EventTarget = scope.wrappers.EventTarget;
  var NodeList = scope.wrappers.NodeList;
  var TreeScope = scope.TreeScope;
  var assert = scope.assert;
  var defineWrapGetter = scope.defineWrapGetter;
  var enqueueMutation = scope.enqueueMutation;
  var getTreeScope = scope.getTreeScope;
  var isWrapper = scope.isWrapper;
  var mixin = scope.mixin;
  var registerTransientObservers = scope.registerTransientObservers;
  var registerWrapper = scope.registerWrapper;
  var setTreeScope = scope.setTreeScope;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var unwrap = scope.unwrap;
  var unwrapIfNeeded = scope.unwrapIfNeeded;
  var wrap = scope.wrap;
  var wrapIfNeeded = scope.wrapIfNeeded;
  var wrappers = scope.wrappers;
  function assertIsNodeWrapper(node) {
    assert(node instanceof Node);
  }
  function createOneElementNodeList(node) {
    var nodes = new NodeList();
    nodes[0] = node;
    nodes.length = 1;
    return nodes;
  }
  var surpressMutations = false;
  function enqueueRemovalForInsertedNodes(node, parent, nodes) {
    enqueueMutation(parent, "childList", {
      removedNodes: nodes,
      previousSibling: node.previousSibling,
      nextSibling: node.nextSibling
    });
  }
  function enqueueRemovalForInsertedDocumentFragment(df, nodes) {
    enqueueMutation(df, "childList", {
      removedNodes: nodes
    });
  }
  function collectNodes(node, parentNode, previousNode, nextNode) {
    if (node instanceof DocumentFragment) {
      var nodes = collectNodesForDocumentFragment(node);
      surpressMutations = true;
      for (var i = nodes.length - 1; i >= 0; i--) {
        node.removeChild(nodes[i]);
        nodes[i].parentNode_ = parentNode;
      }
      surpressMutations = false;
      for (var i = 0; i < nodes.length; i++) {
        nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
        nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
      }
      if (previousNode) previousNode.nextSibling_ = nodes[0];
      if (nextNode) nextNode.previousSibling_ = nodes[nodes.length - 1];
      return nodes;
    }
    var nodes = createOneElementNodeList(node);
    var oldParent = node.parentNode;
    if (oldParent) {
      oldParent.removeChild(node);
    }
    node.parentNode_ = parentNode;
    node.previousSibling_ = previousNode;
    node.nextSibling_ = nextNode;
    if (previousNode) previousNode.nextSibling_ = node;
    if (nextNode) nextNode.previousSibling_ = node;
    return nodes;
  }
  function collectNodesNative(node) {
    if (node instanceof DocumentFragment) return collectNodesForDocumentFragment(node);
    var nodes = createOneElementNodeList(node);
    var oldParent = node.parentNode;
    if (oldParent) enqueueRemovalForInsertedNodes(node, oldParent, nodes);
    return nodes;
  }
  function collectNodesForDocumentFragment(node) {
    var nodes = new NodeList();
    var i = 0;
    for (var child = node.firstChild; child; child = child.nextSibling) {
      nodes[i++] = child;
    }
    nodes.length = i;
    enqueueRemovalForInsertedDocumentFragment(node, nodes);
    return nodes;
  }
  function snapshotNodeList(nodeList) {
    return nodeList;
  }
  function nodeWasAdded(node, treeScope) {
    setTreeScope(node, treeScope);
    node.nodeIsInserted_();
  }
  function nodesWereAdded(nodes, parent) {
    var treeScope = getTreeScope(parent);
    for (var i = 0; i < nodes.length; i++) {
      nodeWasAdded(nodes[i], treeScope);
    }
  }
  function nodeWasRemoved(node) {
    setTreeScope(node, new TreeScope(node, null));
  }
  function nodesWereRemoved(nodes) {
    for (var i = 0; i < nodes.length; i++) {
      nodeWasRemoved(nodes[i]);
    }
  }
  function ensureSameOwnerDocument(parent, child) {
    var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ? parent : parent.ownerDocument;
    if (ownerDoc !== child.ownerDocument) ownerDoc.adoptNode(child);
  }
  function adoptNodesIfNeeded(owner, nodes) {
    if (!nodes.length) return;
    var ownerDoc = owner.ownerDocument;
    if (ownerDoc === nodes[0].ownerDocument) return;
    for (var i = 0; i < nodes.length; i++) {
      scope.adoptNodeNoRemove(nodes[i], ownerDoc);
    }
  }
  function unwrapNodesForInsertion(owner, nodes) {
    adoptNodesIfNeeded(owner, nodes);
    var length = nodes.length;
    if (length === 1) return unwrap(nodes[0]);
    var df = unwrap(owner.ownerDocument.createDocumentFragment());
    for (var i = 0; i < length; i++) {
      df.appendChild(unwrap(nodes[i]));
    }
    return df;
  }
  function clearChildNodes(wrapper) {
    if (wrapper.firstChild_ !== undefined) {
      var child = wrapper.firstChild_;
      while (child) {
        var tmp = child;
        child = child.nextSibling_;
        tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
      }
    }
    wrapper.firstChild_ = wrapper.lastChild_ = undefined;
  }
  function removeAllChildNodes(wrapper) {
    if (wrapper.invalidateShadowRenderer()) {
      var childWrapper = wrapper.firstChild;
      while (childWrapper) {
        assert(childWrapper.parentNode === wrapper);
        var nextSibling = childWrapper.nextSibling;
        var childNode = unwrap(childWrapper);
        var parentNode = childNode.parentNode;
        if (parentNode) originalRemoveChild.call(parentNode, childNode);
        childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = null;
        childWrapper = nextSibling;
      }
      wrapper.firstChild_ = wrapper.lastChild_ = null;
    } else {
      var node = unwrap(wrapper);
      var child = node.firstChild;
      var nextSibling;
      while (child) {
        nextSibling = child.nextSibling;
        originalRemoveChild.call(node, child);
        child = nextSibling;
      }
    }
  }
  function invalidateParent(node) {
    var p = node.parentNode;
    return p && p.invalidateShadowRenderer();
  }
  function cleanupNodes(nodes) {
    for (var i = 0, n; i < nodes.length; i++) {
      n = nodes[i];
      n.parentNode.removeChild(n);
    }
  }
  var originalImportNode = document.importNode;
  var originalCloneNode = window.Node.prototype.cloneNode;
  function cloneNode(node, deep, opt_doc) {
    var clone;
    if (opt_doc) clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false)); else clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));
    if (deep) {
      for (var child = node.firstChild; child; child = child.nextSibling) {
        clone.appendChild(cloneNode(child, true, opt_doc));
      }
      if (node instanceof wrappers.HTMLTemplateElement) {
        var cloneContent = clone.content;
        for (var child = node.content.firstChild; child; child = child.nextSibling) {
          cloneContent.appendChild(cloneNode(child, true, opt_doc));
        }
      }
    }
    return clone;
  }
  function contains(self, child) {
    if (!child || getTreeScope(self) !== getTreeScope(child)) return false;
    for (var node = child; node; node = node.parentNode) {
      if (node === self) return true;
    }
    return false;
  }
  var OriginalNode = window.Node;
  function Node(original) {
    assert(original instanceof OriginalNode);
    EventTarget.call(this, original);
    this.parentNode_ = undefined;
    this.firstChild_ = undefined;
    this.lastChild_ = undefined;
    this.nextSibling_ = undefined;
    this.previousSibling_ = undefined;
    this.treeScope_ = undefined;
  }
  var OriginalDocumentFragment = window.DocumentFragment;
  var originalAppendChild = OriginalNode.prototype.appendChild;
  var originalCompareDocumentPosition = OriginalNode.prototype.compareDocumentPosition;
  var originalIsEqualNode = OriginalNode.prototype.isEqualNode;
  var originalInsertBefore = OriginalNode.prototype.insertBefore;
  var originalRemoveChild = OriginalNode.prototype.removeChild;
  var originalReplaceChild = OriginalNode.prototype.replaceChild;
  var isIEOrEdge = /Trident|Edge/.test(navigator.userAgent);
  var removeChildOriginalHelper = isIEOrEdge ? function(parent, child) {
    try {
      originalRemoveChild.call(parent, child);
    } catch (ex) {
      if (!(parent instanceof OriginalDocumentFragment)) throw ex;
    }
  } : function(parent, child) {
    originalRemoveChild.call(parent, child);
  };
  Node.prototype = Object.create(EventTarget.prototype);
  mixin(Node.prototype, {
    appendChild: function(childWrapper) {
      return this.insertBefore(childWrapper, null);
    },
    insertBefore: function(childWrapper, refWrapper) {
      assertIsNodeWrapper(childWrapper);
      var refNode;
      if (refWrapper) {
        if (isWrapper(refWrapper)) {
          refNode = unwrap(refWrapper);
        } else {
          refNode = refWrapper;
          refWrapper = wrap(refNode);
        }
      } else {
        refWrapper = null;
        refNode = null;
      }
      refWrapper && assert(refWrapper.parentNode === this);
      var nodes;
      var previousNode = refWrapper ? refWrapper.previousSibling : this.lastChild;
      var useNative = !this.invalidateShadowRenderer() && !invalidateParent(childWrapper);
      if (useNative) nodes = collectNodesNative(childWrapper); else nodes = collectNodes(childWrapper, this, previousNode, refWrapper);
      if (useNative) {
        ensureSameOwnerDocument(this, childWrapper);
        clearChildNodes(this);
        originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);
      } else {
        if (!previousNode) this.firstChild_ = nodes[0];
        if (!refWrapper) {
          this.lastChild_ = nodes[nodes.length - 1];
          if (this.firstChild_ === undefined) this.firstChild_ = this.firstChild;
        }
        var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);
        if (parentNode) {
          originalInsertBefore.call(parentNode, unwrapNodesForInsertion(this, nodes), refNode);
        } else {
          adoptNodesIfNeeded(this, nodes);
        }
      }
      enqueueMutation(this, "childList", {
        addedNodes: nodes,
        nextSibling: refWrapper,
        previousSibling: previousNode
      });
      nodesWereAdded(nodes, this);
      return childWrapper;
    },
    removeChild: function(childWrapper) {
      assertIsNodeWrapper(childWrapper);
      if (childWrapper.parentNode !== this) {
        var found = false;
        var childNodes = this.childNodes;
        for (var ieChild = this.firstChild; ieChild; ieChild = ieChild.nextSibling) {
          if (ieChild === childWrapper) {
            found = true;
            break;
          }
        }
        if (!found) {
          throw new Error("NotFoundError");
        }
      }
      var childNode = unwrap(childWrapper);
      var childWrapperNextSibling = childWrapper.nextSibling;
      var childWrapperPreviousSibling = childWrapper.previousSibling;
      if (this.invalidateShadowRenderer()) {
        var thisFirstChild = this.firstChild;
        var thisLastChild = this.lastChild;
        var parentNode = childNode.parentNode;
        if (parentNode) removeChildOriginalHelper(parentNode, childNode);
        if (thisFirstChild === childWrapper) this.firstChild_ = childWrapperNextSibling;
        if (thisLastChild === childWrapper) this.lastChild_ = childWrapperPreviousSibling;
        if (childWrapperPreviousSibling) childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;
        if (childWrapperNextSibling) {
          childWrapperNextSibling.previousSibling_ = childWrapperPreviousSibling;
        }
        childWrapper.previousSibling_ = childWrapper.nextSibling_ = childWrapper.parentNode_ = undefined;
      } else {
        clearChildNodes(this);
        removeChildOriginalHelper(unsafeUnwrap(this), childNode);
      }
      if (!surpressMutations) {
        enqueueMutation(this, "childList", {
          removedNodes: createOneElementNodeList(childWrapper),
          nextSibling: childWrapperNextSibling,
          previousSibling: childWrapperPreviousSibling
        });
      }
      registerTransientObservers(this, childWrapper);
      return childWrapper;
    },
    replaceChild: function(newChildWrapper, oldChildWrapper) {
      assertIsNodeWrapper(newChildWrapper);
      var oldChildNode;
      if (isWrapper(oldChildWrapper)) {
        oldChildNode = unwrap(oldChildWrapper);
      } else {
        oldChildNode = oldChildWrapper;
        oldChildWrapper = wrap(oldChildNode);
      }
      if (oldChildWrapper.parentNode !== this) {
        throw new Error("NotFoundError");
      }
      var nextNode = oldChildWrapper.nextSibling;
      var previousNode = oldChildWrapper.previousSibling;
      var nodes;
      var useNative = !this.invalidateShadowRenderer() && !invalidateParent(newChildWrapper);
      if (useNative) {
        nodes = collectNodesNative(newChildWrapper);
      } else {
        if (nextNode === newChildWrapper) nextNode = newChildWrapper.nextSibling;
        nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
      }
      if (!useNative) {
        if (this.firstChild === oldChildWrapper) this.firstChild_ = nodes[0];
        if (this.lastChild === oldChildWrapper) this.lastChild_ = nodes[nodes.length - 1];
        oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ = oldChildWrapper.parentNode_ = undefined;
        if (oldChildNode.parentNode) {
          originalReplaceChild.call(oldChildNode.parentNode, unwrapNodesForInsertion(this, nodes), oldChildNode);
        }
      } else {
        ensureSameOwnerDocument(this, newChildWrapper);
        clearChildNodes(this);
        originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper), oldChildNode);
      }
      enqueueMutation(this, "childList", {
        addedNodes: nodes,
        removedNodes: createOneElementNodeList(oldChildWrapper),
        nextSibling: nextNode,
        previousSibling: previousNode
      });
      nodeWasRemoved(oldChildWrapper);
      nodesWereAdded(nodes, this);
      return oldChildWrapper;
    },
    nodeIsInserted_: function() {
      for (var child = this.firstChild; child; child = child.nextSibling) {
        child.nodeIsInserted_();
      }
    },
    hasChildNodes: function() {
      return this.firstChild !== null;
    },
    get parentNode() {
      return this.parentNode_ !== undefined ? this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);
    },
    get firstChild() {
      return this.firstChild_ !== undefined ? this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);
    },
    get lastChild() {
      return this.lastChild_ !== undefined ? this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);
    },
    get nextSibling() {
      return this.nextSibling_ !== undefined ? this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);
    },
    get previousSibling() {
      return this.previousSibling_ !== undefined ? this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);
    },
    get parentElement() {
      var p = this.parentNode;
      while (p && p.nodeType !== Node.ELEMENT_NODE) {
        p = p.parentNode;
      }
      return p;
    },
    get textContent() {
      var s = "";
      for (var child = this.firstChild; child; child = child.nextSibling) {
        if (child.nodeType != Node.COMMENT_NODE) {
          s += child.textContent;
        }
      }
      return s;
    },
    set textContent(textContent) {
      if (textContent == null) textContent = "";
      var removedNodes = snapshotNodeList(this.childNodes);
      if (this.invalidateShadowRenderer()) {
        removeAllChildNodes(this);
        if (textContent !== "") {
          var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);
          this.appendChild(textNode);
        }
      } else {
        clearChildNodes(this);
        unsafeUnwrap(this).textContent = textContent;
      }
      var addedNodes = snapshotNodeList(this.childNodes);
      enqueueMutation(this, "childList", {
        addedNodes: addedNodes,
        removedNodes: removedNodes
      });
      nodesWereRemoved(removedNodes);
      nodesWereAdded(addedNodes, this);
    },
    get childNodes() {
      var wrapperList = new NodeList();
      var i = 0;
      for (var child = this.firstChild; child; child = child.nextSibling) {
        wrapperList[i++] = child;
      }
      wrapperList.length = i;
      return wrapperList;
    },
    cloneNode: function(deep) {
      return cloneNode(this, deep);
    },
    contains: function(child) {
      return contains(this, wrapIfNeeded(child));
    },
    compareDocumentPosition: function(otherNode) {
      return originalCompareDocumentPosition.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
    },
    isEqualNode: function(otherNode) {
      return originalIsEqualNode.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
    },
    normalize: function() {
      var nodes = snapshotNodeList(this.childNodes);
      var remNodes = [];
      var s = "";
      var modNode;
      for (var i = 0, n; i < nodes.length; i++) {
        n = nodes[i];
        if (n.nodeType === Node.TEXT_NODE) {
          if (!modNode && !n.data.length) this.removeChild(n); else if (!modNode) modNode = n; else {
            s += n.data;
            remNodes.push(n);
          }
        } else {
          if (modNode && remNodes.length) {
            modNode.data += s;
            cleanupNodes(remNodes);
          }
          remNodes = [];
          s = "";
          modNode = null;
          if (n.childNodes.length) n.normalize();
        }
      }
      if (modNode && remNodes.length) {
        modNode.data += s;
        cleanupNodes(remNodes);
      }
    }
  });
  defineWrapGetter(Node, "ownerDocument");
  registerWrapper(OriginalNode, Node, document.createDocumentFragment());
  delete Node.prototype.querySelector;
  delete Node.prototype.querySelectorAll;
  Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
  scope.cloneNode = cloneNode;
  scope.nodeWasAdded = nodeWasAdded;
  scope.nodeWasRemoved = nodeWasRemoved;
  scope.nodesWereAdded = nodesWereAdded;
  scope.nodesWereRemoved = nodesWereRemoved;
  scope.originalInsertBefore = originalInsertBefore;
  scope.originalRemoveChild = originalRemoveChild;
  scope.snapshotNodeList = snapshotNodeList;
  scope.wrappers.Node = Node;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLCollection = scope.wrappers.HTMLCollection;
  var NodeList = scope.wrappers.NodeList;
  var getTreeScope = scope.getTreeScope;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var wrap = scope.wrap;
  var originalDocumentQuerySelector = document.querySelector;
  var originalElementQuerySelector = document.documentElement.querySelector;
  var originalDocumentQuerySelectorAll = document.querySelectorAll;
  var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;
  var originalDocumentGetElementsByTagName = document.getElementsByTagName;
  var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;
  var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;
  var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;
  var OriginalElement = window.Element;
  var OriginalDocument = window.HTMLDocument || window.Document;
  function filterNodeList(list, index, result, deep) {
    var wrappedItem = null;
    var root = null;
    for (var i = 0, length = list.length; i < length; i++) {
      wrappedItem = wrap(list[i]);
      if (!deep && (root = getTreeScope(wrappedItem).root)) {
        if (root instanceof scope.wrappers.ShadowRoot) {
          continue;
        }
      }
      result[index++] = wrappedItem;
    }
    return index;
  }
  function shimSelector(selector) {
    return String(selector).replace(/\/deep\/|::shadow|>>>/g, " ");
  }
  function shimMatchesSelector(selector) {
    return String(selector).replace(/:host\(([^\s]+)\)/g, "$1").replace(/([^\s]):host/g, "$1").replace(":host", "*").replace(/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content|>>>/g, " ");
  }
  function findOne(node, selector) {
    var m, el = node.firstElementChild;
    while (el) {
      if (el.matches(selector)) return el;
      m = findOne(el, selector);
      if (m) return m;
      el = el.nextElementSibling;
    }
    return null;
  }
  function matchesSelector(el, selector) {
    return el.matches(selector);
  }
  var XHTML_NS = "http://www.w3.org/1999/xhtml";
  function matchesTagName(el, localName, localNameLowerCase) {
    var ln = el.localName;
    return ln === localName || ln === localNameLowerCase && el.namespaceURI === XHTML_NS;
  }
  function matchesEveryThing() {
    return true;
  }
  function matchesLocalNameOnly(el, ns, localName) {
    return el.localName === localName;
  }
  function matchesNameSpace(el, ns) {
    return el.namespaceURI === ns;
  }
  function matchesLocalNameNS(el, ns, localName) {
    return el.namespaceURI === ns && el.localName === localName;
  }
  function findElements(node, index, result, p, arg0, arg1) {
    var el = node.firstElementChild;
    while (el) {
      if (p(el, arg0, arg1)) result[index++] = el;
      index = findElements(el, index, result, p, arg0, arg1);
      el = el.nextElementSibling;
    }
    return index;
  }
  function querySelectorAllFiltered(p, index, result, selector, deep) {
    var target = unsafeUnwrap(this);
    var list;
    var root = getTreeScope(this).root;
    if (root instanceof scope.wrappers.ShadowRoot) {
      return findElements(this, index, result, p, selector, null);
    } else if (target instanceof OriginalElement) {
      list = originalElementQuerySelectorAll.call(target, selector);
    } else if (target instanceof OriginalDocument) {
      list = originalDocumentQuerySelectorAll.call(target, selector);
    } else {
      return findElements(this, index, result, p, selector, null);
    }
    return filterNodeList(list, index, result, deep);
  }
  var SelectorsInterface = {
    querySelector: function(selector) {
      var shimmed = shimSelector(selector);
      var deep = shimmed !== selector;
      selector = shimmed;
      var target = unsafeUnwrap(this);
      var wrappedItem;
      var root = getTreeScope(this).root;
      if (root instanceof scope.wrappers.ShadowRoot) {
        return findOne(this, selector);
      } else if (target instanceof OriginalElement) {
        wrappedItem = wrap(originalElementQuerySelector.call(target, selector));
      } else if (target instanceof OriginalDocument) {
        wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));
      } else {
        return findOne(this, selector);
      }
      if (!wrappedItem) {
        return wrappedItem;
      } else if (!deep && (root = getTreeScope(wrappedItem).root)) {
        if (root instanceof scope.wrappers.ShadowRoot) {
          return findOne(this, selector);
        }
      }
      return wrappedItem;
    },
    querySelectorAll: function(selector) {
      var shimmed = shimSelector(selector);
      var deep = shimmed !== selector;
      selector = shimmed;
      var result = new NodeList();
      result.length = querySelectorAllFiltered.call(this, matchesSelector, 0, result, selector, deep);
      return result;
    }
  };
  var MatchesInterface = {
    matches: function(selector) {
      selector = shimMatchesSelector(selector);
      return scope.originalMatches.call(unsafeUnwrap(this), selector);
    }
  };
  function getElementsByTagNameFiltered(p, index, result, localName, lowercase) {
    var target = unsafeUnwrap(this);
    var list;
    var root = getTreeScope(this).root;
    if (root instanceof scope.wrappers.ShadowRoot) {
      return findElements(this, index, result, p, localName, lowercase);
    } else if (target instanceof OriginalElement) {
      list = originalElementGetElementsByTagName.call(target, localName, lowercase);
    } else if (target instanceof OriginalDocument) {
      list = originalDocumentGetElementsByTagName.call(target, localName, lowercase);
    } else {
      return findElements(this, index, result, p, localName, lowercase);
    }
    return filterNodeList(list, index, result, false);
  }
  function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {
    var target = unsafeUnwrap(this);
    var list;
    var root = getTreeScope(this).root;
    if (root instanceof scope.wrappers.ShadowRoot) {
      return findElements(this, index, result, p, ns, localName);
    } else if (target instanceof OriginalElement) {
      list = originalElementGetElementsByTagNameNS.call(target, ns, localName);
    } else if (target instanceof OriginalDocument) {
      list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);
    } else {
      return findElements(this, index, result, p, ns, localName);
    }
    return filterNodeList(list, index, result, false);
  }
  var GetElementsByInterface = {
    getElementsByTagName: function(localName) {
      var result = new HTMLCollection();
      var match = localName === "*" ? matchesEveryThing : matchesTagName;
      result.length = getElementsByTagNameFiltered.call(this, match, 0, result, localName, localName.toLowerCase());
      return result;
    },
    getElementsByClassName: function(className) {
      return this.querySelectorAll("." + className);
    },
    getElementsByTagNameNS: function(ns, localName) {
      var result = new HTMLCollection();
      var match = null;
      if (ns === "*") {
        match = localName === "*" ? matchesEveryThing : matchesLocalNameOnly;
      } else {
        match = localName === "*" ? matchesNameSpace : matchesLocalNameNS;
      }
      result.length = getElementsByTagNameNSFiltered.call(this, match, 0, result, ns || null, localName);
      return result;
    }
  };
  scope.GetElementsByInterface = GetElementsByInterface;
  scope.SelectorsInterface = SelectorsInterface;
  scope.MatchesInterface = MatchesInterface;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var NodeList = scope.wrappers.NodeList;
  function forwardElement(node) {
    while (node && node.nodeType !== Node.ELEMENT_NODE) {
      node = node.nextSibling;
    }
    return node;
  }
  function backwardsElement(node) {
    while (node && node.nodeType !== Node.ELEMENT_NODE) {
      node = node.previousSibling;
    }
    return node;
  }
  var ParentNodeInterface = {
    get firstElementChild() {
      return forwardElement(this.firstChild);
    },
    get lastElementChild() {
      return backwardsElement(this.lastChild);
    },
    get childElementCount() {
      var count = 0;
      for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
        count++;
      }
      return count;
    },
    get children() {
      var wrapperList = new NodeList();
      var i = 0;
      for (var child = this.firstElementChild; child; child = child.nextElementSibling) {
        wrapperList[i++] = child;
      }
      wrapperList.length = i;
      return wrapperList;
    },
    remove: function() {
      var p = this.parentNode;
      if (p) p.removeChild(this);
    }
  };
  var ChildNodeInterface = {
    get nextElementSibling() {
      return forwardElement(this.nextSibling);
    },
    get previousElementSibling() {
      return backwardsElement(this.previousSibling);
    }
  };
  var NonElementParentNodeInterface = {
    getElementById: function(id) {
      if (/[ \t\n\r\f]/.test(id)) return null;
      return this.querySelector('[id="' + id + '"]');
    }
  };
  scope.ChildNodeInterface = ChildNodeInterface;
  scope.NonElementParentNodeInterface = NonElementParentNodeInterface;
  scope.ParentNodeInterface = ParentNodeInterface;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var ChildNodeInterface = scope.ChildNodeInterface;
  var Node = scope.wrappers.Node;
  var enqueueMutation = scope.enqueueMutation;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var OriginalCharacterData = window.CharacterData;
  function CharacterData(node) {
    Node.call(this, node);
  }
  CharacterData.prototype = Object.create(Node.prototype);
  mixin(CharacterData.prototype, {
    get nodeValue() {
      return this.data;
    },
    set nodeValue(data) {
      this.data = data;
    },
    get textContent() {
      return this.data;
    },
    set textContent(value) {
      this.data = value;
    },
    get data() {
      return unsafeUnwrap(this).data;
    },
    set data(value) {
      var oldValue = unsafeUnwrap(this).data;
      enqueueMutation(this, "characterData", {
        oldValue: oldValue
      });
      unsafeUnwrap(this).data = value;
    }
  });
  mixin(CharacterData.prototype, ChildNodeInterface);
  registerWrapper(OriginalCharacterData, CharacterData, document.createTextNode(""));
  scope.wrappers.CharacterData = CharacterData;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var CharacterData = scope.wrappers.CharacterData;
  var enqueueMutation = scope.enqueueMutation;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  function toUInt32(x) {
    return x >>> 0;
  }
  var OriginalText = window.Text;
  function Text(node) {
    CharacterData.call(this, node);
  }
  Text.prototype = Object.create(CharacterData.prototype);
  mixin(Text.prototype, {
    splitText: function(offset) {
      offset = toUInt32(offset);
      var s = this.data;
      if (offset > s.length) throw new Error("IndexSizeError");
      var head = s.slice(0, offset);
      var tail = s.slice(offset);
      this.data = head;
      var newTextNode = this.ownerDocument.createTextNode(tail);
      if (this.parentNode) this.parentNode.insertBefore(newTextNode, this.nextSibling);
      return newTextNode;
    }
  });
  registerWrapper(OriginalText, Text, document.createTextNode(""));
  scope.wrappers.Text = Text;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  if (!window.DOMTokenList) {
    console.warn("Missing DOMTokenList prototype, please include a " + "compatible classList polyfill such as http://goo.gl/uTcepH.");
    return;
  }
  var unsafeUnwrap = scope.unsafeUnwrap;
  var enqueueMutation = scope.enqueueMutation;
  function getClass(el) {
    return unsafeUnwrap(el).getAttribute("class");
  }
  function enqueueClassAttributeChange(el, oldValue) {
    enqueueMutation(el, "attributes", {
      name: "class",
      namespace: null,
      oldValue: oldValue
    });
  }
  function invalidateClass(el) {
    scope.invalidateRendererBasedOnAttribute(el, "class");
  }
  function changeClass(tokenList, method, args) {
    var ownerElement = tokenList.ownerElement_;
    if (ownerElement == null) {
      return method.apply(tokenList, args);
    }
    var oldValue = getClass(ownerElement);
    var retv = method.apply(tokenList, args);
    if (getClass(ownerElement) !== oldValue) {
      enqueueClassAttributeChange(ownerElement, oldValue);
      invalidateClass(ownerElement);
    }
    return retv;
  }
  var oldAdd = DOMTokenList.prototype.add;
  DOMTokenList.prototype.add = function() {
    changeClass(this, oldAdd, arguments);
  };
  var oldRemove = DOMTokenList.prototype.remove;
  DOMTokenList.prototype.remove = function() {
    changeClass(this, oldRemove, arguments);
  };
  var oldToggle = DOMTokenList.prototype.toggle;
  DOMTokenList.prototype.toggle = function() {
    return changeClass(this, oldToggle, arguments);
  };
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var ChildNodeInterface = scope.ChildNodeInterface;
  var GetElementsByInterface = scope.GetElementsByInterface;
  var Node = scope.wrappers.Node;
  var ParentNodeInterface = scope.ParentNodeInterface;
  var SelectorsInterface = scope.SelectorsInterface;
  var MatchesInterface = scope.MatchesInterface;
  var addWrapNodeListMethod = scope.addWrapNodeListMethod;
  var enqueueMutation = scope.enqueueMutation;
  var mixin = scope.mixin;
  var oneOf = scope.oneOf;
  var registerWrapper = scope.registerWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var wrappers = scope.wrappers;
  var OriginalElement = window.Element;
  var matchesNames = [ "matches", "mozMatchesSelector", "msMatchesSelector", "webkitMatchesSelector" ].filter(function(name) {
    return OriginalElement.prototype[name];
  });
  var matchesName = matchesNames[0];
  var originalMatches = OriginalElement.prototype[matchesName];
  function invalidateRendererBasedOnAttribute(element, name) {
    var p = element.parentNode;
    if (!p || !p.shadowRoot) return;
    var renderer = scope.getRendererForHost(p);
    if (renderer.dependsOnAttribute(name)) renderer.invalidate();
  }
  function enqueAttributeChange(element, name, oldValue) {
    enqueueMutation(element, "attributes", {
      name: name,
      namespace: null,
      oldValue: oldValue
    });
  }
  var classListTable = new WeakMap();
  function Element(node) {
    Node.call(this, node);
  }
  Element.prototype = Object.create(Node.prototype);
  mixin(Element.prototype, {
    createShadowRoot: function() {
      var newShadowRoot = new wrappers.ShadowRoot(this);
      unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;
      var renderer = scope.getRendererForHost(this);
      renderer.invalidate();
      return newShadowRoot;
    },
    get shadowRoot() {
      return unsafeUnwrap(this).polymerShadowRoot_ || null;
    },
    setAttribute: function(name, value) {
      var oldValue = unsafeUnwrap(this).getAttribute(name);
      unsafeUnwrap(this).setAttribute(name, value);
      enqueAttributeChange(this, name, oldValue);
      invalidateRendererBasedOnAttribute(this, name);
    },
    removeAttribute: function(name) {
      var oldValue = unsafeUnwrap(this).getAttribute(name);
      unsafeUnwrap(this).removeAttribute(name);
      enqueAttributeChange(this, name, oldValue);
      invalidateRendererBasedOnAttribute(this, name);
    },
    get classList() {
      var list = classListTable.get(this);
      if (!list) {
        list = unsafeUnwrap(this).classList;
        if (!list) return;
        list.ownerElement_ = this;
        classListTable.set(this, list);
      }
      return list;
    },
    get className() {
      return unsafeUnwrap(this).className;
    },
    set className(v) {
      this.setAttribute("class", v);
    },
    get id() {
      return unsafeUnwrap(this).id;
    },
    set id(v) {
      this.setAttribute("id", v);
    }
  });
  matchesNames.forEach(function(name) {
    if (name !== "matches") {
      Element.prototype[name] = function(selector) {
        return this.matches(selector);
      };
    }
  });
  if (OriginalElement.prototype.webkitCreateShadowRoot) {
    Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;
  }
  mixin(Element.prototype, ChildNodeInterface);
  mixin(Element.prototype, GetElementsByInterface);
  mixin(Element.prototype, ParentNodeInterface);
  mixin(Element.prototype, SelectorsInterface);
  mixin(Element.prototype, MatchesInterface);
  registerWrapper(OriginalElement, Element, document.createElementNS(null, "x"));
  scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;
  scope.matchesNames = matchesNames;
  scope.originalMatches = originalMatches;
  scope.wrappers.Element = Element;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var Element = scope.wrappers.Element;
  var defineGetter = scope.defineGetter;
  var enqueueMutation = scope.enqueueMutation;
  var mixin = scope.mixin;
  var nodesWereAdded = scope.nodesWereAdded;
  var nodesWereRemoved = scope.nodesWereRemoved;
  var registerWrapper = scope.registerWrapper;
  var snapshotNodeList = scope.snapshotNodeList;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var wrappers = scope.wrappers;
  var escapeAttrRegExp = /[&\u00A0"]/g;
  var escapeDataRegExp = /[&\u00A0<>]/g;
  function escapeReplace(c) {
    switch (c) {
     case "&":
      return "&amp;";

     case "<":
      return "&lt;";

     case ">":
      return "&gt;";

     case '"':
      return "&quot;";

     case " ":
      return "&nbsp;";
    }
  }
  function escapeAttr(s) {
    return s.replace(escapeAttrRegExp, escapeReplace);
  }
  function escapeData(s) {
    return s.replace(escapeDataRegExp, escapeReplace);
  }
  function makeSet(arr) {
    var set = {};
    for (var i = 0; i < arr.length; i++) {
      set[arr[i]] = true;
    }
    return set;
  }
  var voidElements = makeSet([ "area", "base", "br", "col", "command", "embed", "hr", "img", "input", "keygen", "link", "meta", "param", "source", "track", "wbr" ]);
  var plaintextParents = makeSet([ "style", "script", "xmp", "iframe", "noembed", "noframes", "plaintext", "noscript" ]);
  var XHTML_NS = "http://www.w3.org/1999/xhtml";
  function needsSelfClosingSlash(node) {
    if (node.namespaceURI !== XHTML_NS) return true;
    var doctype = node.ownerDocument.doctype;
    return doctype && doctype.publicId && doctype.systemId;
  }
  function getOuterHTML(node, parentNode) {
    switch (node.nodeType) {
     case Node.ELEMENT_NODE:
      var tagName = node.tagName.toLowerCase();
      var s = "<" + tagName;
      var attrs = node.attributes;
      for (var i = 0, attr; attr = attrs[i]; i++) {
        s += " " + attr.name + '="' + escapeAttr(attr.value) + '"';
      }
      if (voidElements[tagName]) {
        if (needsSelfClosingSlash(node)) s += "/";
        return s + ">";
      }
      return s + ">" + getInnerHTML(node) + "</" + tagName + ">";

     case Node.TEXT_NODE:
      var data = node.data;
      if (parentNode && plaintextParents[parentNode.localName]) return data;
      return escapeData(data);

     case Node.COMMENT_NODE:
      return "<!--" + node.data + "-->";

     default:
      console.error(node);
      throw new Error("not implemented");
    }
  }
  function getInnerHTML(node) {
    if (node instanceof wrappers.HTMLTemplateElement) node = node.content;
    var s = "";
    for (var child = node.firstChild; child; child = child.nextSibling) {
      s += getOuterHTML(child, node);
    }
    return s;
  }
  function setInnerHTML(node, value, opt_tagName) {
    var tagName = opt_tagName || "div";
    node.textContent = "";
    var tempElement = unwrap(node.ownerDocument.createElement(tagName));
    tempElement.innerHTML = value;
    var firstChild;
    while (firstChild = tempElement.firstChild) {
      node.appendChild(wrap(firstChild));
    }
  }
  var oldIe = /MSIE/.test(navigator.userAgent);
  var OriginalHTMLElement = window.HTMLElement;
  var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
  function HTMLElement(node) {
    Element.call(this, node);
  }
  HTMLElement.prototype = Object.create(Element.prototype);
  mixin(HTMLElement.prototype, {
    get innerHTML() {
      return getInnerHTML(this);
    },
    set innerHTML(value) {
      if (oldIe && plaintextParents[this.localName]) {
        this.textContent = value;
        return;
      }
      var removedNodes = snapshotNodeList(this.childNodes);
      if (this.invalidateShadowRenderer()) {
        if (this instanceof wrappers.HTMLTemplateElement) setInnerHTML(this.content, value); else setInnerHTML(this, value, this.tagName);
      } else if (!OriginalHTMLTemplateElement && this instanceof wrappers.HTMLTemplateElement) {
        setInnerHTML(this.content, value);
      } else {
        unsafeUnwrap(this).innerHTML = value;
      }
      var addedNodes = snapshotNodeList(this.childNodes);
      enqueueMutation(this, "childList", {
        addedNodes: addedNodes,
        removedNodes: removedNodes
      });
      nodesWereRemoved(removedNodes);
      nodesWereAdded(addedNodes, this);
    },
    get outerHTML() {
      return getOuterHTML(this, this.parentNode);
    },
    set outerHTML(value) {
      var p = this.parentNode;
      if (p) {
        p.invalidateShadowRenderer();
        var df = frag(p, value);
        p.replaceChild(df, this);
      }
    },
    insertAdjacentHTML: function(position, text) {
      var contextElement, refNode;
      switch (String(position).toLowerCase()) {
       case "beforebegin":
        contextElement = this.parentNode;
        refNode = this;
        break;

       case "afterend":
        contextElement = this.parentNode;
        refNode = this.nextSibling;
        break;

       case "afterbegin":
        contextElement = this;
        refNode = this.firstChild;
        break;

       case "beforeend":
        contextElement = this;
        refNode = null;
        break;

       default:
        return;
      }
      var df = frag(contextElement, text);
      contextElement.insertBefore(df, refNode);
    },
    get hidden() {
      return this.hasAttribute("hidden");
    },
    set hidden(v) {
      if (v) {
        this.setAttribute("hidden", "");
      } else {
        this.removeAttribute("hidden");
      }
    }
  });
  function frag(contextElement, html) {
    var p = unwrap(contextElement.cloneNode(false));
    p.innerHTML = html;
    var df = unwrap(document.createDocumentFragment());
    var c;
    while (c = p.firstChild) {
      df.appendChild(c);
    }
    return wrap(df);
  }
  function getter(name) {
    return function() {
      scope.renderAllPending();
      return unsafeUnwrap(this)[name];
    };
  }
  function getterRequiresRendering(name) {
    defineGetter(HTMLElement, name, getter(name));
  }
  [ "clientHeight", "clientLeft", "clientTop", "clientWidth", "offsetHeight", "offsetLeft", "offsetTop", "offsetWidth", "scrollHeight", "scrollWidth" ].forEach(getterRequiresRendering);
  function getterAndSetterRequiresRendering(name) {
    Object.defineProperty(HTMLElement.prototype, name, {
      get: getter(name),
      set: function(v) {
        scope.renderAllPending();
        unsafeUnwrap(this)[name] = v;
      },
      configurable: true,
      enumerable: true
    });
  }
  [ "scrollLeft", "scrollTop" ].forEach(getterAndSetterRequiresRendering);
  function methodRequiresRendering(name) {
    Object.defineProperty(HTMLElement.prototype, name, {
      value: function() {
        scope.renderAllPending();
        return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);
      },
      configurable: true,
      enumerable: true
    });
  }
  [ "focus", "getBoundingClientRect", "getClientRects", "scrollIntoView" ].forEach(methodRequiresRendering);
  registerWrapper(OriginalHTMLElement, HTMLElement, document.createElement("b"));
  scope.wrappers.HTMLElement = HTMLElement;
  scope.getInnerHTML = getInnerHTML;
  scope.setInnerHTML = setInnerHTML;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var wrap = scope.wrap;
  var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
  function HTMLCanvasElement(node) {
    HTMLElement.call(this, node);
  }
  HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);
  mixin(HTMLCanvasElement.prototype, {
    getContext: function() {
      var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);
      return context && wrap(context);
    }
  });
  registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement, document.createElement("canvas"));
  scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var OriginalHTMLContentElement = window.HTMLContentElement;
  function HTMLContentElement(node) {
    HTMLElement.call(this, node);
  }
  HTMLContentElement.prototype = Object.create(HTMLElement.prototype);
  mixin(HTMLContentElement.prototype, {
    constructor: HTMLContentElement,
    get select() {
      return this.getAttribute("select");
    },
    set select(value) {
      this.setAttribute("select", value);
    },
    setAttribute: function(n, v) {
      HTMLElement.prototype.setAttribute.call(this, n, v);
      if (String(n).toLowerCase() === "select") this.invalidateShadowRenderer(true);
    }
  });
  if (OriginalHTMLContentElement) registerWrapper(OriginalHTMLContentElement, HTMLContentElement);
  scope.wrappers.HTMLContentElement = HTMLContentElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var wrapHTMLCollection = scope.wrapHTMLCollection;
  var unwrap = scope.unwrap;
  var OriginalHTMLFormElement = window.HTMLFormElement;
  function HTMLFormElement(node) {
    HTMLElement.call(this, node);
  }
  HTMLFormElement.prototype = Object.create(HTMLElement.prototype);
  mixin(HTMLFormElement.prototype, {
    get elements() {
      return wrapHTMLCollection(unwrap(this).elements);
    }
  });
  registerWrapper(OriginalHTMLFormElement, HTMLFormElement, document.createElement("form"));
  scope.wrappers.HTMLFormElement = HTMLFormElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var registerWrapper = scope.registerWrapper;
  var unwrap = scope.unwrap;
  var rewrap = scope.rewrap;
  var OriginalHTMLImageElement = window.HTMLImageElement;
  function HTMLImageElement(node) {
    HTMLElement.call(this, node);
  }
  HTMLImageElement.prototype = Object.create(HTMLElement.prototype);
  registerWrapper(OriginalHTMLImageElement, HTMLImageElement, document.createElement("img"));
  function Image(width, height) {
    if (!(this instanceof Image)) {
      throw new TypeError("DOM object constructor cannot be called as a function.");
    }
    var node = unwrap(document.createElement("img"));
    HTMLElement.call(this, node);
    rewrap(node, this);
    if (width !== undefined) node.width = width;
    if (height !== undefined) node.height = height;
  }
  Image.prototype = HTMLImageElement.prototype;
  scope.wrappers.HTMLImageElement = HTMLImageElement;
  scope.wrappers.Image = Image;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var mixin = scope.mixin;
  var NodeList = scope.wrappers.NodeList;
  var registerWrapper = scope.registerWrapper;
  var OriginalHTMLShadowElement = window.HTMLShadowElement;
  function HTMLShadowElement(node) {
    HTMLElement.call(this, node);
  }
  HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);
  HTMLShadowElement.prototype.constructor = HTMLShadowElement;
  if (OriginalHTMLShadowElement) registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);
  scope.wrappers.HTMLShadowElement = HTMLShadowElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var contentTable = new WeakMap();
  var templateContentsOwnerTable = new WeakMap();
  function getTemplateContentsOwner(doc) {
    if (!doc.defaultView) return doc;
    var d = templateContentsOwnerTable.get(doc);
    if (!d) {
      d = doc.implementation.createHTMLDocument("");
      while (d.lastChild) {
        d.removeChild(d.lastChild);
      }
      templateContentsOwnerTable.set(doc, d);
    }
    return d;
  }
  function extractContent(templateElement) {
    var doc = getTemplateContentsOwner(templateElement.ownerDocument);
    var df = unwrap(doc.createDocumentFragment());
    var child;
    while (child = templateElement.firstChild) {
      df.appendChild(child);
    }
    return df;
  }
  var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
  function HTMLTemplateElement(node) {
    HTMLElement.call(this, node);
    if (!OriginalHTMLTemplateElement) {
      var content = extractContent(node);
      contentTable.set(this, wrap(content));
    }
  }
  HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
  mixin(HTMLTemplateElement.prototype, {
    constructor: HTMLTemplateElement,
    get content() {
      if (OriginalHTMLTemplateElement) return wrap(unsafeUnwrap(this).content);
      return contentTable.get(this);
    }
  });
  if (OriginalHTMLTemplateElement) registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);
  scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var registerWrapper = scope.registerWrapper;
  var OriginalHTMLMediaElement = window.HTMLMediaElement;
  if (!OriginalHTMLMediaElement) return;
  function HTMLMediaElement(node) {
    HTMLElement.call(this, node);
  }
  HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);
  registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement, document.createElement("audio"));
  scope.wrappers.HTMLMediaElement = HTMLMediaElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLMediaElement = scope.wrappers.HTMLMediaElement;
  var registerWrapper = scope.registerWrapper;
  var unwrap = scope.unwrap;
  var rewrap = scope.rewrap;
  var OriginalHTMLAudioElement = window.HTMLAudioElement;
  if (!OriginalHTMLAudioElement) return;
  function HTMLAudioElement(node) {
    HTMLMediaElement.call(this, node);
  }
  HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);
  registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement, document.createElement("audio"));
  function Audio(src) {
    if (!(this instanceof Audio)) {
      throw new TypeError("DOM object constructor cannot be called as a function.");
    }
    var node = unwrap(document.createElement("audio"));
    HTMLMediaElement.call(this, node);
    rewrap(node, this);
    node.setAttribute("preload", "auto");
    if (src !== undefined) node.setAttribute("src", src);
  }
  Audio.prototype = HTMLAudioElement.prototype;
  scope.wrappers.HTMLAudioElement = HTMLAudioElement;
  scope.wrappers.Audio = Audio;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var rewrap = scope.rewrap;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var OriginalHTMLOptionElement = window.HTMLOptionElement;
  function trimText(s) {
    return s.replace(/\s+/g, " ").trim();
  }
  function HTMLOptionElement(node) {
    HTMLElement.call(this, node);
  }
  HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);
  mixin(HTMLOptionElement.prototype, {
    get text() {
      return trimText(this.textContent);
    },
    set text(value) {
      this.textContent = trimText(String(value));
    },
    get form() {
      return wrap(unwrap(this).form);
    }
  });
  registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement, document.createElement("option"));
  function Option(text, value, defaultSelected, selected) {
    if (!(this instanceof Option)) {
      throw new TypeError("DOM object constructor cannot be called as a function.");
    }
    var node = unwrap(document.createElement("option"));
    HTMLElement.call(this, node);
    rewrap(node, this);
    if (text !== undefined) node.text = text;
    if (value !== undefined) node.setAttribute("value", value);
    if (defaultSelected === true) node.setAttribute("selected", "");
    node.selected = selected === true;
  }
  Option.prototype = HTMLOptionElement.prototype;
  scope.wrappers.HTMLOptionElement = HTMLOptionElement;
  scope.wrappers.Option = Option;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var OriginalHTMLSelectElement = window.HTMLSelectElement;
  function HTMLSelectElement(node) {
    HTMLElement.call(this, node);
  }
  HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);
  mixin(HTMLSelectElement.prototype, {
    add: function(element, before) {
      if (typeof before === "object") before = unwrap(before);
      unwrap(this).add(unwrap(element), before);
    },
    remove: function(indexOrNode) {
      if (indexOrNode === undefined) {
        HTMLElement.prototype.remove.call(this);
        return;
      }
      if (typeof indexOrNode === "object") indexOrNode = unwrap(indexOrNode);
      unwrap(this).remove(indexOrNode);
    },
    get form() {
      return wrap(unwrap(this).form);
    }
  });
  registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement, document.createElement("select"));
  scope.wrappers.HTMLSelectElement = HTMLSelectElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var wrapHTMLCollection = scope.wrapHTMLCollection;
  var OriginalHTMLTableElement = window.HTMLTableElement;
  function HTMLTableElement(node) {
    HTMLElement.call(this, node);
  }
  HTMLTableElement.prototype = Object.create(HTMLElement.prototype);
  mixin(HTMLTableElement.prototype, {
    get caption() {
      return wrap(unwrap(this).caption);
    },
    createCaption: function() {
      return wrap(unwrap(this).createCaption());
    },
    get tHead() {
      return wrap(unwrap(this).tHead);
    },
    createTHead: function() {
      return wrap(unwrap(this).createTHead());
    },
    createTFoot: function() {
      return wrap(unwrap(this).createTFoot());
    },
    get tFoot() {
      return wrap(unwrap(this).tFoot);
    },
    get tBodies() {
      return wrapHTMLCollection(unwrap(this).tBodies);
    },
    createTBody: function() {
      return wrap(unwrap(this).createTBody());
    },
    get rows() {
      return wrapHTMLCollection(unwrap(this).rows);
    },
    insertRow: function(index) {
      return wrap(unwrap(this).insertRow(index));
    }
  });
  registerWrapper(OriginalHTMLTableElement, HTMLTableElement, document.createElement("table"));
  scope.wrappers.HTMLTableElement = HTMLTableElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var wrapHTMLCollection = scope.wrapHTMLCollection;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;
  function HTMLTableSectionElement(node) {
    HTMLElement.call(this, node);
  }
  HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);
  mixin(HTMLTableSectionElement.prototype, {
    constructor: HTMLTableSectionElement,
    get rows() {
      return wrapHTMLCollection(unwrap(this).rows);
    },
    insertRow: function(index) {
      return wrap(unwrap(this).insertRow(index));
    }
  });
  registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement, document.createElement("thead"));
  scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var wrapHTMLCollection = scope.wrapHTMLCollection;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var OriginalHTMLTableRowElement = window.HTMLTableRowElement;
  function HTMLTableRowElement(node) {
    HTMLElement.call(this, node);
  }
  HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);
  mixin(HTMLTableRowElement.prototype, {
    get cells() {
      return wrapHTMLCollection(unwrap(this).cells);
    },
    insertCell: function(index) {
      return wrap(unwrap(this).insertCell(index));
    }
  });
  registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement, document.createElement("tr"));
  scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLContentElement = scope.wrappers.HTMLContentElement;
  var HTMLElement = scope.wrappers.HTMLElement;
  var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
  var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var OriginalHTMLUnknownElement = window.HTMLUnknownElement;
  function HTMLUnknownElement(node) {
    switch (node.localName) {
     case "content":
      return new HTMLContentElement(node);

     case "shadow":
      return new HTMLShadowElement(node);

     case "template":
      return new HTMLTemplateElement(node);
    }
    HTMLElement.call(this, node);
  }
  HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);
  registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);
  scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var Element = scope.wrappers.Element;
  var HTMLElement = scope.wrappers.HTMLElement;
  var registerWrapper = scope.registerWrapper;
  var defineWrapGetter = scope.defineWrapGetter;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var wrap = scope.wrap;
  var mixin = scope.mixin;
  var SVG_NS = "http://www.w3.org/2000/svg";
  var OriginalSVGElement = window.SVGElement;
  var svgTitleElement = document.createElementNS(SVG_NS, "title");
  if (!("classList" in svgTitleElement)) {
    var descr = Object.getOwnPropertyDescriptor(Element.prototype, "classList");
    Object.defineProperty(HTMLElement.prototype, "classList", descr);
    delete Element.prototype.classList;
  }
  function SVGElement(node) {
    Element.call(this, node);
  }
  SVGElement.prototype = Object.create(Element.prototype);
  mixin(SVGElement.prototype, {
    get ownerSVGElement() {
      return wrap(unsafeUnwrap(this).ownerSVGElement);
    }
  });
  registerWrapper(OriginalSVGElement, SVGElement, document.createElementNS(SVG_NS, "title"));
  scope.wrappers.SVGElement = SVGElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var OriginalSVGUseElement = window.SVGUseElement;
  var SVG_NS = "http://www.w3.org/2000/svg";
  var gWrapper = wrap(document.createElementNS(SVG_NS, "g"));
  var useElement = document.createElementNS(SVG_NS, "use");
  var SVGGElement = gWrapper.constructor;
  var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
  var parentInterface = parentInterfacePrototype.constructor;
  function SVGUseElement(impl) {
    parentInterface.call(this, impl);
  }
  SVGUseElement.prototype = Object.create(parentInterfacePrototype);
  if ("instanceRoot" in useElement) {
    mixin(SVGUseElement.prototype, {
      get instanceRoot() {
        return wrap(unwrap(this).instanceRoot);
      },
      get animatedInstanceRoot() {
        return wrap(unwrap(this).animatedInstanceRoot);
      }
    });
  }
  registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
  scope.wrappers.SVGUseElement = SVGUseElement;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var EventTarget = scope.wrappers.EventTarget;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var wrap = scope.wrap;
  var OriginalSVGElementInstance = window.SVGElementInstance;
  if (!OriginalSVGElementInstance) return;
  function SVGElementInstance(impl) {
    EventTarget.call(this, impl);
  }
  SVGElementInstance.prototype = Object.create(EventTarget.prototype);
  mixin(SVGElementInstance.prototype, {
    get correspondingElement() {
      return wrap(unsafeUnwrap(this).correspondingElement);
    },
    get correspondingUseElement() {
      return wrap(unsafeUnwrap(this).correspondingUseElement);
    },
    get parentNode() {
      return wrap(unsafeUnwrap(this).parentNode);
    },
    get childNodes() {
      throw new Error("Not implemented");
    },
    get firstChild() {
      return wrap(unsafeUnwrap(this).firstChild);
    },
    get lastChild() {
      return wrap(unsafeUnwrap(this).lastChild);
    },
    get previousSibling() {
      return wrap(unsafeUnwrap(this).previousSibling);
    },
    get nextSibling() {
      return wrap(unsafeUnwrap(this).nextSibling);
    }
  });
  registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
  scope.wrappers.SVGElementInstance = SVGElementInstance;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var setWrapper = scope.setWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var unwrap = scope.unwrap;
  var unwrapIfNeeded = scope.unwrapIfNeeded;
  var wrap = scope.wrap;
  var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
  function CanvasRenderingContext2D(impl) {
    setWrapper(impl, this);
  }
  mixin(CanvasRenderingContext2D.prototype, {
    get canvas() {
      return wrap(unsafeUnwrap(this).canvas);
    },
    drawImage: function() {
      arguments[0] = unwrapIfNeeded(arguments[0]);
      unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);
    },
    createPattern: function() {
      arguments[0] = unwrap(arguments[0]);
      return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);
    }
  });
  registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D, document.createElement("canvas").getContext("2d"));
  scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var addForwardingProperties = scope.addForwardingProperties;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var setWrapper = scope.setWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var unwrapIfNeeded = scope.unwrapIfNeeded;
  var wrap = scope.wrap;
  var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
  if (!OriginalWebGLRenderingContext) return;
  function WebGLRenderingContext(impl) {
    setWrapper(impl, this);
  }
  mixin(WebGLRenderingContext.prototype, {
    get canvas() {
      return wrap(unsafeUnwrap(this).canvas);
    },
    texImage2D: function() {
      arguments[5] = unwrapIfNeeded(arguments[5]);
      unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);
    },
    texSubImage2D: function() {
      arguments[6] = unwrapIfNeeded(arguments[6]);
      unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);
    }
  });
  var OriginalWebGLRenderingContextBase = Object.getPrototypeOf(OriginalWebGLRenderingContext.prototype);
  if (OriginalWebGLRenderingContextBase !== Object.prototype) {
    addForwardingProperties(OriginalWebGLRenderingContextBase, WebGLRenderingContext.prototype);
  }
  var instanceProperties = /WebKit/.test(navigator.userAgent) ? {
    drawingBufferHeight: null,
    drawingBufferWidth: null
  } : {};
  registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext, instanceProperties);
  scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var Node = scope.wrappers.Node;
  var GetElementsByInterface = scope.GetElementsByInterface;
  var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;
  var ParentNodeInterface = scope.ParentNodeInterface;
  var SelectorsInterface = scope.SelectorsInterface;
  var mixin = scope.mixin;
  var registerObject = scope.registerObject;
  var registerWrapper = scope.registerWrapper;
  var OriginalDocumentFragment = window.DocumentFragment;
  function DocumentFragment(node) {
    Node.call(this, node);
  }
  DocumentFragment.prototype = Object.create(Node.prototype);
  mixin(DocumentFragment.prototype, ParentNodeInterface);
  mixin(DocumentFragment.prototype, SelectorsInterface);
  mixin(DocumentFragment.prototype, GetElementsByInterface);
  mixin(DocumentFragment.prototype, NonElementParentNodeInterface);
  registerWrapper(OriginalDocumentFragment, DocumentFragment, document.createDocumentFragment());
  scope.wrappers.DocumentFragment = DocumentFragment;
  var Comment = registerObject(document.createComment(""));
  scope.wrappers.Comment = Comment;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var DocumentFragment = scope.wrappers.DocumentFragment;
  var TreeScope = scope.TreeScope;
  var elementFromPoint = scope.elementFromPoint;
  var getInnerHTML = scope.getInnerHTML;
  var getTreeScope = scope.getTreeScope;
  var mixin = scope.mixin;
  var rewrap = scope.rewrap;
  var setInnerHTML = scope.setInnerHTML;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var shadowHostTable = new WeakMap();
  var nextOlderShadowTreeTable = new WeakMap();
  function ShadowRoot(hostWrapper) {
    var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());
    DocumentFragment.call(this, node);
    rewrap(node, this);
    var oldShadowRoot = hostWrapper.shadowRoot;
    nextOlderShadowTreeTable.set(this, oldShadowRoot);
    this.treeScope_ = new TreeScope(this, getTreeScope(oldShadowRoot || hostWrapper));
    shadowHostTable.set(this, hostWrapper);
  }
  ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
  mixin(ShadowRoot.prototype, {
    constructor: ShadowRoot,
    get innerHTML() {
      return getInnerHTML(this);
    },
    set innerHTML(value) {
      setInnerHTML(this, value);
      this.invalidateShadowRenderer();
    },
    get olderShadowRoot() {
      return nextOlderShadowTreeTable.get(this) || null;
    },
    get host() {
      return shadowHostTable.get(this) || null;
    },
    invalidateShadowRenderer: function() {
      return shadowHostTable.get(this).invalidateShadowRenderer();
    },
    elementFromPoint: function(x, y) {
      return elementFromPoint(this, this.ownerDocument, x, y);
    },
    getSelection: function() {
      return document.getSelection();
    },
    get activeElement() {
      var unwrappedActiveElement = unwrap(this).ownerDocument.activeElement;
      if (!unwrappedActiveElement || !unwrappedActiveElement.nodeType) return null;
      var activeElement = wrap(unwrappedActiveElement);
      while (!this.contains(activeElement)) {
        while (activeElement.parentNode) {
          activeElement = activeElement.parentNode;
        }
        if (activeElement.host) {
          activeElement = activeElement.host;
        } else {
          return null;
        }
      }
      return activeElement;
    }
  });
  scope.wrappers.ShadowRoot = ShadowRoot;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var registerWrapper = scope.registerWrapper;
  var setWrapper = scope.setWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var unwrap = scope.unwrap;
  var unwrapIfNeeded = scope.unwrapIfNeeded;
  var wrap = scope.wrap;
  var getTreeScope = scope.getTreeScope;
  var OriginalRange = window.Range;
  var ShadowRoot = scope.wrappers.ShadowRoot;
  function getHost(node) {
    var root = getTreeScope(node).root;
    if (root instanceof ShadowRoot) {
      return root.host;
    }
    return null;
  }
  function hostNodeToShadowNode(refNode, offset) {
    if (refNode.shadowRoot) {
      offset = Math.min(refNode.childNodes.length - 1, offset);
      var child = refNode.childNodes[offset];
      if (child) {
        var insertionPoint = scope.getDestinationInsertionPoints(child);
        if (insertionPoint.length > 0) {
          var parentNode = insertionPoint[0].parentNode;
          if (parentNode.nodeType == Node.ELEMENT_NODE) {
            refNode = parentNode;
          }
        }
      }
    }
    return refNode;
  }
  function shadowNodeToHostNode(node) {
    node = wrap(node);
    return getHost(node) || node;
  }
  function Range(impl) {
    setWrapper(impl, this);
  }
  Range.prototype = {
    get startContainer() {
      return shadowNodeToHostNode(unsafeUnwrap(this).startContainer);
    },
    get endContainer() {
      return shadowNodeToHostNode(unsafeUnwrap(this).endContainer);
    },
    get commonAncestorContainer() {
      return shadowNodeToHostNode(unsafeUnwrap(this).commonAncestorContainer);
    },
    setStart: function(refNode, offset) {
      refNode = hostNodeToShadowNode(refNode, offset);
      unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);
    },
    setEnd: function(refNode, offset) {
      refNode = hostNodeToShadowNode(refNode, offset);
      unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);
    },
    setStartBefore: function(refNode) {
      unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));
    },
    setStartAfter: function(refNode) {
      unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));
    },
    setEndBefore: function(refNode) {
      unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));
    },
    setEndAfter: function(refNode) {
      unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));
    },
    selectNode: function(refNode) {
      unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));
    },
    selectNodeContents: function(refNode) {
      unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));
    },
    compareBoundaryPoints: function(how, sourceRange) {
      return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));
    },
    extractContents: function() {
      return wrap(unsafeUnwrap(this).extractContents());
    },
    cloneContents: function() {
      return wrap(unsafeUnwrap(this).cloneContents());
    },
    insertNode: function(node) {
      unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));
    },
    surroundContents: function(newParent) {
      unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));
    },
    cloneRange: function() {
      return wrap(unsafeUnwrap(this).cloneRange());
    },
    isPointInRange: function(node, offset) {
      return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);
    },
    comparePoint: function(node, offset) {
      return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);
    },
    intersectsNode: function(node) {
      return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));
    },
    toString: function() {
      return unsafeUnwrap(this).toString();
    }
  };
  if (OriginalRange.prototype.createContextualFragment) {
    Range.prototype.createContextualFragment = function(html) {
      return wrap(unsafeUnwrap(this).createContextualFragment(html));
    };
  }
  registerWrapper(window.Range, Range, document.createRange());
  scope.wrappers.Range = Range;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var Element = scope.wrappers.Element;
  var HTMLContentElement = scope.wrappers.HTMLContentElement;
  var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
  var Node = scope.wrappers.Node;
  var ShadowRoot = scope.wrappers.ShadowRoot;
  var assert = scope.assert;
  var getTreeScope = scope.getTreeScope;
  var mixin = scope.mixin;
  var oneOf = scope.oneOf;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var ArraySplice = scope.ArraySplice;
  function updateWrapperUpAndSideways(wrapper) {
    wrapper.previousSibling_ = wrapper.previousSibling;
    wrapper.nextSibling_ = wrapper.nextSibling;
    wrapper.parentNode_ = wrapper.parentNode;
  }
  function updateWrapperDown(wrapper) {
    wrapper.firstChild_ = wrapper.firstChild;
    wrapper.lastChild_ = wrapper.lastChild;
  }
  function updateAllChildNodes(parentNodeWrapper) {
    assert(parentNodeWrapper instanceof Node);
    for (var childWrapper = parentNodeWrapper.firstChild; childWrapper; childWrapper = childWrapper.nextSibling) {
      updateWrapperUpAndSideways(childWrapper);
    }
    updateWrapperDown(parentNodeWrapper);
  }
  function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {
    var parentNode = unwrap(parentNodeWrapper);
    var newChild = unwrap(newChildWrapper);
    var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;
    remove(newChildWrapper);
    updateWrapperUpAndSideways(newChildWrapper);
    if (!refChildWrapper) {
      parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;
      if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild) parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;
      var lastChildWrapper = wrap(parentNode.lastChild);
      if (lastChildWrapper) lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;
    } else {
      if (parentNodeWrapper.firstChild === refChildWrapper) parentNodeWrapper.firstChild_ = refChildWrapper;
      refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;
    }
    scope.originalInsertBefore.call(parentNode, newChild, refChild);
  }
  function remove(nodeWrapper) {
    var node = unwrap(nodeWrapper);
    var parentNode = node.parentNode;
    if (!parentNode) return;
    var parentNodeWrapper = wrap(parentNode);
    updateWrapperUpAndSideways(nodeWrapper);
    if (nodeWrapper.previousSibling) nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;
    if (nodeWrapper.nextSibling) nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;
    if (parentNodeWrapper.lastChild === nodeWrapper) parentNodeWrapper.lastChild_ = nodeWrapper;
    if (parentNodeWrapper.firstChild === nodeWrapper) parentNodeWrapper.firstChild_ = nodeWrapper;
    scope.originalRemoveChild.call(parentNode, node);
  }
  var distributedNodesTable = new WeakMap();
  var destinationInsertionPointsTable = new WeakMap();
  var rendererForHostTable = new WeakMap();
  function resetDistributedNodes(insertionPoint) {
    distributedNodesTable.set(insertionPoint, []);
  }
  function getDistributedNodes(insertionPoint) {
    var rv = distributedNodesTable.get(insertionPoint);
    if (!rv) distributedNodesTable.set(insertionPoint, rv = []);
    return rv;
  }
  function getChildNodesSnapshot(node) {
    var result = [], i = 0;
    for (var child = node.firstChild; child; child = child.nextSibling) {
      result[i++] = child;
    }
    return result;
  }
  var request = oneOf(window, [ "requestAnimationFrame", "mozRequestAnimationFrame", "webkitRequestAnimationFrame", "setTimeout" ]);
  var pendingDirtyRenderers = [];
  var renderTimer;
  function renderAllPending() {
    for (var i = 0; i < pendingDirtyRenderers.length; i++) {
      var renderer = pendingDirtyRenderers[i];
      var parentRenderer = renderer.parentRenderer;
      if (parentRenderer && parentRenderer.dirty) continue;
      renderer.render();
    }
    pendingDirtyRenderers = [];
  }
  function handleRequestAnimationFrame() {
    renderTimer = null;
    renderAllPending();
  }
  function getRendererForHost(host) {
    var renderer = rendererForHostTable.get(host);
    if (!renderer) {
      renderer = new ShadowRenderer(host);
      rendererForHostTable.set(host, renderer);
    }
    return renderer;
  }
  function getShadowRootAncestor(node) {
    var root = getTreeScope(node).root;
    if (root instanceof ShadowRoot) return root;
    return null;
  }
  function getRendererForShadowRoot(shadowRoot) {
    return getRendererForHost(shadowRoot.host);
  }
  var spliceDiff = new ArraySplice();
  spliceDiff.equals = function(renderNode, rawNode) {
    return unwrap(renderNode.node) === rawNode;
  };
  function RenderNode(node) {
    this.skip = false;
    this.node = node;
    this.childNodes = [];
  }
  RenderNode.prototype = {
    append: function(node) {
      var rv = new RenderNode(node);
      this.childNodes.push(rv);
      return rv;
    },
    sync: function(opt_added) {
      if (this.skip) return;
      var nodeWrapper = this.node;
      var newChildren = this.childNodes;
      var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));
      var added = opt_added || new WeakMap();
      var splices = spliceDiff.calculateSplices(newChildren, oldChildren);
      var newIndex = 0, oldIndex = 0;
      var lastIndex = 0;
      for (var i = 0; i < splices.length; i++) {
        var splice = splices[i];
        for (;lastIndex < splice.index; lastIndex++) {
          oldIndex++;
          newChildren[newIndex++].sync(added);
        }
        var removedCount = splice.removed.length;
        for (var j = 0; j < removedCount; j++) {
          var wrapper = wrap(oldChildren[oldIndex++]);
          if (!added.get(wrapper)) remove(wrapper);
        }
        var addedCount = splice.addedCount;
        var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);
        for (var j = 0; j < addedCount; j++) {
          var newChildRenderNode = newChildren[newIndex++];
          var newChildWrapper = newChildRenderNode.node;
          insertBefore(nodeWrapper, newChildWrapper, refNode);
          added.set(newChildWrapper, true);
          newChildRenderNode.sync(added);
        }
        lastIndex += addedCount;
      }
      for (var i = lastIndex; i < newChildren.length; i++) {
        newChildren[i].sync(added);
      }
    }
  };
  function ShadowRenderer(host) {
    this.host = host;
    this.dirty = false;
    this.invalidateAttributes();
    this.associateNode(host);
  }
  ShadowRenderer.prototype = {
    render: function(opt_renderNode) {
      if (!this.dirty) return;
      this.invalidateAttributes();
      var host = this.host;
      this.distribution(host);
      var renderNode = opt_renderNode || new RenderNode(host);
      this.buildRenderTree(renderNode, host);
      var topMostRenderer = !opt_renderNode;
      if (topMostRenderer) renderNode.sync();
      this.dirty = false;
    },
    get parentRenderer() {
      return getTreeScope(this.host).renderer;
    },
    invalidate: function() {
      if (!this.dirty) {
        this.dirty = true;
        var parentRenderer = this.parentRenderer;
        if (parentRenderer) parentRenderer.invalidate();
        pendingDirtyRenderers.push(this);
        if (renderTimer) return;
        renderTimer = window[request](handleRequestAnimationFrame, 0);
      }
    },
    distribution: function(root) {
      this.resetAllSubtrees(root);
      this.distributionResolution(root);
    },
    resetAll: function(node) {
      if (isInsertionPoint(node)) resetDistributedNodes(node); else resetDestinationInsertionPoints(node);
      this.resetAllSubtrees(node);
    },
    resetAllSubtrees: function(node) {
      for (var child = node.firstChild; child; child = child.nextSibling) {
        this.resetAll(child);
      }
      if (node.shadowRoot) this.resetAll(node.shadowRoot);
      if (node.olderShadowRoot) this.resetAll(node.olderShadowRoot);
    },
    distributionResolution: function(node) {
      if (isShadowHost(node)) {
        var shadowHost = node;
        var pool = poolPopulation(shadowHost);
        var shadowTrees = getShadowTrees(shadowHost);
        for (var i = 0; i < shadowTrees.length; i++) {
          this.poolDistribution(shadowTrees[i], pool);
        }
        for (var i = shadowTrees.length - 1; i >= 0; i--) {
          var shadowTree = shadowTrees[i];
          var shadow = getShadowInsertionPoint(shadowTree);
          if (shadow) {
            var olderShadowRoot = shadowTree.olderShadowRoot;
            if (olderShadowRoot) {
              pool = poolPopulation(olderShadowRoot);
            }
            for (var j = 0; j < pool.length; j++) {
              destributeNodeInto(pool[j], shadow);
            }
          }
          this.distributionResolution(shadowTree);
        }
      }
      for (var child = node.firstChild; child; child = child.nextSibling) {
        this.distributionResolution(child);
      }
    },
    poolDistribution: function(node, pool) {
      if (node instanceof HTMLShadowElement) return;
      if (node instanceof HTMLContentElement) {
        var content = node;
        this.updateDependentAttributes(content.getAttribute("select"));
        var anyDistributed = false;
        for (var i = 0; i < pool.length; i++) {
          var node = pool[i];
          if (!node) continue;
          if (matches(node, content)) {
            destributeNodeInto(node, content);
            pool[i] = undefined;
            anyDistributed = true;
          }
        }
        if (!anyDistributed) {
          for (var child = content.firstChild; child; child = child.nextSibling) {
            destributeNodeInto(child, content);
          }
        }
        return;
      }
      for (var child = node.firstChild; child; child = child.nextSibling) {
        this.poolDistribution(child, pool);
      }
    },
    buildRenderTree: function(renderNode, node) {
      var children = this.compose(node);
      for (var i = 0; i < children.length; i++) {
        var child = children[i];
        var childRenderNode = renderNode.append(child);
        this.buildRenderTree(childRenderNode, child);
      }
      if (isShadowHost(node)) {
        var renderer = getRendererForHost(node);
        renderer.dirty = false;
      }
    },
    compose: function(node) {
      var children = [];
      var p = node.shadowRoot || node;
      for (var child = p.firstChild; child; child = child.nextSibling) {
        if (isInsertionPoint(child)) {
          this.associateNode(p);
          var distributedNodes = getDistributedNodes(child);
          for (var j = 0; j < distributedNodes.length; j++) {
            var distributedNode = distributedNodes[j];
            if (isFinalDestination(child, distributedNode)) children.push(distributedNode);
          }
        } else {
          children.push(child);
        }
      }
      return children;
    },
    invalidateAttributes: function() {
      this.attributes = Object.create(null);
    },
    updateDependentAttributes: function(selector) {
      if (!selector) return;
      var attributes = this.attributes;
      if (/\.\w+/.test(selector)) attributes["class"] = true;
      if (/#\w+/.test(selector)) attributes["id"] = true;
      selector.replace(/\[\s*([^\s=\|~\]]+)/g, function(_, name) {
        attributes[name] = true;
      });
    },
    dependsOnAttribute: function(name) {
      return this.attributes[name];
    },
    associateNode: function(node) {
      unsafeUnwrap(node).polymerShadowRenderer_ = this;
    }
  };
  function poolPopulation(node) {
    var pool = [];
    for (var child = node.firstChild; child; child = child.nextSibling) {
      if (isInsertionPoint(child)) {
        pool.push.apply(pool, getDistributedNodes(child));
      } else {
        pool.push(child);
      }
    }
    return pool;
  }
  function getShadowInsertionPoint(node) {
    if (node instanceof HTMLShadowElement) return node;
    if (node instanceof HTMLContentElement) return null;
    for (var child = node.firstChild; child; child = child.nextSibling) {
      var res = getShadowInsertionPoint(child);
      if (res) return res;
    }
    return null;
  }
  function destributeNodeInto(child, insertionPoint) {
    getDistributedNodes(insertionPoint).push(child);
    var points = destinationInsertionPointsTable.get(child);
    if (!points) destinationInsertionPointsTable.set(child, [ insertionPoint ]); else points.push(insertionPoint);
  }
  function getDestinationInsertionPoints(node) {
    return destinationInsertionPointsTable.get(node);
  }
  function resetDestinationInsertionPoints(node) {
    destinationInsertionPointsTable.set(node, undefined);
  }
  var selectorStartCharRe = /^(:not\()?[*.#[a-zA-Z_|]/;
  function matches(node, contentElement) {
    var select = contentElement.getAttribute("select");
    if (!select) return true;
    select = select.trim();
    if (!select) return true;
    if (!(node instanceof Element)) return false;
    if (!selectorStartCharRe.test(select)) return false;
    try {
      return node.matches(select);
    } catch (ex) {
      return false;
    }
  }
  function isFinalDestination(insertionPoint, node) {
    var points = getDestinationInsertionPoints(node);
    return points && points[points.length - 1] === insertionPoint;
  }
  function isInsertionPoint(node) {
    return node instanceof HTMLContentElement || node instanceof HTMLShadowElement;
  }
  function isShadowHost(shadowHost) {
    return shadowHost.shadowRoot;
  }
  function getShadowTrees(host) {
    var trees = [];
    for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {
      trees.push(tree);
    }
    return trees;
  }
  function render(host) {
    new ShadowRenderer(host).render();
  }
  Node.prototype.invalidateShadowRenderer = function(force) {
    var renderer = unsafeUnwrap(this).polymerShadowRenderer_;
    if (renderer) {
      renderer.invalidate();
      return true;
    }
    return false;
  };
  HTMLContentElement.prototype.getDistributedNodes = HTMLShadowElement.prototype.getDistributedNodes = function() {
    renderAllPending();
    return getDistributedNodes(this);
  };
  Element.prototype.getDestinationInsertionPoints = function() {
    renderAllPending();
    return getDestinationInsertionPoints(this) || [];
  };
  HTMLContentElement.prototype.nodeIsInserted_ = HTMLShadowElement.prototype.nodeIsInserted_ = function() {
    this.invalidateShadowRenderer();
    var shadowRoot = getShadowRootAncestor(this);
    var renderer;
    if (shadowRoot) renderer = getRendererForShadowRoot(shadowRoot);
    unsafeUnwrap(this).polymerShadowRenderer_ = renderer;
    if (renderer) renderer.invalidate();
  };
  scope.getRendererForHost = getRendererForHost;
  scope.getShadowTrees = getShadowTrees;
  scope.renderAllPending = renderAllPending;
  scope.getDestinationInsertionPoints = getDestinationInsertionPoints;
  scope.visual = {
    insertBefore: insertBefore,
    remove: remove
  };
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var HTMLElement = scope.wrappers.HTMLElement;
  var assert = scope.assert;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var elementsWithFormProperty = [ "HTMLButtonElement", "HTMLFieldSetElement", "HTMLInputElement", "HTMLKeygenElement", "HTMLLabelElement", "HTMLLegendElement", "HTMLObjectElement", "HTMLOutputElement", "HTMLTextAreaElement" ];
  function createWrapperConstructor(name) {
    if (!window[name]) return;
    assert(!scope.wrappers[name]);
    var GeneratedWrapper = function(node) {
      HTMLElement.call(this, node);
    };
    GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);
    mixin(GeneratedWrapper.prototype, {
      get form() {
        return wrap(unwrap(this).form);
      }
    });
    registerWrapper(window[name], GeneratedWrapper, document.createElement(name.slice(4, -7)));
    scope.wrappers[name] = GeneratedWrapper;
  }
  elementsWithFormProperty.forEach(createWrapperConstructor);
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var registerWrapper = scope.registerWrapper;
  var setWrapper = scope.setWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var unwrap = scope.unwrap;
  var unwrapIfNeeded = scope.unwrapIfNeeded;
  var wrap = scope.wrap;
  var OriginalSelection = window.Selection;
  function Selection(impl) {
    setWrapper(impl, this);
  }
  Selection.prototype = {
    get anchorNode() {
      return wrap(unsafeUnwrap(this).anchorNode);
    },
    get focusNode() {
      return wrap(unsafeUnwrap(this).focusNode);
    },
    addRange: function(range) {
      unsafeUnwrap(this).addRange(unwrapIfNeeded(range));
    },
    collapse: function(node, index) {
      unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);
    },
    containsNode: function(node, allowPartial) {
      return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);
    },
    getRangeAt: function(index) {
      return wrap(unsafeUnwrap(this).getRangeAt(index));
    },
    removeRange: function(range) {
      unsafeUnwrap(this).removeRange(unwrap(range));
    },
    selectAllChildren: function(node) {
      unsafeUnwrap(this).selectAllChildren(node instanceof ShadowRoot ? unsafeUnwrap(node.host) : unwrapIfNeeded(node));
    },
    toString: function() {
      return unsafeUnwrap(this).toString();
    }
  };
  if (OriginalSelection.prototype.extend) {
    Selection.prototype.extend = function(node, offset) {
      unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);
    };
  }
  registerWrapper(window.Selection, Selection, window.getSelection());
  scope.wrappers.Selection = Selection;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var registerWrapper = scope.registerWrapper;
  var setWrapper = scope.setWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var unwrapIfNeeded = scope.unwrapIfNeeded;
  var wrap = scope.wrap;
  var OriginalTreeWalker = window.TreeWalker;
  function TreeWalker(impl) {
    setWrapper(impl, this);
  }
  TreeWalker.prototype = {
    get root() {
      return wrap(unsafeUnwrap(this).root);
    },
    get currentNode() {
      return wrap(unsafeUnwrap(this).currentNode);
    },
    set currentNode(node) {
      unsafeUnwrap(this).currentNode = unwrapIfNeeded(node);
    },
    get filter() {
      return unsafeUnwrap(this).filter;
    },
    parentNode: function() {
      return wrap(unsafeUnwrap(this).parentNode());
    },
    firstChild: function() {
      return wrap(unsafeUnwrap(this).firstChild());
    },
    lastChild: function() {
      return wrap(unsafeUnwrap(this).lastChild());
    },
    previousSibling: function() {
      return wrap(unsafeUnwrap(this).previousSibling());
    },
    previousNode: function() {
      return wrap(unsafeUnwrap(this).previousNode());
    },
    nextNode: function() {
      return wrap(unsafeUnwrap(this).nextNode());
    }
  };
  registerWrapper(OriginalTreeWalker, TreeWalker);
  scope.wrappers.TreeWalker = TreeWalker;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var GetElementsByInterface = scope.GetElementsByInterface;
  var Node = scope.wrappers.Node;
  var ParentNodeInterface = scope.ParentNodeInterface;
  var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;
  var Selection = scope.wrappers.Selection;
  var SelectorsInterface = scope.SelectorsInterface;
  var ShadowRoot = scope.wrappers.ShadowRoot;
  var TreeScope = scope.TreeScope;
  var cloneNode = scope.cloneNode;
  var defineGetter = scope.defineGetter;
  var defineWrapGetter = scope.defineWrapGetter;
  var elementFromPoint = scope.elementFromPoint;
  var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
  var matchesNames = scope.matchesNames;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var renderAllPending = scope.renderAllPending;
  var rewrap = scope.rewrap;
  var setWrapper = scope.setWrapper;
  var unsafeUnwrap = scope.unsafeUnwrap;
  var unwrap = scope.unwrap;
  var wrap = scope.wrap;
  var wrapEventTargetMethods = scope.wrapEventTargetMethods;
  var wrapNodeList = scope.wrapNodeList;
  var implementationTable = new WeakMap();
  function Document(node) {
    Node.call(this, node);
    this.treeScope_ = new TreeScope(this, null);
  }
  Document.prototype = Object.create(Node.prototype);
  defineWrapGetter(Document, "documentElement");
  defineWrapGetter(Document, "body");
  defineWrapGetter(Document, "head");
  defineGetter(Document, "activeElement", function() {
    var unwrappedActiveElement = unwrap(this).activeElement;
    if (!unwrappedActiveElement || !unwrappedActiveElement.nodeType) return null;
    var activeElement = wrap(unwrappedActiveElement);
    while (!this.contains(activeElement)) {
      while (activeElement.parentNode) {
        activeElement = activeElement.parentNode;
      }
      if (activeElement.host) {
        activeElement = activeElement.host;
      } else {
        return null;
      }
    }
    return activeElement;
  });
  function wrapMethod(name) {
    var original = document[name];
    Document.prototype[name] = function() {
      return wrap(original.apply(unsafeUnwrap(this), arguments));
    };
  }
  [ "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode" ].forEach(wrapMethod);
  var originalAdoptNode = document.adoptNode;
  function adoptNodeNoRemove(node, doc) {
    originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));
    adoptSubtree(node, doc);
  }
  function adoptSubtree(node, doc) {
    if (node.shadowRoot) doc.adoptNode(node.shadowRoot);
    if (node instanceof ShadowRoot) adoptOlderShadowRoots(node, doc);
    for (var child = node.firstChild; child; child = child.nextSibling) {
      adoptSubtree(child, doc);
    }
  }
  function adoptOlderShadowRoots(shadowRoot, doc) {
    var oldShadowRoot = shadowRoot.olderShadowRoot;
    if (oldShadowRoot) doc.adoptNode(oldShadowRoot);
  }
  var originalGetSelection = document.getSelection;
  mixin(Document.prototype, {
    adoptNode: function(node) {
      if (node.parentNode) node.parentNode.removeChild(node);
      adoptNodeNoRemove(node, this);
      return node;
    },
    elementFromPoint: function(x, y) {
      return elementFromPoint(this, this, x, y);
    },
    importNode: function(node, deep) {
      return cloneNode(node, deep, unsafeUnwrap(this));
    },
    getSelection: function() {
      renderAllPending();
      return new Selection(originalGetSelection.call(unwrap(this)));
    },
    getElementsByName: function(name) {
      return SelectorsInterface.querySelectorAll.call(this, "[name=" + JSON.stringify(String(name)) + "]");
    }
  });
  var originalCreateTreeWalker = document.createTreeWalker;
  var TreeWalkerWrapper = scope.wrappers.TreeWalker;
  Document.prototype.createTreeWalker = function(root, whatToShow, filter, expandEntityReferences) {
    var newFilter = null;
    if (filter) {
      if (filter.acceptNode && typeof filter.acceptNode === "function") {
        newFilter = {
          acceptNode: function(node) {
            return filter.acceptNode(wrap(node));
          }
        };
      } else if (typeof filter === "function") {
        newFilter = function(node) {
          return filter(wrap(node));
        };
      }
    }
    return new TreeWalkerWrapper(originalCreateTreeWalker.call(unwrap(this), unwrap(root), whatToShow, newFilter, expandEntityReferences));
  };
  if (document.registerElement) {
    var originalRegisterElement = document.registerElement;
    Document.prototype.registerElement = function(tagName, object) {
      var prototype, extendsOption;
      if (object !== undefined) {
        prototype = object.prototype;
        extendsOption = object.extends;
      }
      if (!prototype) prototype = Object.create(HTMLElement.prototype);
      if (scope.nativePrototypeTable.get(prototype)) {
        throw new Error("NotSupportedError");
      }
      var proto = Object.getPrototypeOf(prototype);
      var nativePrototype;
      var prototypes = [];
      while (proto) {
        nativePrototype = scope.nativePrototypeTable.get(proto);
        if (nativePrototype) break;
        prototypes.push(proto);
        proto = Object.getPrototypeOf(proto);
      }
      if (!nativePrototype) {
        throw new Error("NotSupportedError");
      }
      var newPrototype = Object.create(nativePrototype);
      for (var i = prototypes.length - 1; i >= 0; i--) {
        newPrototype = Object.create(newPrototype);
      }
      [ "createdCallback", "attachedCallback", "detachedCallback", "attributeChangedCallback" ].forEach(function(name) {
        var f = prototype[name];
        if (!f) return;
        newPrototype[name] = function() {
          if (!(wrap(this) instanceof CustomElementConstructor)) {
            rewrap(this);
          }
          f.apply(wrap(this), arguments);
        };
      });
      var p = {
        prototype: newPrototype
      };
      if (extendsOption) p.extends = extendsOption;
      function CustomElementConstructor(node) {
        if (!node) {
          if (extendsOption) {
            return document.createElement(extendsOption, tagName);
          } else {
            return document.createElement(tagName);
          }
        }
        setWrapper(node, this);
      }
      CustomElementConstructor.prototype = prototype;
      CustomElementConstructor.prototype.constructor = CustomElementConstructor;
      scope.constructorTable.set(newPrototype, CustomElementConstructor);
      scope.nativePrototypeTable.set(prototype, newPrototype);
      var nativeConstructor = originalRegisterElement.call(unwrap(this), tagName, p);
      return CustomElementConstructor;
    };
    forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "registerElement" ]);
  }
  forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement, window.HTMLHtmlElement ], [ "appendChild", "compareDocumentPosition", "contains", "getElementsByClassName", "getElementsByTagName", "getElementsByTagNameNS", "insertBefore", "querySelector", "querySelectorAll", "removeChild", "replaceChild" ]);
  forwardMethodsToWrapper([ window.HTMLBodyElement, window.HTMLHeadElement, window.HTMLHtmlElement ], matchesNames);
  forwardMethodsToWrapper([ window.HTMLDocument || window.Document ], [ "adoptNode", "importNode", "contains", "createComment", "createDocumentFragment", "createElement", "createElementNS", "createEvent", "createEventNS", "createRange", "createTextNode", "createTreeWalker", "elementFromPoint", "getElementById", "getElementsByName", "getSelection" ]);
  mixin(Document.prototype, GetElementsByInterface);
  mixin(Document.prototype, ParentNodeInterface);
  mixin(Document.prototype, SelectorsInterface);
  mixin(Document.prototype, NonElementParentNodeInterface);
  mixin(Document.prototype, {
    get implementation() {
      var implementation = implementationTable.get(this);
      if (implementation) return implementation;
      implementation = new DOMImplementation(unwrap(this).implementation);
      implementationTable.set(this, implementation);
      return implementation;
    },
    get defaultView() {
      return wrap(unwrap(this).defaultView);
    }
  });
  registerWrapper(window.Document, Document, document.implementation.createHTMLDocument(""));
  if (window.HTMLDocument) registerWrapper(window.HTMLDocument, Document);
  wrapEventTargetMethods([ window.HTMLBodyElement, window.HTMLDocument || window.Document, window.HTMLHeadElement ]);
  function DOMImplementation(impl) {
    setWrapper(impl, this);
  }
  var originalCreateDocument = document.implementation.createDocument;
  DOMImplementation.prototype.createDocument = function() {
    arguments[2] = unwrap(arguments[2]);
    return wrap(originalCreateDocument.apply(unsafeUnwrap(this), arguments));
  };
  function wrapImplMethod(constructor, name) {
    var original = document.implementation[name];
    constructor.prototype[name] = function() {
      return wrap(original.apply(unsafeUnwrap(this), arguments));
    };
  }
  function forwardImplMethod(constructor, name) {
    var original = document.implementation[name];
    constructor.prototype[name] = function() {
      return original.apply(unsafeUnwrap(this), arguments);
    };
  }
  wrapImplMethod(DOMImplementation, "createDocumentType");
  wrapImplMethod(DOMImplementation, "createHTMLDocument");
  forwardImplMethod(DOMImplementation, "hasFeature");
  registerWrapper(window.DOMImplementation, DOMImplementation);
  forwardMethodsToWrapper([ window.DOMImplementation ], [ "createDocument", "createDocumentType", "createHTMLDocument", "hasFeature" ]);
  scope.adoptNodeNoRemove = adoptNodeNoRemove;
  scope.wrappers.DOMImplementation = DOMImplementation;
  scope.wrappers.Document = Document;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var EventTarget = scope.wrappers.EventTarget;
  var Selection = scope.wrappers.Selection;
  var mixin = scope.mixin;
  var registerWrapper = scope.registerWrapper;
  var renderAllPending = scope.renderAllPending;
  var unwrap = scope.unwrap;
  var unwrapIfNeeded = scope.unwrapIfNeeded;
  var wrap = scope.wrap;
  var OriginalWindow = window.Window;
  var originalGetComputedStyle = window.getComputedStyle;
  var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;
  var originalGetSelection = window.getSelection;
  function Window(impl) {
    EventTarget.call(this, impl);
  }
  Window.prototype = Object.create(EventTarget.prototype);
  OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
    return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
  };
  if (originalGetDefaultComputedStyle) {
    OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {
      return wrap(this || window).getDefaultComputedStyle(unwrapIfNeeded(el), pseudo);
    };
  }
  OriginalWindow.prototype.getSelection = function() {
    return wrap(this || window).getSelection();
  };
  delete window.getComputedStyle;
  delete window.getDefaultComputedStyle;
  delete window.getSelection;
  [ "addEventListener", "removeEventListener", "dispatchEvent" ].forEach(function(name) {
    OriginalWindow.prototype[name] = function() {
      var w = wrap(this || window);
      return w[name].apply(w, arguments);
    };
    delete window[name];
  });
  mixin(Window.prototype, {
    getComputedStyle: function(el, pseudo) {
      renderAllPending();
      return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
    },
    getSelection: function() {
      renderAllPending();
      return new Selection(originalGetSelection.call(unwrap(this)));
    },
    get document() {
      return wrap(unwrap(this).document);
    }
  });
  if (originalGetDefaultComputedStyle) {
    Window.prototype.getDefaultComputedStyle = function(el, pseudo) {
      renderAllPending();
      return originalGetDefaultComputedStyle.call(unwrap(this), unwrapIfNeeded(el), pseudo);
    };
  }
  registerWrapper(OriginalWindow, Window, window);
  scope.wrappers.Window = Window;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var unwrap = scope.unwrap;
  var OriginalDataTransfer = window.DataTransfer || window.Clipboard;
  var OriginalDataTransferSetDragImage = OriginalDataTransfer.prototype.setDragImage;
  if (OriginalDataTransferSetDragImage) {
    OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {
      OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);
    };
  }
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var registerWrapper = scope.registerWrapper;
  var setWrapper = scope.setWrapper;
  var unwrap = scope.unwrap;
  var OriginalFormData = window.FormData;
  if (!OriginalFormData) return;
  function FormData(formElement) {
    var impl;
    if (formElement instanceof OriginalFormData) {
      impl = formElement;
    } else {
      impl = new OriginalFormData(formElement && unwrap(formElement));
    }
    setWrapper(impl, this);
  }
  registerWrapper(OriginalFormData, FormData, new OriginalFormData());
  scope.wrappers.FormData = FormData;
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var unwrapIfNeeded = scope.unwrapIfNeeded;
  var originalSend = XMLHttpRequest.prototype.send;
  XMLHttpRequest.prototype.send = function(obj) {
    return originalSend.call(this, unwrapIfNeeded(obj));
  };
})(window.ShadowDOMPolyfill);

(function(scope) {
  "use strict";
  var isWrapperFor = scope.isWrapperFor;
  var elements = {
    a: "HTMLAnchorElement",
    area: "HTMLAreaElement",
    audio: "HTMLAudioElement",
    base: "HTMLBaseElement",
    body: "HTMLBodyElement",
    br: "HTMLBRElement",
    button: "HTMLButtonElement",
    canvas: "HTMLCanvasElement",
    caption: "HTMLTableCaptionElement",
    col: "HTMLTableColElement",
    content: "HTMLContentElement",
    data: "HTMLDataElement",
    datalist: "HTMLDataListElement",
    del: "HTMLModElement",
    dir: "HTMLDirectoryElement",
    div: "HTMLDivElement",
    dl: "HTMLDListElement",
    embed: "HTMLEmbedElement",
    fieldset: "HTMLFieldSetElement",
    font: "HTMLFontElement",
    form: "HTMLFormElement",
    frame: "HTMLFrameElement",
    frameset: "HTMLFrameSetElement",
    h1: "HTMLHeadingElement",
    head: "HTMLHeadElement",
    hr: "HTMLHRElement",
    html: "HTMLHtmlElement",
    iframe: "HTMLIFrameElement",
    img: "HTMLImageElement",
    input: "HTMLInputElement",
    keygen: "HTMLKeygenElement",
    label: "HTMLLabelElement",
    legend: "HTMLLegendElement",
    li: "HTMLLIElement",
    link: "HTMLLinkElement",
    map: "HTMLMapElement",
    marquee: "HTMLMarqueeElement",
    menu: "HTMLMenuElement",
    menuitem: "HTMLMenuItemElement",
    meta: "HTMLMetaElement",
    meter: "HTMLMeterElement",
    object: "HTMLObjectElement",
    ol: "HTMLOListElement",
    optgroup: "HTMLOptGroupElement",
    option: "HTMLOptionElement",
    output: "HTMLOutputElement",
    p: "HTMLParagraphElement",
    param: "HTMLParamElement",
    pre: "HTMLPreElement",
    progress: "HTMLProgressElement",
    q: "HTMLQuoteElement",
    script: "HTMLScriptElement",
    select: "HTMLSelectElement",
    shadow: "HTMLShadowElement",
    source: "HTMLSourceElement",
    span: "HTMLSpanElement",
    style: "HTMLStyleElement",
    table: "HTMLTableElement",
    tbody: "HTMLTableSectionElement",
    template: "HTMLTemplateElement",
    textarea: "HTMLTextAreaElement",
    thead: "HTMLTableSectionElement",
    time: "HTMLTimeElement",
    title: "HTMLTitleElement",
    tr: "HTMLTableRowElement",
    track: "HTMLTrackElement",
    ul: "HTMLUListElement",
    video: "HTMLVideoElement"
  };
  function overrideConstructor(tagName) {
    var nativeConstructorName = elements[tagName];
    var nativeConstructor = window[nativeConstructorName];
    if (!nativeConstructor) return;
    var element = document.createElement(tagName);
    var wrapperConstructor = element.constructor;
    window[nativeConstructorName] = wrapperConstructor;
  }
  Object.keys(elements).forEach(overrideConstructor);
  Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {
    window[name] = scope.wrappers[name];
  });
})(window.ShadowDOMPolyfill);