text: (function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = global || self, factory(global.au = {}));
  }(this, function (exports) { 'use strict';
  
    function AggregateError(message, innerError, skipIfAlreadyAggregate) {
      if (innerError) {
        if (innerError.innerError && skipIfAlreadyAggregate) {
          return innerError;
        }
  
        const separator = '\n------------------------------------------------\n';
  
        message += `${separator}Inner Error:\n`;
  
        if (typeof innerError === 'string') {
          message += `Message: ${innerError}`;
        } else {
          if (innerError.message) {
            message += `Message: ${innerError.message}`;
          } else {
            message += `Unknown Inner Error Type. Displaying Inner Error as JSON:\n ${JSON.stringify(innerError, null, '  ')}`;
          }
  
          if (innerError.stack) {
            message += `\nInner Error Stack:\n${innerError.stack}`;
            message += '\nEnd Inner Error Stack';
          }
        }
  
        message += separator;
      }
  
      let e = new Error(message);
      if (innerError) {
        e.innerError = innerError;
      }
  
      return e;
    }
  
    const FEATURE = {};
  
    const PLATFORM = {
      noop() {},
      eachModule() {},
      moduleName(moduleName) {
        return moduleName;
      }
    };
  
    PLATFORM.global = function () {
      if (typeof self !== 'undefined') {
        return self;
      }
  
      if (typeof global !== 'undefined') {
        return global;
      }
  
      return new Function('return this')();
    }();
  
    const DOM = {};
    exports.isInitialized = false;
  
    function initializePAL(callback) {
      if (exports.isInitialized) {
        return;
      }
      exports.isInitialized = true;
      if (typeof Object.getPropertyDescriptor !== 'function') {
        Object.getPropertyDescriptor = function (subject, name) {
          let pd = Object.getOwnPropertyDescriptor(subject, name);
          let proto = Object.getPrototypeOf(subject);
          while (typeof pd === 'undefined' && proto !== null) {
            pd = Object.getOwnPropertyDescriptor(proto, name);
            proto = Object.getPrototypeOf(proto);
          }
          return pd;
        };
      }
  
      callback(PLATFORM, FEATURE, DOM);
    }
    function reset() {
      exports.isInitialized = false;
    }
  
    if (!String.prototype.endsWith || function () {
      try {
        return !"ab".endsWith("a", 1);
      } catch (e) {
        return true;
      }
    }()) {
      String.prototype.endsWith = function (searchString, position) {
        var subjectString = this.toString();
        if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
          position = subjectString.length;
        }
        position -= searchString.length;
        var lastIndex = subjectString.indexOf(searchString, position);
        return lastIndex !== -1 && lastIndex === position;
      };
    }
  
    if (!String.prototype.startsWith || function () {
      try {
        return !"ab".startsWith("b", 1);
      } catch (e) {
        return true;
      }
    }()) {
      String.prototype.startsWith = function (searchString, position) {
        position = position || 0;
        return this.substr(position, searchString.length) === searchString;
      };
    }
  
    {
  
      var emptyMetadata = Object.freeze({});
      var metadataContainerKey = '__metadata__';
  
      if (typeof Reflect.getOwnMetadata !== 'function') {
        Reflect.getOwnMetadata = function (metadataKey, target, targetKey) {
          if (target.hasOwnProperty(metadataContainerKey)) {
            return (target[metadataContainerKey][targetKey] || emptyMetadata)[metadataKey];
          }
        };
      }
  
      if (typeof Reflect.defineMetadata !== 'function') {
        Reflect.defineMetadata = function (metadataKey, metadataValue, target, targetKey) {
          var metadataContainer = target.hasOwnProperty(metadataContainerKey) ? target[metadataContainerKey] : target[metadataContainerKey] = {};
          var targetContainer = metadataContainer[targetKey] || (metadataContainer[targetKey] = {});
          targetContainer[metadataKey] = metadataValue;
        };
      }
  
      if (typeof Reflect.metadata !== 'function') {
        Reflect.metadata = function (metadataKey, metadataValue) {
          return function (target, targetKey) {
            Reflect.defineMetadata(metadataKey, metadataValue, target, targetKey);
          };
        };
      }
    }
  
    const _PLATFORM = {
      location: window.location,
      history: window.history,
      addEventListener(eventName, callback, capture) {
        this.global.addEventListener(eventName, callback, capture);
      },
      removeEventListener(eventName, callback, capture) {
        this.global.removeEventListener(eventName, callback, capture);
      },
      performance: window.performance,
      requestAnimationFrame(callback) {
        return this.global.requestAnimationFrame(callback);
      }
    };
  
    if (Element && !Element.prototype.matches) {
      let proto = Element.prototype;
      proto.matches = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector || proto.webkitMatchesSelector;
    }
  
    const _FEATURE = {
      shadowDOM: !!HTMLElement.prototype.attachShadow,
      scopedCSS: 'scoped' in document.createElement('style'),
      htmlTemplateElement: function () {
        let d = document.createElement('div');
        d.innerHTML = '<template></template>';
        return 'content' in d.children[0];
      }(),
      mutationObserver: !!(window.MutationObserver || window.WebKitMutationObserver),
      ensureHTMLTemplateElement: t => t
    };
  
    let shadowPoly = window.ShadowDOMPolyfill || null;
  
    const _DOM = {
      Element: Element,
      NodeList: NodeList,
      SVGElement: SVGElement,
      boundary: 'aurelia-dom-boundary',
      addEventListener(eventName, callback, capture) {
        document.addEventListener(eventName, callback, capture);
      },
      removeEventListener(eventName, callback, capture) {
        document.removeEventListener(eventName, callback, capture);
      },
      adoptNode(node) {
        return document.adoptNode(node);
      },
      createAttribute(name) {
        return document.createAttribute(name);
      },
      createElement(tagName) {
        return document.createElement(tagName);
      },
      createTextNode(text) {
        return document.createTextNode(text);
      },
      createComment(text) {
        return document.createComment(text);
      },
      createDocumentFragment() {
        return document.createDocumentFragment();
      },
      createTemplateElement() {
        let template = document.createElement('template');
        return _FEATURE.ensureHTMLTemplateElement(template);
      },
      createMutationObserver(callback) {
        return new (window.MutationObserver || window.WebKitMutationObserver)(callback);
      },
      createCustomEvent(eventType, options) {
        return new window.CustomEvent(eventType, options);
      },
      dispatchEvent(evt) {
        document.dispatchEvent(evt);
      },
      getComputedStyle(element) {
        return window.getComputedStyle(element);
      },
      getElementById(id) {
        return document.getElementById(id);
      },
      querySelector(query) {
        return document.querySelector(query);
      },
      querySelectorAll(query) {
        return document.querySelectorAll(query);
      },
      nextElementSibling(element) {
        if (element.nextElementSibling) {
          return element.nextElementSibling;
        }
        do {
          element = element.nextSibling;
        } while (element && element.nodeType !== 1);
        return element;
      },
      createTemplateFromMarkup(markup) {
        let parser = document.createElement('div');
        parser.innerHTML = markup;
  
        let temp = parser.firstElementChild;
        if (!temp || temp.nodeName !== 'TEMPLATE') {
          throw new Error('Template markup must be wrapped in a <template> element e.g. <template> <!-- markup here --> </template>');
        }
  
        return _FEATURE.ensureHTMLTemplateElement(temp);
      },
      appendNode(newNode, parentNode) {
        (parentNode || document.body).appendChild(newNode);
      },
      replaceNode(newNode, node, parentNode) {
        if (node.parentNode) {
          node.parentNode.replaceChild(newNode, node);
        } else if (shadowPoly !== null) {
          shadowPoly.unwrap(parentNode).replaceChild(shadowPoly.unwrap(newNode), shadowPoly.unwrap(node));
        } else {
          parentNode.replaceChild(newNode, node);
        }
      },
      removeNode(node, parentNode) {
        if (node.parentNode) {
          node.parentNode.removeChild(node);
        } else if (parentNode) {
          if (shadowPoly !== null) {
            shadowPoly.unwrap(parentNode).removeChild(shadowPoly.unwrap(node));
          } else {
            parentNode.removeChild(node);
          }
        }
      },
      injectStyles(styles, destination, prepend, id) {
        if (id) {
          let oldStyle = document.getElementById(id);
          if (oldStyle) {
            let isStyleTag = oldStyle.tagName.toLowerCase() === 'style';
  
            if (isStyleTag) {
              oldStyle.innerHTML = styles;
              return;
            }
  
            throw new Error('The provided id does not indicate a style tag.');
          }
        }
  
        let node = document.createElement('style');
        node.innerHTML = styles;
        node.type = 'text/css';
  
        if (id) {
          node.id = id;
        }
  
        destination = destination || document.head;
  
        if (prepend && destination.childNodes.length > 0) {
          destination.insertBefore(node, destination.childNodes[0]);
        } else {
          destination.appendChild(node);
        }
  
        return node;
      }
    };
  
    function initialize() {
      if (exports.isInitialized) {
        return;
      }
  
      initializePAL((platform, feature, dom) => {
        Object.assign(platform, _PLATFORM);
        Object.assign(feature, _FEATURE);
        Object.assign(dom, _DOM);
  
        Object.defineProperty(dom, 'title', {
          get: () => document.title,
          set: value => {
            document.title = value;
          }
        });
  
        Object.defineProperty(dom, 'activeElement', {
          get: () => document.activeElement
        });
  
        Object.defineProperty(platform, 'XMLHttpRequest', {
          get: () => platform.global.XMLHttpRequest
        });
      });
    }
  
    var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
  
    function isObject(val) {
      return val && (typeof val === 'function' || typeof val === 'object');
    }
  
    const metadata = {
      resource: 'aurelia:resource',
      paramTypes: 'design:paramtypes',
      propertyType: 'design:type',
      properties: 'design:properties',
      get(metadataKey, target, targetKey) {
        if (!isObject(target)) {
          return undefined;
        }
        let result = metadata.getOwn(metadataKey, target, targetKey);
        return result === undefined ? metadata.get(metadataKey, Object.getPrototypeOf(target), targetKey) : result;
      },
      getOwn(metadataKey, target, targetKey) {
        if (!isObject(target)) {
          return undefined;
        }
        return Reflect.getOwnMetadata(metadataKey, target, targetKey);
      },
      define(metadataKey, metadataValue, target, targetKey) {
        Reflect.defineMetadata(metadataKey, metadataValue, target, targetKey);
      },
      getOrCreateOwn(metadataKey, Type, target, targetKey) {
        let result = metadata.getOwn(metadataKey, target, targetKey);
  
        if (result === undefined) {
          result = new Type();
          Reflect.defineMetadata(metadataKey, result, target, targetKey);
        }
  
        return result;
      }
    };
  
    const originStorage = new Map();
    const unknownOrigin = Object.freeze({ moduleId: undefined, moduleMember: undefined });
  
    let Origin = class Origin {
      constructor(moduleId, moduleMember) {
        this.moduleId = moduleId;
        this.moduleMember = moduleMember;
      }
  
      static get(fn) {
        let origin = originStorage.get(fn);
  
        if (origin === undefined) {
          PLATFORM.eachModule((key, value) => {
            if (typeof value === 'object') {
              for (let name in value) {
                try {
                  let exp = value[name];
                  if (exp === fn) {
                    originStorage.set(fn, origin = new Origin(key, name));
                    return true;
                  }
                } catch (e) {}
              }
            }
  
            if (value === fn) {
              originStorage.set(fn, origin = new Origin(key, 'default'));
              return true;
            }
  
            return false;
          });
        }
  
        return origin || unknownOrigin;
      }
  
      static set(fn, origin) {
        originStorage.set(fn, origin);
      }
    };
  
    function decorators(...rest) {
      let applicator = function (target, key, descriptor) {
        let i = rest.length;
  
        if (key) {
          descriptor = descriptor || {
            value: target[key],
            writable: true,
            configurable: true,
            enumerable: true
          };
  
          while (i--) {
            descriptor = rest[i](target, key, descriptor) || descriptor;
          }
  
          Object.defineProperty(target, key, descriptor);
        } else {
          while (i--) {
            target = rest[i](target) || target;
          }
        }
  
        return target;
      };
  
      applicator.on = applicator;
      return applicator;
    }
  
    function deprecated(optionsOrTarget, maybeKey, maybeDescriptor) {
      function decorator(target, key, descriptor) {
        const methodSignature = `${target.constructor.name}#${key}`;
        let options = maybeKey ? {} : optionsOrTarget || {};
        let message = `DEPRECATION - ${methodSignature}`;
  
        if (typeof descriptor.value !== 'function') {
          throw new SyntaxError('Only methods can be marked as deprecated.');
        }
  
        if (options.message) {
          message += ` - ${options.message}`;
        }
  
        return _extends({}, descriptor, {
          value: function deprecationWrapper() {
            if (options.error) {
              throw new Error(message);
            } else {
              console.warn(message);
            }
  
            return descriptor.value.apply(this, arguments);
          }
        });
      }
  
      return maybeKey ? decorator(optionsOrTarget, maybeKey, maybeDescriptor) : decorator;
    }
  
    function mixin(behavior) {
      const instanceKeys = Object.keys(behavior);
  
      function _mixin(possible) {
        let decorator = function (target) {
          let resolvedTarget = typeof target === 'function' ? target.prototype : target;
  
          let i = instanceKeys.length;
          while (i--) {
            let property = instanceKeys[i];
            Object.defineProperty(resolvedTarget, property, {
              value: behavior[property],
              writable: true
            });
          }
        };
  
        return possible ? decorator(possible) : decorator;
      }
  
      return _mixin;
    }
  
    function alwaysValid() {
      return true;
    }
    function noCompose() {}
  
    function ensureProtocolOptions(options) {
      if (options === undefined) {
        options = {};
      } else if (typeof options === 'function') {
        options = {
          validate: options
        };
      }
  
      if (!options.validate) {
        options.validate = alwaysValid;
      }
  
      if (!options.compose) {
        options.compose = noCompose;
      }
  
      return options;
    }
  
    function createProtocolValidator(validate) {
      return function (target) {
        let result = validate(target);
        return result === true;
      };
    }
  
    function createProtocolAsserter(name, validate) {
      return function (target) {
        let result = validate(target);
        if (result !== true) {
          throw new Error(result || `${name} was not correctly implemented.`);
        }
      };
    }
  
    function protocol(name, options) {
      options = ensureProtocolOptions(options);
  
      let result = function (target) {
        let resolvedTarget = typeof target === 'function' ? target.prototype : target;
  
        options.compose(resolvedTarget);
        result.assert(resolvedTarget);
  
        Object.defineProperty(resolvedTarget, 'protocol:' + name, {
          enumerable: false,
          configurable: false,
          writable: false,
          value: true
        });
      };
  
      result.validate = createProtocolValidator(options.validate);
      result.assert = createProtocolAsserter(name, options.validate);
  
      return result;
    }
  
    protocol.create = function (name, options) {
      options = ensureProtocolOptions(options);
      let hidden = 'protocol:' + name;
      let result = function (target) {
        let decorator = protocol(name, options);
        return target ? decorator(target) : decorator;
      };
  
      result.decorates = function (obj) {
        return obj[hidden] === true;
      };
      result.validate = createProtocolValidator(options.validate);
      result.assert = createProtocolAsserter(name, options.validate);
  
      return result;
    };
  
    var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
  
    function trimDots(ary) {
      for (var i = 0; i < ary.length; ++i) {
        var part = ary[i];
        if (part === '.') {
          ary.splice(i, 1);
          i -= 1;
        } else if (part === '..') {
          if (i === 0 || i === 1 && ary[2] === '..' || ary[i - 1] === '..') {
            continue;
          } else if (i > 0) {
            ary.splice(i - 1, 2);
            i -= 2;
          }
        }
      }
    }
  
    function relativeToFile(name, file) {
      var fileParts = file && file.split('/');
      var nameParts = name.trim().split('/');
  
      if (nameParts[0].charAt(0) === '.' && fileParts) {
        var normalizedBaseParts = fileParts.slice(0, fileParts.length - 1);
        nameParts.unshift.apply(nameParts, normalizedBaseParts);
      }
  
      trimDots(nameParts);
  
      return nameParts.join('/');
    }
  
    function join(path1, path2) {
      if (!path1) {
        return path2;
      }
  
      if (!path2) {
        return path1;
      }
  
      var schemeMatch = path1.match(/^([^/]*?:)\//);
      var scheme = schemeMatch && schemeMatch.length > 0 ? schemeMatch[1] : '';
      path1 = path1.substr(scheme.length);
  
      var urlPrefix = void 0;
      if (path1.indexOf('///') === 0 && scheme === 'file:') {
        urlPrefix = '///';
      } else if (path1.indexOf('//') === 0) {
        urlPrefix = '//';
      } else if (path1.indexOf('/') === 0) {
        urlPrefix = '/';
      } else {
        urlPrefix = '';
      }
  
      var trailingSlash = path2.slice(-1) === '/' ? '/' : '';
  
      var url1 = path1.split('/');
      var url2 = path2.split('/');
      var url3 = [];
  
      for (var i = 0, ii = url1.length; i < ii; ++i) {
        if (url1[i] === '..') {
          url3.pop();
        } else if (url1[i] === '.' || url1[i] === '') {
          continue;
        } else {
          url3.push(url1[i]);
        }
      }
  
      for (var _i = 0, _ii = url2.length; _i < _ii; ++_i) {
        if (url2[_i] === '..') {
          url3.pop();
        } else if (url2[_i] === '.' || url2[_i] === '') {
          continue;
        } else {
          url3.push(url2[_i]);
        }
      }
  
      return scheme + urlPrefix + url3.join('/') + trailingSlash;
    }
  
    var encode = encodeURIComponent;
    var encodeKey = function encodeKey(k) {
      return encode(k).replace('%24', '$');
    };
  
    function buildParam(key, value, traditional) {
      var result = [];
      if (value === null || value === undefined) {
        return result;
      }
      if (Array.isArray(value)) {
        for (var i = 0, l = value.length; i < l; i++) {
          if (traditional) {
            result.push(encodeKey(key) + '=' + encode(value[i]));
          } else {
            var arrayKey = key + '[' + (_typeof(value[i]) === 'object' && value[i] !== null ? i : '') + ']';
            result = result.concat(buildParam(arrayKey, value[i]));
          }
        }
      } else if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && !traditional) {
        for (var propertyName in value) {
          result = result.concat(buildParam(key + '[' + propertyName + ']', value[propertyName]));
        }
      } else {
        result.push(encodeKey(key) + '=' + encode(value));
      }
      return result;
    }
  
    function buildQueryString(params, traditional) {
      var pairs = [];
      var keys = Object.keys(params || {}).sort();
      for (var i = 0, len = keys.length; i < len; i++) {
        var key = keys[i];
        pairs = pairs.concat(buildParam(key, params[key], traditional));
      }
  
      if (pairs.length === 0) {
        return '';
      }
  
      return pairs.join('&');
    }
  
    function processScalarParam(existedParam, value) {
      if (Array.isArray(existedParam)) {
        existedParam.push(value);
        return existedParam;
      }
      if (existedParam !== undefined) {
        return [existedParam, value];
      }
  
      return value;
    }
  
    function parseComplexParam(queryParams, keys, value) {
      var currentParams = queryParams;
      var keysLastIndex = keys.length - 1;
      for (var j = 0; j <= keysLastIndex; j++) {
        var key = keys[j] === '' ? currentParams.length : keys[j];
        if (j < keysLastIndex) {
          var prevValue = !currentParams[key] || _typeof(currentParams[key]) === 'object' ? currentParams[key] : [currentParams[key]];
          currentParams = currentParams[key] = prevValue || (isNaN(keys[j + 1]) ? {} : []);
        } else {
          currentParams = currentParams[key] = value;
        }
      }
    }
  
    function parseQueryString(queryString) {
      var queryParams = {};
      if (!queryString || typeof queryString !== 'string') {
        return queryParams;
      }
  
      var query = queryString;
      if (query.charAt(0) === '?') {
        query = query.substr(1);
      }
  
      var pairs = query.replace(/\+/g, ' ').split('&');
      for (var i = 0; i < pairs.length; i++) {
        var pair = pairs[i].split('=');
        var key = decodeURIComponent(pair[0]);
        if (!key) {
          continue;
        }
  
        var keys = key.split('][');
        var keysLastIndex = keys.length - 1;
  
        if (/\[/.test(keys[0]) && /\]$/.test(keys[keysLastIndex])) {
          keys[keysLastIndex] = keys[keysLastIndex].replace(/\]$/, '');
          keys = keys.shift().split('[').concat(keys);
          keysLastIndex = keys.length - 1;
        } else {
          keysLastIndex = 0;
        }
  
        if (pair.length >= 2) {
          var value = pair[1] ? decodeURIComponent(pair[1]) : '';
          if (keysLastIndex) {
            parseComplexParam(queryParams, keys, value);
          } else {
            queryParams[key] = processScalarParam(queryParams[key], value);
          }
        } else {
          queryParams[key] = true;
        }
      }
      return queryParams;
    }
  
    let TemplateDependency = class TemplateDependency {
      constructor(src, name) {
        this.src = src;
        this.name = name;
      }
    };
  
    let TemplateRegistryEntry = class TemplateRegistryEntry {
      constructor(address) {
        this.templateIsLoaded = false;
        this.factoryIsReady = false;
        this.resources = null;
        this.dependencies = null;
  
        this.address = address;
        this.onReady = null;
        this._template = null;
        this._factory = null;
      }
  
      get template() {
        return this._template;
      }
  
      set template(value) {
        let address = this.address;
        let requires;
        let current;
        let src;
        let dependencies;
  
        this._template = value;
        this.templateIsLoaded = true;
  
        requires = value.content.querySelectorAll('require');
        dependencies = this.dependencies = new Array(requires.length);
  
        for (let i = 0, ii = requires.length; i < ii; ++i) {
          current = requires[i];
          src = current.getAttribute('from');
  
          if (!src) {
            throw new Error(`<require> element in ${address} has no "from" attribute.`);
          }
  
          dependencies[i] = new TemplateDependency(relativeToFile(src, address), current.getAttribute('as'));
  
          if (current.parentNode) {
            current.parentNode.removeChild(current);
          }
        }
      }
  
      get factory() {
        return this._factory;
      }
  
      set factory(value) {
        this._factory = value;
        this.factoryIsReady = true;
      }
  
      addDependency(src, name) {
        let finalSrc = typeof src === 'string' ? relativeToFile(src, this.address) : Origin.get(src).moduleId;
  
        this.dependencies.push(new TemplateDependency(finalSrc, name));
      }
    };
  
    let Loader = class Loader {
      constructor() {
        this.templateRegistry = {};
      }
  
      map(id, source) {
        throw new Error('Loaders must implement map(id, source).');
      }
  
      normalizeSync(moduleId, relativeTo) {
        throw new Error('Loaders must implement normalizeSync(moduleId, relativeTo).');
      }
  
      normalize(moduleId, relativeTo) {
        throw new Error('Loaders must implement normalize(moduleId: string, relativeTo: string): Promise<string>.');
      }
  
      loadModule(id) {
        throw new Error('Loaders must implement loadModule(id).');
      }
  
      loadAllModules(ids) {
        throw new Error('Loader must implement loadAllModules(ids).');
      }
  
      loadTemplate(url) {
        throw new Error('Loader must implement loadTemplate(url).');
      }
  
      loadText(url) {
        throw new Error('Loader must implement loadText(url).');
      }
  
      applyPluginToUrl(url, pluginName) {
        throw new Error('Loader must implement applyPluginToUrl(url, pluginName).');
      }
  
      addPlugin(pluginName, implementation) {
        throw new Error('Loader must implement addPlugin(pluginName, implementation).');
      }
  
      getOrCreateTemplateRegistryEntry(address) {
        return this.templateRegistry[address] || (this.templateRegistry[address] = new TemplateRegistryEntry(address));
      }
    };
  
    /**
    * An implementation of the TemplateLoader interface implemented with text-based loading.
    */
    class TextTemplateLoader {
        /**
        * Loads a template.
        * @param loader The loader that is requesting the template load.
        * @param entry The TemplateRegistryEntry to load and populate with a template.
        * @return A promise which resolves when the TemplateRegistryEntry is loaded with a template.
        */
        async loadTemplate(loader, entry) {
            const text = await loader.loadText(entry.address);
            entry.template = DOM.createTemplateFromMarkup(text);
        }
    }
    function ensureOriginOnExports(moduleExports, moduleId) {
        let target = moduleExports;
        let key;
        let exportedValue;
        // Mark the module with Origin
        // for view mapping from loader
        Origin.set(target, new Origin(moduleId, ''));
        if (typeof target === 'object') {
            for (key in target) {
                exportedValue = target[key];
                if (typeof exportedValue === 'function') {
                    Origin.set(exportedValue, new Origin(moduleId, key));
                }
            }
        }
        return moduleExports;
    }
    /**
    * A default implementation of the Loader abstraction which works with webpack (extended common-js style).
    */
    class EsmLoader extends Loader {
        constructor() {
            super();
            this.moduleRegistry = Object.create(null);
            this.loaderPlugins = Object.create(null);
            this.modulesBeingLoaded = new Map();
            this.baseUrl = location.origin || `${location.protocol}//${location.hostname}${location.port ? `:${location.port}` : ''}`;
            this.useTemplateLoader(new TextTemplateLoader());
            this.addPlugin('template-registry-entry', {
                fetch: async (moduleId) => {
                    const entry = this.getOrCreateTemplateRegistryEntry(moduleId);
                    if (!entry.templateIsLoaded) {
                        await this.templateLoader.loadTemplate(this, entry);
                    }
                    return entry;
                }
            });
            PLATFORM.eachModule = callback => {
                const registry = this.moduleRegistry;
                const cachedModuleIds = Object.getOwnPropertyNames(registry);
                cachedModuleIds
                    // Note: we use .some here like a .forEach that can be "break"ed out of.
                    // It will stop iterating only when a truthy value is returned.
                    // Even though the docs say "true" explicitly, loader-default also goes by truthy
                    // and this is to keep it consistent with that.
                    .some(moduleId => {
                    const moduleExports = registry[moduleId].exports;
                    if (typeof moduleExports === 'object') {
                        return callback(moduleId, moduleExports);
                    }
                    return false;
                });
            };
        }
        /**
         * @internal
         */
        async _import(address) {
            const addressParts = address.split('!');
            const moduleId = addressParts.splice(addressParts.length - 1, 1)[0];
            const loaderPlugin = addressParts.length === 1 ? addressParts[0] : null;
            if (loaderPlugin) {
                const plugin = this.loaderPlugins[loaderPlugin];
                if (!plugin) {
                    throw new Error(`Plugin ${loaderPlugin} is not registered in the loader.`);
                }
                return await plugin.fetch(moduleId);
            }
            return import(join(this.baseUrl, moduleId)).then(m => {
                this.moduleRegistry[moduleId] = m;
                return m;
            });
        }
        /**
        * Maps a module id to a source.
        * @param id The module id.
        * @param source The source to map the module to.
        */
        map(id, source) { }
        /**
        * Normalizes a module id.
        * @param moduleId The module id to normalize.
        * @param relativeTo What the module id should be normalized relative to.
        * @return The normalized module id.
        */
        normalizeSync(moduleId, relativeTo) {
            return moduleId;
        }
        /**
        * Normalizes a module id.
        * @param moduleId The module id to normalize.
        * @param relativeTo What the module id should be normalized relative to.
        * @return The normalized module id.
        */
        normalize(moduleId, relativeTo) {
            return Promise.resolve(moduleId);
        }
        /**
        * Instructs the loader to use a specific TemplateLoader instance for loading templates
        * @param templateLoader The instance of TemplateLoader to use for loading templates.
        */
        useTemplateLoader(templateLoader) {
            this.templateLoader = templateLoader;
        }
        /**
        * Loads a collection of modules.
        * @param ids The set of module ids to load.
        * @return A Promise for an array of loaded modules.
        */
        loadAllModules(ids) {
            return Promise.all(ids.map(id => this.loadModule(id)));
        }
        /**
        * Loads a module.
        * @param moduleId The module ID to load.
        * @return A Promise for the loaded module.
        */
        async loadModule(moduleId) {
            let existing = this.moduleRegistry[moduleId];
            if (existing) {
                return existing;
            }
            let beingLoaded = this.modulesBeingLoaded.get(moduleId);
            if (beingLoaded) {
                return beingLoaded;
            }
            beingLoaded = this._import(moduleId);
            this.modulesBeingLoaded.set(moduleId, beingLoaded);
            const moduleExports = await beingLoaded;
            this.moduleRegistry[moduleId] = ensureOriginOnExports(moduleExports, moduleId);
            this.modulesBeingLoaded.delete(moduleId);
            return moduleExports;
        }
        /**
        * Loads a template.
        * @param url The url of the template to load.
        * @return A Promise for a TemplateRegistryEntry containing the template.
        */
        loadTemplate(url) {
            return this.loadModule(this.applyPluginToUrl(url, 'template-registry-entry'));
        }
        /**
        * Loads a text-based resource.
        * @param url The url of the text file to load.
        * @return A Promise for text content.
        */
        async loadText(url) {
            return fetch(url).then(res => res.text());
        }
        /**
        * Alters a module id so that it includes a plugin loader.
        * @param url The url of the module to load.
        * @param pluginName The plugin to apply to the module id.
        * @return The plugin-based module id.
        */
        applyPluginToUrl(url, pluginName) {
            return `${pluginName}!${url}`;
        }
        /**
        * Registers a plugin with the loader.
        * @param pluginName The name of the plugin.
        * @param implementation The plugin implementation.
        */
        addPlugin(pluginName, implementation) {
            this.loaderPlugins[pluginName] = implementation;
        }
    }
    PLATFORM.Loader = EsmLoader;
  
    const logLevel = {
      none: 0,
      error: 10,
      warn: 20,
      info: 30,
      debug: 40
    };
  
    let loggers = {};
    let appenders = [];
    let globalDefaultLevel = logLevel.none;
  
    const standardLevels = ['none', 'error', 'warn', 'info', 'debug'];
    function isStandardLevel(level) {
      return standardLevels.filter(l => l === level).length > 0;
    }
  
    function appendArgs() {
      return [this, ...arguments];
    }
  
    function logFactory(level) {
      const threshold = logLevel[level];
      return function () {
        if (this.level < threshold) {
          return;
        }
  
        const args = appendArgs.apply(this, arguments);
        let i = appenders.length;
        while (i--) {
          appenders[i][level](...args);
        }
      };
    }
  
    function logFactoryCustom(level) {
      const threshold = logLevel[level];
      return function () {
        if (this.level < threshold) {
          return;
        }
  
        const args = appendArgs.apply(this, arguments);
        let i = appenders.length;
        while (i--) {
          const appender = appenders[i];
          if (appender[level] !== undefined) {
            appender[level](...args);
          }
        }
      };
    }
  
    function connectLoggers() {
      let proto = Logger.prototype;
      for (let level in logLevel) {
        if (isStandardLevel(level)) {
          if (level !== 'none') {
            proto[level] = logFactory(level);
          }
        } else {
          proto[level] = logFactoryCustom(level);
        }
      }
    }
  
    function disconnectLoggers() {
      let proto = Logger.prototype;
      for (let level in logLevel) {
        if (level !== 'none') {
          proto[level] = function () {};
        }
      }
    }
  
    function getLogger(id) {
      return loggers[id] || new Logger(id);
    }
  
    function addAppender(appender) {
      if (appenders.push(appender) === 1) {
        connectLoggers();
      }
    }
  
    function removeAppender(appender) {
      appenders = appenders.filter(a => a !== appender);
    }
  
    function getAppenders() {
      return [...appenders];
    }
  
    function clearAppenders() {
      appenders = [];
      disconnectLoggers();
    }
  
    function addCustomLevel(name, value) {
      if (logLevel[name] !== undefined) {
        throw Error(`Log level "${name}" already exists.`);
      }
  
      if (isNaN(value)) {
        throw Error('Value must be a number.');
      }
  
      logLevel[name] = value;
  
      if (appenders.length > 0) {
        connectLoggers();
      } else {
        Logger.prototype[name] = function () {};
      }
    }
  
    function removeCustomLevel(name) {
      if (logLevel[name] === undefined) {
        return;
      }
  
      if (isStandardLevel(name)) {
        throw Error(`Built-in log level "${name}" cannot be removed.`);
      }
  
      delete logLevel[name];
      delete Logger.prototype[name];
    }
  
    function setLevel(level) {
      globalDefaultLevel = level;
      for (let key in loggers) {
        loggers[key].setLevel(level);
      }
    }
  
    function getLevel() {
      return globalDefaultLevel;
    }
  
    let Logger = class Logger {
      constructor(id) {
        let cached = loggers[id];
        if (cached) {
          return cached;
        }
  
        loggers[id] = this;
        this.id = id;
        this.level = globalDefaultLevel;
      }
  
      debug(message, ...rest) {}
  
      info(message, ...rest) {}
  
      warn(message, ...rest) {}
  
      error(message, ...rest) {}
  
      setLevel(level) {
        this.level = level;
      }
  
      isDebugEnabled() {
        return this.level === logLevel.debug;
      }
    };
  
    var TheLogManager = /*#__PURE__*/Object.freeze({
      logLevel: logLevel,
      getLogger: getLogger,
      addAppender: addAppender,
      removeAppender: removeAppender,
      getAppenders: getAppenders,
      clearAppenders: clearAppenders,
      addCustomLevel: addCustomLevel,
      removeCustomLevel: removeCustomLevel,
      setLevel: setLevel,
      getLevel: getLevel,
      Logger: Logger
    });
  
    var _dec, _class, _dec2, _class2, _dec3, _class3, _dec4, _class4, _dec5, _class5, _dec6, _class6, _dec7, _class7;
  
    const resolver = protocol.create('aurelia:resolver', function (target) {
      if (!(typeof target.get === 'function')) {
        return 'Resolvers must implement: get(container: Container, key: any): any';
      }
  
      return true;
    });
  
    let StrategyResolver = (_dec = resolver(), _dec(_class = class StrategyResolver {
      constructor(strategy, state) {
        this.strategy = strategy;
        this.state = state;
      }
  
      get(container, key) {
        switch (this.strategy) {
          case 0:
            return this.state;
          case 1:
            let singleton = container.invoke(this.state);
            this.state = singleton;
            this.strategy = 0;
            return singleton;
          case 2:
            return container.invoke(this.state);
          case 3:
            return this.state(container, key, this);
          case 4:
            return this.state[0].get(container, key);
          case 5:
            return container.get(this.state);
          default:
            throw new Error('Invalid strategy: ' + this.strategy);
        }
      }
    }) || _class);
  
    let Lazy = (_dec2 = resolver(), _dec2(_class2 = class Lazy {
      constructor(key) {
        this._key = key;
      }
  
      get(container) {
        return () => container.get(this._key);
      }
  
      static of(key) {
        return new Lazy(key);
      }
    }) || _class2);
  
    let All = (_dec3 = resolver(), _dec3(_class3 = class All {
      constructor(key) {
        this._key = key;
      }
  
      get(container) {
        return container.getAll(this._key);
      }
  
      static of(key) {
        return new All(key);
      }
    }) || _class3);
  
    let Optional = (_dec4 = resolver(), _dec4(_class4 = class Optional {
      constructor(key, checkParent = true) {
        this._key = key;
        this._checkParent = checkParent;
      }
  
      get(container) {
        if (container.hasResolver(this._key, this._checkParent)) {
          return container.get(this._key);
        }
  
        return null;
      }
  
      static of(key, checkParent = true) {
        return new Optional(key, checkParent);
      }
    }) || _class4);
  
    let Parent = (_dec5 = resolver(), _dec5(_class5 = class Parent {
      constructor(key) {
        this._key = key;
      }
  
      get(container) {
        return container.parent ? container.parent.get(this._key) : null;
      }
  
      static of(key) {
        return new Parent(key);
      }
    }) || _class5);
  
    let Factory = (_dec6 = resolver(), _dec6(_class6 = class Factory {
      constructor(key) {
        this._key = key;
      }
  
      get(container) {
        let fn = this._key;
        let resolver = container.getResolver(fn);
        if (resolver && resolver.strategy === 3) {
          fn = resolver.state;
        }
  
        return (...rest) => container.invoke(fn, rest);
      }
  
      static of(key) {
        return new Factory(key);
      }
    }) || _class6);
  
    let NewInstance = (_dec7 = resolver(), _dec7(_class7 = class NewInstance {
      constructor(key, ...dynamicDependencies) {
        this.key = key;
        this.asKey = key;
        this.dynamicDependencies = dynamicDependencies;
      }
  
      get(container) {
        let dynamicDependencies = this.dynamicDependencies.length > 0 ? this.dynamicDependencies.map(dependency => dependency['protocol:aurelia:resolver'] ? dependency.get(container) : container.get(dependency)) : undefined;
  
        let fn = this.key;
        let resolver = container.getResolver(fn);
        if (resolver && resolver.strategy === 3) {
          fn = resolver.state;
        }
  
        const instance = container.invoke(fn, dynamicDependencies);
        container.registerInstance(this.asKey, instance);
        return instance;
      }
  
      as(key) {
        this.asKey = key;
        return this;
      }
  
      static of(key, ...dynamicDependencies) {
        return new NewInstance(key, ...dynamicDependencies);
      }
    }) || _class7);
  
    function getDecoratorDependencies(target) {
      autoinject(target);
  
      return target.inject;
    }
  
    function lazy(keyValue) {
      return function (target, key, index) {
        let inject = getDecoratorDependencies(target);
        inject[index] = Lazy.of(keyValue);
      };
    }
  
    function all(keyValue) {
      return function (target, key, index) {
        let inject = getDecoratorDependencies(target);
        inject[index] = All.of(keyValue);
      };
    }
  
    function optional(checkParentOrTarget = true) {
      let deco = function (checkParent) {
        return function (target, key, index) {
          let inject = getDecoratorDependencies(target);
          inject[index] = Optional.of(inject[index], checkParent);
        };
      };
      if (typeof checkParentOrTarget === 'boolean') {
        return deco(checkParentOrTarget);
      }
      return deco(true);
    }
  
    function parent(target, key, index) {
      let inject = getDecoratorDependencies(target);
      inject[index] = Parent.of(inject[index]);
    }
  
    function factory(keyValue) {
      return function (target, key, index) {
        let inject = getDecoratorDependencies(target);
        inject[index] = Factory.of(keyValue);
      };
    }
  
    function newInstance(asKeyOrTarget, ...dynamicDependencies) {
      let deco = function (asKey) {
        return function (target, key, index) {
          let inject = getDecoratorDependencies(target);
          inject[index] = NewInstance.of(inject[index], ...dynamicDependencies);
          if (!!asKey) {
            inject[index].as(asKey);
          }
        };
      };
      if (arguments.length >= 1) {
        return deco(asKeyOrTarget);
      }
      return deco();
    }
  
    function invoker(value) {
      return function (target) {
        metadata.define(metadata.invoker, value, target);
      };
    }
  
    function invokeAsFactory(potentialTarget) {
      let deco = function (target) {
        metadata.define(metadata.invoker, FactoryInvoker.instance, target);
      };
  
      return potentialTarget ? deco(potentialTarget) : deco;
    }
  
    let FactoryInvoker = class FactoryInvoker {
      invoke(container, fn, dependencies) {
        let i = dependencies.length;
        let args = new Array(i);
  
        while (i--) {
          args[i] = container.get(dependencies[i]);
        }
  
        return fn.apply(undefined, args);
      }
  
      invokeWithDynamicDependencies(container, fn, staticDependencies, dynamicDependencies) {
        let i = staticDependencies.length;
        let args = new Array(i);
  
        while (i--) {
          args[i] = container.get(staticDependencies[i]);
        }
  
        if (dynamicDependencies !== undefined) {
          args = args.concat(dynamicDependencies);
        }
  
        return fn.apply(undefined, args);
      }
    };
  
    FactoryInvoker.instance = new FactoryInvoker();
  
    function registration(value) {
      return function (target) {
        metadata.define(metadata.registration, value, target);
      };
    }
  
    function transient(key) {
      return registration(new TransientRegistration(key));
    }
  
    function singleton(keyOrRegisterInChild, registerInChild = false) {
      return registration(new SingletonRegistration(keyOrRegisterInChild, registerInChild));
    }
  
    let TransientRegistration = class TransientRegistration {
      constructor(key) {
        this._key = key;
      }
  
      registerResolver(container, key, fn) {
        let existingResolver = container.getResolver(this._key || key);
        return existingResolver === undefined ? container.registerTransient(this._key || key, fn) : existingResolver;
      }
    };
  
    let SingletonRegistration = class SingletonRegistration {
      constructor(keyOrRegisterInChild, registerInChild = false) {
        if (typeof keyOrRegisterInChild === 'boolean') {
          this._registerInChild = keyOrRegisterInChild;
        } else {
          this._key = keyOrRegisterInChild;
          this._registerInChild = registerInChild;
        }
      }
  
      registerResolver(container, key, fn) {
        let targetContainer = this._registerInChild ? container : container.root;
        let existingResolver = targetContainer.getResolver(this._key || key);
        return existingResolver === undefined ? targetContainer.registerSingleton(this._key || key, fn) : existingResolver;
      }
    };
  
    function validateKey(key) {
      if (key === null || key === undefined) {
        throw new Error('key/value cannot be null or undefined. Are you trying to inject/register something that doesn\'t exist with DI?');
      }
    }
    const _emptyParameters = Object.freeze([]);
  
    metadata.registration = 'aurelia:registration';
    metadata.invoker = 'aurelia:invoker';
  
    let resolverDecorates = resolver.decorates;
  
    let InvocationHandler = class InvocationHandler {
      constructor(fn, invoker, dependencies) {
        this.fn = fn;
        this.invoker = invoker;
        this.dependencies = dependencies;
      }
  
      invoke(container, dynamicDependencies) {
        return dynamicDependencies !== undefined ? this.invoker.invokeWithDynamicDependencies(container, this.fn, this.dependencies, dynamicDependencies) : this.invoker.invoke(container, this.fn, this.dependencies);
      }
    };
  
    function invokeWithDynamicDependencies(container, fn, staticDependencies, dynamicDependencies) {
      let i = staticDependencies.length;
      let args = new Array(i);
      let lookup;
  
      while (i--) {
        lookup = staticDependencies[i];
  
        if (lookup === null || lookup === undefined) {
          throw new Error('Constructor Parameter with index ' + i + ' cannot be null or undefined. Are you trying to inject/register something that doesn\'t exist with DI?');
        } else {
          args[i] = container.get(lookup);
        }
      }
  
      if (dynamicDependencies !== undefined) {
        args = args.concat(dynamicDependencies);
      }
  
      return Reflect.construct(fn, args);
    }
  
    let classInvokers = {
      [0]: {
        invoke(container, Type) {
          return new Type();
        },
        invokeWithDynamicDependencies: invokeWithDynamicDependencies
      },
      [1]: {
        invoke(container, Type, deps) {
          return new Type(container.get(deps[0]));
        },
        invokeWithDynamicDependencies: invokeWithDynamicDependencies
      },
      [2]: {
        invoke(container, Type, deps) {
          return new Type(container.get(deps[0]), container.get(deps[1]));
        },
        invokeWithDynamicDependencies: invokeWithDynamicDependencies
      },
      [3]: {
        invoke(container, Type, deps) {
          return new Type(container.get(deps[0]), container.get(deps[1]), container.get(deps[2]));
        },
        invokeWithDynamicDependencies: invokeWithDynamicDependencies
      },
      [4]: {
        invoke(container, Type, deps) {
          return new Type(container.get(deps[0]), container.get(deps[1]), container.get(deps[2]), container.get(deps[3]));
        },
        invokeWithDynamicDependencies: invokeWithDynamicDependencies
      },
      [5]: {
        invoke(container, Type, deps) {
          return new Type(container.get(deps[0]), container.get(deps[1]), container.get(deps[2]), container.get(deps[3]), container.get(deps[4]));
        },
        invokeWithDynamicDependencies: invokeWithDynamicDependencies
      },
      fallback: {
        invoke: invokeWithDynamicDependencies,
        invokeWithDynamicDependencies: invokeWithDynamicDependencies
      }
    };
  
    function getDependencies(f) {
      if (!f.hasOwnProperty('inject')) {
        return [];
      }
  
      if (typeof f.inject === 'function') {
        return f.inject();
      }
  
      return f.inject;
    }
  
    let Container = class Container {
      constructor(configuration) {
        if (configuration === undefined) {
          configuration = {};
        }
  
        this._configuration = configuration;
        this._onHandlerCreated = configuration.onHandlerCreated;
        this._handlers = configuration.handlers || (configuration.handlers = new Map());
        this._resolvers = new Map();
        this.root = this;
        this.parent = null;
      }
  
      makeGlobal() {
        Container.instance = this;
        return this;
      }
  
      setHandlerCreatedCallback(onHandlerCreated) {
        this._onHandlerCreated = onHandlerCreated;
        this._configuration.onHandlerCreated = onHandlerCreated;
      }
  
      registerInstance(key, instance) {
        return this.registerResolver(key, new StrategyResolver(0, instance === undefined ? key : instance));
      }
  
      registerSingleton(key, fn) {
        return this.registerResolver(key, new StrategyResolver(1, fn === undefined ? key : fn));
      }
  
      registerTransient(key, fn) {
        return this.registerResolver(key, new StrategyResolver(2, fn === undefined ? key : fn));
      }
  
      registerHandler(key, handler) {
        return this.registerResolver(key, new StrategyResolver(3, handler));
      }
  
      registerAlias(originalKey, aliasKey) {
        return this.registerResolver(aliasKey, new StrategyResolver(5, originalKey));
      }
  
      registerResolver(key, resolver) {
        validateKey(key);
  
        let allResolvers = this._resolvers;
        let result = allResolvers.get(key);
  
        if (result === undefined) {
          allResolvers.set(key, resolver);
        } else if (result.strategy === 4) {
          result.state.push(resolver);
        } else {
          allResolvers.set(key, new StrategyResolver(4, [result, resolver]));
        }
  
        return resolver;
      }
  
      autoRegister(key, fn) {
        fn = fn === undefined ? key : fn;
  
        if (typeof fn === 'function') {
          let registration = metadata.get(metadata.registration, fn);
  
          if (registration === undefined) {
            return this.registerResolver(key, new StrategyResolver(1, fn));
          }
  
          return registration.registerResolver(this, key, fn);
        }
  
        return this.registerResolver(key, new StrategyResolver(0, fn));
      }
  
      autoRegisterAll(fns) {
        let i = fns.length;
        while (i--) {
          this.autoRegister(fns[i]);
        }
      }
  
      unregister(key) {
        this._resolvers.delete(key);
      }
  
      hasResolver(key, checkParent = false) {
        validateKey(key);
  
        return this._resolvers.has(key) || checkParent && this.parent !== null && this.parent.hasResolver(key, checkParent);
      }
  
      getResolver(key) {
        return this._resolvers.get(key);
      }
  
      get(key) {
        validateKey(key);
  
        if (key === Container) {
          return this;
        }
  
        if (resolverDecorates(key)) {
          return key.get(this, key);
        }
  
        let resolver = this._resolvers.get(key);
  
        if (resolver === undefined) {
          if (this.parent === null) {
            return this.autoRegister(key).get(this, key);
          }
  
          let registration = metadata.get(metadata.registration, key);
  
          if (registration === undefined) {
            return this.parent._get(key);
          }
  
          return registration.registerResolver(this, key, key).get(this, key);
        }
  
        return resolver.get(this, key);
      }
  
      _get(key) {
        let resolver = this._resolvers.get(key);
  
        if (resolver === undefined) {
          if (this.parent === null) {
            return this.autoRegister(key).get(this, key);
          }
  
          return this.parent._get(key);
        }
  
        return resolver.get(this, key);
      }
  
      getAll(key) {
        validateKey(key);
  
        let resolver = this._resolvers.get(key);
  
        if (resolver === undefined) {
          if (this.parent === null) {
            return _emptyParameters;
          }
  
          return this.parent.getAll(key);
        }
  
        if (resolver.strategy === 4) {
          let state = resolver.state;
          let i = state.length;
          let results = new Array(i);
  
          while (i--) {
            results[i] = state[i].get(this, key);
          }
  
          return results;
        }
  
        return [resolver.get(this, key)];
      }
  
      createChild() {
        let child = new Container(this._configuration);
        child.root = this.root;
        child.parent = this;
        return child;
      }
  
      invoke(fn, dynamicDependencies) {
        try {
          let handler = this._handlers.get(fn);
  
          if (handler === undefined) {
            handler = this._createInvocationHandler(fn);
            this._handlers.set(fn, handler);
          }
  
          return handler.invoke(this, dynamicDependencies);
        } catch (e) {
          throw new AggregateError(`Error invoking ${fn.name}. Check the inner error for details.`, e, true);
        }
      }
  
      _createInvocationHandler(fn) {
        let dependencies;
  
        if (fn.inject === undefined) {
          dependencies = metadata.getOwn(metadata.paramTypes, fn) || _emptyParameters;
        } else {
          dependencies = [];
          let ctor = fn;
          while (typeof ctor === 'function') {
            dependencies.push(...getDependencies(ctor));
            ctor = Object.getPrototypeOf(ctor);
          }
        }
  
        let invoker = metadata.getOwn(metadata.invoker, fn) || classInvokers[dependencies.length] || classInvokers.fallback;
  
        let handler = new InvocationHandler(fn, invoker, dependencies);
        return this._onHandlerCreated !== undefined ? this._onHandlerCreated(handler) : handler;
      }
    };
  
    function autoinject(potentialTarget) {
      let deco = function (target) {
        if (!target.hasOwnProperty('inject')) {
          target.inject = (metadata.getOwn(metadata.paramTypes, target) || _emptyParameters).slice();
  
          if (target.inject.length > 0 && target.inject[target.inject.length - 1] === Object) {
            target.inject.pop();
          }
        }
      };
  
      return potentialTarget ? deco(potentialTarget) : deco;
    }
  
    function inject(...rest) {
      return function (target, key, descriptor) {
        if (typeof descriptor === 'number') {
          autoinject(target);
          if (rest.length === 1) {
            target.inject[descriptor] = rest[0];
          }
          return;
        }
  
        if (descriptor) {
          const fn = descriptor.value;
          fn.inject = rest;
        } else {
          target.inject = rest;
        }
      };
    }
  
    const stackSeparator = '\nEnqueued in TaskQueue by:\n';
    const microStackSeparator = '\nEnqueued in MicroTaskQueue by:\n';
  
    function makeRequestFlushFromMutationObserver(flush) {
      let observer = DOM.createMutationObserver(flush);
      let val = 'a';
      let node = DOM.createTextNode('a');
      let values = Object.create(null);
      values.a = 'b';
      values.b = 'a';
      observer.observe(node, { characterData: true });
      return function requestFlush() {
        node.data = val = values[val];
      };
    }
  
    function makeRequestFlushFromTimer(flush) {
      return function requestFlush() {
        let timeoutHandle = setTimeout(handleFlushTimer, 0);
  
        let intervalHandle = setInterval(handleFlushTimer, 50);
        function handleFlushTimer() {
          clearTimeout(timeoutHandle);
          clearInterval(intervalHandle);
          flush();
        }
      };
    }
  
    function onError(error, task, longStacks) {
      if (longStacks && task.stack && typeof error === 'object' && error !== null) {
        error.stack = filterFlushStack(error.stack) + task.stack;
      }
  
      if ('onError' in task) {
        task.onError(error);
      } else {
        setTimeout(() => {
          throw error;
        }, 0);
      }
    }
  
    let TaskQueue = class TaskQueue {
      constructor() {
        this.flushing = false;
        this.longStacks = false;
  
        this.microTaskQueue = [];
        this.microTaskQueueCapacity = 1024;
        this.taskQueue = [];
  
        if (FEATURE.mutationObserver) {
          this.requestFlushMicroTaskQueue = makeRequestFlushFromMutationObserver(() => this.flushMicroTaskQueue());
        } else {
          this.requestFlushMicroTaskQueue = makeRequestFlushFromTimer(() => this.flushMicroTaskQueue());
        }
  
        this.requestFlushTaskQueue = makeRequestFlushFromTimer(() => this.flushTaskQueue());
      }
  
      _flushQueue(queue, capacity) {
        let index = 0;
        let task;
  
        try {
          this.flushing = true;
          while (index < queue.length) {
            task = queue[index];
            if (this.longStacks) {
              this.stack = typeof task.stack === 'string' ? task.stack : undefined;
            }
            task.call();
            index++;
  
            if (index > capacity) {
              for (let scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
                queue[scan] = queue[scan + index];
              }
  
              queue.length -= index;
              index = 0;
            }
          }
        } catch (error) {
          onError(error, task, this.longStacks);
        } finally {
          this.flushing = false;
        }
      }
  
      queueMicroTask(task) {
        if (this.microTaskQueue.length < 1) {
          this.requestFlushMicroTaskQueue();
        }
  
        if (this.longStacks) {
          task.stack = this.prepareQueueStack(microStackSeparator);
        }
  
        this.microTaskQueue.push(task);
      }
  
      queueTask(task) {
        if (this.taskQueue.length < 1) {
          this.requestFlushTaskQueue();
        }
  
        if (this.longStacks) {
          task.stack = this.prepareQueueStack(stackSeparator);
        }
  
        this.taskQueue.push(task);
      }
  
      flushTaskQueue() {
        let queue = this.taskQueue;
        this.taskQueue = [];
        this._flushQueue(queue, Number.MAX_VALUE);
      }
  
      flushMicroTaskQueue() {
        let queue = this.microTaskQueue;
        this._flushQueue(queue, this.microTaskQueueCapacity);
        queue.length = 0;
      }
  
      prepareQueueStack(separator) {
        let stack = separator + filterQueueStack(captureStack());
  
        if (typeof this.stack === 'string') {
          stack = filterFlushStack(stack) + this.stack;
        }
  
        return stack;
      }
    };
  
    function captureStack() {
      let error = new Error();
  
      if (error.stack) {
        return error.stack;
      }
  
      try {
        throw error;
      } catch (e) {
        return e.stack;
      }
    }
  
    function filterQueueStack(stack) {
      return stack.replace(/^[\s\S]*?\bqueue(Micro)?Task\b[^\n]*\n/, '');
    }
  
    function filterFlushStack(stack) {
      let index = stack.lastIndexOf('flushMicroTaskQueue');
  
      if (index < 0) {
        index = stack.lastIndexOf('flushTaskQueue');
        if (index < 0) {
          return stack;
        }
      }
  
      index = stack.lastIndexOf('\n', index);
  
      return index < 0 ? stack : stack.substr(0, index);
    }
  
    var _dec$1, _dec2$1, _class$1, _dec3$1, _class2$1, _dec4$1, _class3$1, _dec5$1, _class5$1, _dec6$1, _class7$1, _dec7$1, _class8, _dec8, _class9, _dec9, _class10, _class11, _temp, _dec10, _class12, _class13, _temp2;
  
    const targetContext = 'Binding:target';
    const sourceContext = 'Binding:source';
  
    const map = Object.create(null);
  
    function camelCase(name) {
      if (name in map) {
        return map[name];
      }
      const result = name.charAt(0).toLowerCase() + name.slice(1).replace(/[_.-](\w|$)/g, (_, x) => x.toUpperCase());
      map[name] = result;
      return result;
    }
  
    function createOverrideContext(bindingContext, parentOverrideContext) {
      return {
        bindingContext: bindingContext,
        parentOverrideContext: parentOverrideContext || null
      };
    }
  
    function getContextFor(name, scope, ancestor) {
      let oc = scope.overrideContext;
  
      if (ancestor) {
        while (ancestor && oc) {
          ancestor--;
          oc = oc.parentOverrideContext;
        }
        if (ancestor || !oc) {
          return undefined;
        }
        return name in oc ? oc : oc.bindingContext;
      }
  
      while (oc && !(name in oc) && !(oc.bindingContext && name in oc.bindingContext)) {
        oc = oc.parentOverrideContext;
      }
      if (oc) {
        return name in oc ? oc : oc.bindingContext;
      }
  
      return scope.bindingContext || scope.overrideContext;
    }
  
    function createScopeForTest(bindingContext, parentBindingContext) {
      if (parentBindingContext) {
        return {
          bindingContext,
          overrideContext: createOverrideContext(bindingContext, createOverrideContext(parentBindingContext))
        };
      }
      return {
        bindingContext,
        overrideContext: createOverrideContext(bindingContext)
      };
    }
  
    const slotNames = [];
    const versionSlotNames = [];
  
    for (let i = 0; i < 100; i++) {
      slotNames.push(`_observer${i}`);
      versionSlotNames.push(`_observerVersion${i}`);
    }
  
    function addObserver(observer) {
      let observerSlots = this._observerSlots === undefined ? 0 : this._observerSlots;
      let i = observerSlots;
      while (i-- && this[slotNames[i]] !== observer) {}
  
      if (i === -1) {
        i = 0;
        while (this[slotNames[i]]) {
          i++;
        }
        this[slotNames[i]] = observer;
        observer.subscribe(sourceContext, this);
  
        if (i === observerSlots) {
          this._observerSlots = i + 1;
        }
      }
  
      if (this._version === undefined) {
        this._version = 0;
      }
      this[versionSlotNames[i]] = this._version;
    }
  
    function observeProperty(obj, propertyName) {
      let observer = this.observerLocator.getObserver(obj, propertyName);
      addObserver.call(this, observer);
    }
  
    function observeArray(array) {
      let observer = this.observerLocator.getArrayObserver(array);
      addObserver.call(this, observer);
    }
  
    function unobserve(all) {
      let i = this._observerSlots;
      while (i--) {
        if (all || this[versionSlotNames[i]] !== this._version) {
          let observer = this[slotNames[i]];
          this[slotNames[i]] = null;
          if (observer) {
            observer.unsubscribe(sourceContext, this);
          }
        }
      }
    }
  
    function connectable() {
      return function (target) {
        target.prototype.observeProperty = observeProperty;
        target.prototype.observeArray = observeArray;
        target.prototype.unobserve = unobserve;
        target.prototype.addObserver = addObserver;
      };
    }
  
    const queue = [];
    const queued = {};
    let nextId = 0;
    let minimumImmediate = 100;
    const frameBudget = 15;
  
    let isFlushRequested = false;
    let immediate = 0;
  
    function flush(animationFrameStart) {
      const length = queue.length;
      let i = 0;
      while (i < length) {
        const binding = queue[i];
        queued[binding.__connectQueueId] = false;
        binding.connect(true);
        i++;
  
        if (i % 100 === 0 && PLATFORM.performance.now() - animationFrameStart > frameBudget) {
          break;
        }
      }
      queue.splice(0, i);
  
      if (queue.length) {
        PLATFORM.requestAnimationFrame(flush);
      } else {
        isFlushRequested = false;
        immediate = 0;
      }
    }
  
    function enqueueBindingConnect(binding) {
      if (immediate < minimumImmediate) {
        immediate++;
        binding.connect(false);
      } else {
        let id = binding.__connectQueueId;
        if (id === undefined) {
          id = nextId;
          nextId++;
          binding.__connectQueueId = id;
        }
  
        if (!queued[id]) {
          queue.push(binding);
          queued[id] = true;
        }
      }
      if (!isFlushRequested) {
        isFlushRequested = true;
        PLATFORM.requestAnimationFrame(flush);
      }
    }
  
    function setConnectQueueThreshold(value) {
      minimumImmediate = value;
    }
  
    function enableConnectQueue() {
      setConnectQueueThreshold(100);
    }
  
    function disableConnectQueue() {
      setConnectQueueThreshold(Number.MAX_SAFE_INTEGER);
    }
  
    function getConnectQueueSize() {
      return queue.length;
    }
  
    function addSubscriber(context, callable) {
      if (this.hasSubscriber(context, callable)) {
        return false;
      }
      if (!this._context0) {
        this._context0 = context;
        this._callable0 = callable;
        return true;
      }
      if (!this._context1) {
        this._context1 = context;
        this._callable1 = callable;
        return true;
      }
      if (!this._context2) {
        this._context2 = context;
        this._callable2 = callable;
        return true;
      }
      if (!this._contextsRest) {
        this._contextsRest = [context];
        this._callablesRest = [callable];
        return true;
      }
      this._contextsRest.push(context);
      this._callablesRest.push(callable);
      return true;
    }
  
    function removeSubscriber(context, callable) {
      if (this._context0 === context && this._callable0 === callable) {
        this._context0 = null;
        this._callable0 = null;
        return true;
      }
      if (this._context1 === context && this._callable1 === callable) {
        this._context1 = null;
        this._callable1 = null;
        return true;
      }
      if (this._context2 === context && this._callable2 === callable) {
        this._context2 = null;
        this._callable2 = null;
        return true;
      }
      const callables = this._callablesRest;
      if (callables === undefined || callables.length === 0) {
        return false;
      }
      const contexts = this._contextsRest;
      let i = 0;
      while (!(callables[i] === callable && contexts[i] === context) && callables.length > i) {
        i++;
      }
      if (i >= callables.length) {
        return false;
      }
      contexts.splice(i, 1);
      callables.splice(i, 1);
      return true;
    }
  
    let arrayPool1 = [];
    let arrayPool2 = [];
    let poolUtilization = [];
  
    function callSubscribers(newValue, oldValue) {
      let context0 = this._context0;
      let callable0 = this._callable0;
      let context1 = this._context1;
      let callable1 = this._callable1;
      let context2 = this._context2;
      let callable2 = this._callable2;
      let length = this._contextsRest ? this._contextsRest.length : 0;
      let contextsRest;
      let callablesRest;
      let poolIndex;
      let i;
      if (length) {
        poolIndex = poolUtilization.length;
        while (poolIndex-- && poolUtilization[poolIndex]) {}
        if (poolIndex < 0) {
          poolIndex = poolUtilization.length;
          contextsRest = [];
          callablesRest = [];
          poolUtilization.push(true);
          arrayPool1.push(contextsRest);
          arrayPool2.push(callablesRest);
        } else {
          poolUtilization[poolIndex] = true;
          contextsRest = arrayPool1[poolIndex];
          callablesRest = arrayPool2[poolIndex];
        }
  
        i = length;
        while (i--) {
          contextsRest[i] = this._contextsRest[i];
          callablesRest[i] = this._callablesRest[i];
        }
      }
  
      if (context0) {
        if (callable0) {
          callable0.call(context0, newValue, oldValue);
        } else {
          context0(newValue, oldValue);
        }
      }
      if (context1) {
        if (callable1) {
          callable1.call(context1, newValue, oldValue);
        } else {
          context1(newValue, oldValue);
        }
      }
      if (context2) {
        if (callable2) {
          callable2.call(context2, newValue, oldValue);
        } else {
          context2(newValue, oldValue);
        }
      }
      if (length) {
        for (i = 0; i < length; i++) {
          let callable = callablesRest[i];
          let context = contextsRest[i];
          if (callable) {
            callable.call(context, newValue, oldValue);
          } else {
            context(newValue, oldValue);
          }
          contextsRest[i] = null;
          callablesRest[i] = null;
        }
        poolUtilization[poolIndex] = false;
      }
    }
  
    function hasSubscribers() {
      return !!(this._context0 || this._context1 || this._context2 || this._contextsRest && this._contextsRest.length);
    }
  
    function hasSubscriber(context, callable) {
      let has = this._context0 === context && this._callable0 === callable || this._context1 === context && this._callable1 === callable || this._context2 === context && this._callable2 === callable;
      if (has) {
        return true;
      }
      let index;
      let contexts = this._contextsRest;
      if (!contexts || (index = contexts.length) === 0) {
        return false;
      }
      let callables = this._callablesRest;
      while (index--) {
        if (contexts[index] === context && callables[index] === callable) {
          return true;
        }
      }
      return false;
    }
  
    function subscriberCollection() {
      return function (target) {
        target.prototype.addSubscriber = addSubscriber;
        target.prototype.removeSubscriber = removeSubscriber;
        target.prototype.callSubscribers = callSubscribers;
        target.prototype.hasSubscribers = hasSubscribers;
        target.prototype.hasSubscriber = hasSubscriber;
      };
    }
  
    let ExpressionObserver = (_dec$1 = connectable(), _dec2$1 = subscriberCollection(), _dec$1(_class$1 = _dec2$1(_class$1 = class ExpressionObserver {
      constructor(scope, expression, observerLocator, lookupFunctions) {
        this.scope = scope;
        this.expression = expression;
        this.observerLocator = observerLocator;
        this.lookupFunctions = lookupFunctions;
      }
  
      getValue() {
        return this.expression.evaluate(this.scope, this.lookupFunctions);
      }
  
      setValue(newValue) {
        this.expression.assign(this.scope, newValue);
      }
  
      subscribe(context, callable) {
        if (!this.hasSubscribers()) {
          this.oldValue = this.expression.evaluate(this.scope, this.lookupFunctions);
          this.expression.connect(this, this.scope);
        }
        this.addSubscriber(context, callable);
        if (arguments.length === 1 && context instanceof Function) {
          return {
            dispose: () => {
              this.unsubscribe(context, callable);
            }
          };
        }
      }
  
      unsubscribe(context, callable) {
        if (this.removeSubscriber(context, callable) && !this.hasSubscribers()) {
          this.unobserve(true);
          this.oldValue = undefined;
        }
      }
  
      call() {
        let newValue = this.expression.evaluate(this.scope, this.lookupFunctions);
        let oldValue = this.oldValue;
        if (newValue !== oldValue) {
          this.oldValue = newValue;
          this.callSubscribers(newValue, oldValue);
        }
        this._version++;
        this.expression.connect(this, this.scope);
        this.unobserve(false);
      }
    }) || _class$1) || _class$1);
  
    function isIndex(s) {
      return +s === s >>> 0;
    }
  
    function toNumber(s) {
      return +s;
    }
  
    function newSplice(index, removed, addedCount) {
      return {
        index: index,
        removed: removed,
        addedCount: addedCount
      };
    }
  
    const EDIT_LEAVE = 0;
    const EDIT_UPDATE = 1;
    const EDIT_ADD = 2;
    const EDIT_DELETE = 3;
  
    function ArraySplice() {}
  
    ArraySplice.prototype = {
      calcEditDistances: function (current, currentStart, currentEnd, old, oldStart, oldEnd) {
        let rowCount = oldEnd - oldStart + 1;
        let columnCount = currentEnd - currentStart + 1;
        let distances = new Array(rowCount);
        let north;
        let west;
  
        for (let i = 0; i < rowCount; ++i) {
          distances[i] = new Array(columnCount);
          distances[i][0] = i;
        }
  
        for (let j = 0; j < columnCount; ++j) {
          distances[0][j] = j;
        }
  
        for (let i = 1; i < rowCount; ++i) {
          for (let 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 {
              north = distances[i - 1][j] + 1;
              west = distances[i][j - 1] + 1;
              distances[i][j] = north < west ? north : west;
            }
          }
        }
  
        return distances;
      },
  
      spliceOperationsFromEditDistances: function (distances) {
        let i = distances.length - 1;
        let j = distances[0].length - 1;
        let current = distances[i][j];
        let edits = [];
        while (i > 0 || j > 0) {
          if (i === 0) {
            edits.push(EDIT_ADD);
            j--;
            continue;
          }
          if (j === 0) {
            edits.push(EDIT_DELETE);
            i--;
            continue;
          }
          let northWest = distances[i - 1][j - 1];
          let west = distances[i - 1][j];
          let north = distances[i][j - 1];
  
          let 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) {
        let prefixCount = 0;
        let suffixCount = 0;
  
        let 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) {
          let splice = newSplice(currentStart, [], 0);
          while (oldStart < oldEnd) {
            splice.removed.push(old[oldStart++]);
          }
  
          return [splice];
        } else if (oldStart === oldEnd) {
          return [newSplice(currentStart, [], currentEnd - currentStart)];
        }
  
        let ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));
  
        let splice = undefined;
        let splices = [];
        let index = currentStart;
        let oldIndex = oldStart;
        for (let 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 (let i = 0; i < searchLength; ++i) {
          if (!this.equals(current[i], old[i])) {
            return i;
          }
        }
  
        return searchLength;
      },
  
      sharedSuffix: function (current, old, searchLength) {
        let index1 = current.length;
        let index2 = old.length;
        let 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;
      }
    };
  
    let arraySplice = new ArraySplice();
  
    function calcSplices(current, currentStart, currentEnd, old, oldStart, oldEnd) {
      return arraySplice.calcSplices(current, currentStart, currentEnd, old, oldStart, oldEnd);
    }
  
    function intersect(start1, end1, start2, end2) {
      if (end1 < start2 || end2 < start1) {
        return -1;
      }
  
      if (end1 === start2 || end2 === start1) {
        return 0;
      }
  
      if (start1 < start2) {
        if (end1 < end2) {
          return end1 - start2;
        }
  
        return end2 - start2;
      }
  
      if (end2 < end1) {
        return end2 - start1;
      }
  
      return end1 - start1;
    }
  
    function mergeSplice(splices, index, removed, addedCount) {
      let splice = newSplice(index, removed, addedCount);
  
      let inserted = false;
      let insertionOffset = 0;
  
      for (let i = 0; i < splices.length; i++) {
        let current = splices[i];
        current.index += insertionOffset;
  
        if (inserted) {
          continue;
        }
  
        let intersectCount = intersect(splice.index, splice.index + splice.removed.length, current.index, current.index + current.addedCount);
  
        if (intersectCount >= 0) {
  
          splices.splice(i, 1);
          i--;
  
          insertionOffset -= current.addedCount - current.removed.length;
  
          splice.addedCount += current.addedCount - intersectCount;
          let deleteCount = splice.removed.length + current.removed.length - intersectCount;
  
          if (!splice.addedCount && !deleteCount) {
            inserted = true;
          } else {
            let currentRemoved = current.removed;
  
            if (splice.index < current.index) {
              let prepend = splice.removed.slice(0, current.index - splice.index);
              Array.prototype.push.apply(prepend, currentRemoved);
              currentRemoved = prepend;
            }
  
            if (splice.index + splice.removed.length > current.index + current.addedCount) {
              let append = splice.removed.slice(current.index + current.addedCount - splice.index);
              Array.prototype.push.apply(currentRemoved, append);
            }
  
            splice.removed = currentRemoved;
            if (current.index < splice.index) {
              splice.index = current.index;
            }
          }
        } else if (splice.index < current.index) {
  
          inserted = true;
  
          splices.splice(i, 0, splice);
          i++;
  
          let offset = splice.addedCount - splice.removed.length;
          current.index += offset;
          insertionOffset += offset;
        }
      }
  
      if (!inserted) {
        splices.push(splice);
      }
    }
  
    function createInitialSplices(array, changeRecords) {
      let splices = [];
  
      for (let i = 0; i < changeRecords.length; i++) {
        let record = changeRecords[i];
        switch (record.type) {
          case 'splice':
            mergeSplice(splices, record.index, record.removed.slice(), record.addedCount);
            break;
          case 'add':
          case 'update':
          case 'delete':
            if (!isIndex(record.name)) {
              continue;
            }
  
            let index = toNumber(record.name);
            if (index < 0) {
              continue;
            }
  
            mergeSplice(splices, index, [record.oldValue], record.type === 'delete' ? 0 : 1);
            break;
          default:
            console.error('Unexpected record type: ' + JSON.stringify(record));
            break;
        }
      }
  
      return splices;
    }
  
    function projectArraySplices(array, changeRecords) {
      let splices = [];
  
      createInitialSplices(array, changeRecords).forEach(function (splice) {
        if (splice.addedCount === 1 && splice.removed.length === 1) {
          if (splice.removed[0] !== array[splice.index]) {
            splices.push(splice);
          }
  
          return;
        }
  
        splices = splices.concat(calcSplices(array, splice.index, splice.index + splice.addedCount, splice.removed, 0, splice.removed.length));
      });
  
      return splices;
    }
  
    function newRecord(type, object, key, oldValue) {
      return {
        type: type,
        object: object,
        key: key,
        oldValue: oldValue
      };
    }
  
    function getChangeRecords(map) {
      let entries = new Array(map.size);
      let keys = map.keys();
      let i = 0;
      let item;
  
      while (item = keys.next()) {
        if (item.done) {
          break;
        }
  
        entries[i] = newRecord('added', map, item.value);
        i++;
      }
  
      return entries;
    }
  
    let ModifyCollectionObserver = (_dec3$1 = subscriberCollection(), _dec3$1(_class2$1 = class ModifyCollectionObserver {
      constructor(taskQueue, collection) {
        this.taskQueue = taskQueue;
        this.queued = false;
        this.changeRecords = null;
        this.oldCollection = null;
        this.collection = collection;
        this.lengthPropertyName = collection instanceof Map || collection instanceof Set ? 'size' : 'length';
      }
  
      subscribe(context, callable) {
        this.addSubscriber(context, callable);
      }
  
      unsubscribe(context, callable) {
        this.removeSubscriber(context, callable);
      }
  
      addChangeRecord(changeRecord) {
        if (!this.hasSubscribers() && !this.lengthObserver) {
          return;
        }
  
        if (changeRecord.type === 'splice') {
          let index = changeRecord.index;
          let arrayLength = changeRecord.object.length;
          if (index > arrayLength) {
            index = arrayLength - changeRecord.addedCount;
          } else if (index < 0) {
            index = arrayLength + changeRecord.removed.length + index - changeRecord.addedCount;
          }
          if (index < 0) {
            index = 0;
          }
          changeRecord.index = index;
        }
  
        if (this.changeRecords === null) {
          this.changeRecords = [changeRecord];
        } else {
          this.changeRecords.push(changeRecord);
        }
  
        if (!this.queued) {
          this.queued = true;
          this.taskQueue.queueMicroTask(this);
        }
      }
  
      flushChangeRecords() {
        if (this.changeRecords && this.changeRecords.length || this.oldCollection) {
          this.call();
        }
      }
  
      reset(oldCollection) {
        this.oldCollection = oldCollection;
  
        if (this.hasSubscribers() && !this.queued) {
          this.queued = true;
          this.taskQueue.queueMicroTask(this);
        }
      }
  
      getLengthObserver() {
        return this.lengthObserver || (this.lengthObserver = new CollectionLengthObserver(this.collection));
      }
  
      call() {
        let changeRecords = this.changeRecords;
        let oldCollection = this.oldCollection;
        let records;
  
        this.queued = false;
        this.changeRecords = [];
        this.oldCollection = null;
  
        if (this.hasSubscribers()) {
          if (oldCollection) {
            if (this.collection instanceof Map || this.collection instanceof Set) {
              records = getChangeRecords(oldCollection);
            } else {
              records = calcSplices(this.collection, 0, this.collection.length, oldCollection, 0, oldCollection.length);
            }
          } else {
            if (this.collection instanceof Map || this.collection instanceof Set) {
              records = changeRecords;
            } else {
              records = projectArraySplices(this.collection, changeRecords);
            }
          }
  
          this.callSubscribers(records);
        }
  
        if (this.lengthObserver) {
          this.lengthObserver.call(this.collection[this.lengthPropertyName]);
        }
      }
    }) || _class2$1);
  
    let CollectionLengthObserver = (_dec4$1 = subscriberCollection(), _dec4$1(_class3$1 = class CollectionLengthObserver {
      constructor(collection) {
        this.collection = collection;
        this.lengthPropertyName = collection instanceof Map || collection instanceof Set ? 'size' : 'length';
        this.currentValue = collection[this.lengthPropertyName];
      }
  
      getValue() {
        return this.collection[this.lengthPropertyName];
      }
  
      setValue(newValue) {
        this.collection[this.lengthPropertyName] = newValue;
      }
  
      subscribe(context, callable) {
        this.addSubscriber(context, callable);
      }
  
      unsubscribe(context, callable) {
        this.removeSubscriber(context, callable);
      }
  
      call(newValue) {
        let oldValue = this.currentValue;
        this.callSubscribers(newValue, oldValue);
        this.currentValue = newValue;
      }
    }) || _class3$1);
  
    const arrayProto = Array.prototype;
    const pop = arrayProto.pop;
    const push = arrayProto.push;
    const reverse = arrayProto.reverse;
    const shift = arrayProto.shift;
    const sort = arrayProto.sort;
    const splice = arrayProto.splice;
    const unshift = arrayProto.unshift;
  
    if (arrayProto.__au_patched__) {
      getLogger('array-observation').warn('Detected 2nd attempt of patching array from Aurelia binding.' + ' This is probably caused by dependency mismatch between core modules and a 3rd party plugin.' + ' Please see https://github.com/aurelia/cli/pull/906 if you are using webpack.');
    } else {
      Reflect.defineProperty(arrayProto, '__au_patched__', { value: 1 });
      arrayProto.pop = function () {
        let notEmpty = this.length > 0;
        let methodCallResult = pop.apply(this, arguments);
        if (notEmpty && this.__array_observer__ !== undefined) {
          this.__array_observer__.addChangeRecord({
            type: 'delete',
            object: this,
            name: this.length,
            oldValue: methodCallResult
          });
        }
        return methodCallResult;
      };
  
      arrayProto.push = function () {
        let methodCallResult = push.apply(this, arguments);
        if (this.__array_observer__ !== undefined) {
          this.__array_observer__.addChangeRecord({
            type: 'splice',
            object: this,
            index: this.length - arguments.length,
            removed: [],
            addedCount: arguments.length
          });
        }
        return methodCallResult;
      };
  
      arrayProto.reverse = function () {
        let oldArray;
        if (this.__array_observer__ !== undefined) {
          this.__array_observer__.flushChangeRecords();
          oldArray = this.slice();
        }
        let methodCallResult = reverse.apply(this, arguments);
        if (this.__array_observer__ !== undefined) {
          this.__array_observer__.reset(oldArray);
        }
        return methodCallResult;
      };
  
      arrayProto.shift = function () {
        let notEmpty = this.length > 0;
        let methodCallResult = shift.apply(this, arguments);
        if (notEmpty && this.__array_observer__ !== undefined) {
          this.__array_observer__.addChangeRecord({
            type: 'delete',
            object: this,
            name: 0,
            oldValue: methodCallResult
          });
        }
        return methodCallResult;
      };
  
      arrayProto.sort = function () {
        let oldArray;
        if (this.__array_observer__ !== undefined) {
          this.__array_observer__.flushChangeRecords();
          oldArray = this.slice();
        }
        let methodCallResult = sort.apply(this, arguments);
        if (this.__array_observer__ !== undefined) {
          this.__array_observer__.reset(oldArray);
        }
        return methodCallResult;
      };
  
      arrayProto.splice = function () {
        let methodCallResult = splice.apply(this, arguments);
        if (this.__array_observer__ !== undefined) {
          this.__array_observer__.addChangeRecord({
            type: 'splice',
            object: this,
            index: +arguments[0],
            removed: methodCallResult,
            addedCount: arguments.length > 2 ? arguments.length - 2 : 0
          });
        }
        return methodCallResult;
      };
  
      arrayProto.unshift = function () {
        let methodCallResult = unshift.apply(this, arguments);
        if (this.__array_observer__ !== undefined) {
          this.__array_observer__.addChangeRecord({
            type: 'splice',
            object: this,
            index: 0,
            removed: [],
            addedCount: arguments.length
          });
        }
        return methodCallResult;
      };
    }
  
    function getArrayObserver(taskQueue, array) {
      return ModifyArrayObserver.for(taskQueue, array);
    }
  
    let ModifyArrayObserver = class ModifyArrayObserver extends ModifyCollectionObserver {
      constructor(taskQueue, array) {
        super(taskQueue, array);
      }
  
      static for(taskQueue, array) {
        if (!('__array_observer__' in array)) {
          Reflect.defineProperty(array, '__array_observer__', {
            value: ModifyArrayObserver.create(taskQueue, array),
            enumerable: false, configurable: false
          });
        }
        return array.__array_observer__;
      }
  
      static create(taskQueue, array) {
        return new ModifyArrayObserver(taskQueue, array);
      }
    };
  
  
    let Expression = class Expression {
      constructor() {
        this.isAssignable = false;
      }
  
      evaluate(scope, lookupFunctions, args) {
        throw new Error(`Binding expression "${this}" cannot be evaluated.`);
      }
  
      assign(scope, value, lookupFunctions) {
        throw new Error(`Binding expression "${this}" cannot be assigned to.`);
      }
  
      toString() {
        return  super.toString();
      }
    };
  
    let BindingBehavior = class BindingBehavior extends Expression {
      constructor(expression, name, args) {
        super();
  
        this.expression = expression;
        this.name = name;
        this.args = args;
      }
  
      evaluate(scope, lookupFunctions) {
        return this.expression.evaluate(scope, lookupFunctions);
      }
  
      assign(scope, value, lookupFunctions) {
        return this.expression.assign(scope, value, lookupFunctions);
      }
  
      accept(visitor) {
        return visitor.visitBindingBehavior(this);
      }
  
      connect(binding, scope) {
        this.expression.connect(binding, scope);
      }
  
      bind(binding, scope, lookupFunctions) {
        if (this.expression.expression && this.expression.bind) {
          this.expression.bind(binding, scope, lookupFunctions);
        }
        let behavior = lookupFunctions.bindingBehaviors(this.name);
        if (!behavior) {
          throw new Error(`No BindingBehavior named "${this.name}" was found!`);
        }
        let behaviorKey = `behavior-${this.name}`;
        if (binding[behaviorKey]) {
          throw new Error(`A binding behavior named "${this.name}" has already been applied to "${this.expression}"`);
        }
        binding[behaviorKey] = behavior;
        behavior.bind.apply(behavior, [binding, scope].concat(evalList(scope, this.args, binding.lookupFunctions)));
      }
  
      unbind(binding, scope) {
        let behaviorKey = `behavior-${this.name}`;
        binding[behaviorKey].unbind(binding, scope);
        binding[behaviorKey] = null;
        if (this.expression.expression && this.expression.unbind) {
          this.expression.unbind(binding, scope);
        }
      }
    };
  
    let ValueConverter = class ValueConverter extends Expression {
      constructor(expression, name, args) {
        super();
  
        this.expression = expression;
        this.name = name;
        this.args = args;
        this.allArgs = [expression].concat(args);
      }
  
      evaluate(scope, lookupFunctions) {
        let converter = lookupFunctions.valueConverters(this.name);
        if (!converter) {
          throw new Error(`No ValueConverter named "${this.name}" was found!`);
        }
  
        if ('toView' in converter) {
          return converter.toView.apply(converter, evalList(scope, this.allArgs, lookupFunctions));
        }
  
        return this.allArgs[0].evaluate(scope, lookupFunctions);
      }
  
      assign(scope, value, lookupFunctions) {
        let converter = lookupFunctions.valueConverters(this.name);
        if (!converter) {
          throw new Error(`No ValueConverter named "${this.name}" was found!`);
        }
  
        if ('fromView' in converter) {
          value = converter.fromView.apply(converter, [value].concat(evalList(scope, this.args, lookupFunctions)));
        }
  
        return this.allArgs[0].assign(scope, value, lookupFunctions);
      }
  
      accept(visitor) {
        return visitor.visitValueConverter(this);
      }
  
      connect(binding, scope) {
        let expressions = this.allArgs;
        let i = expressions.length;
        while (i--) {
          expressions[i].connect(binding, scope);
        }
        let converter = binding.lookupFunctions.valueConverters(this.name);
        if (!converter) {
          throw new Error(`No ValueConverter named "${this.name}" was found!`);
        }
        let signals = converter.signals;
        if (signals === undefined) {
          return;
        }
        i = signals.length;
        while (i--) {
          connectBindingToSignal(binding, signals[i]);
        }
      }
    };
  
    let Assign = class Assign extends Expression {
      constructor(target, value) {
        super();
  
        this.target = target;
        this.value = value;
        this.isAssignable = true;
      }
  
      evaluate(scope, lookupFunctions) {
        return this.target.assign(scope, this.value.evaluate(scope, lookupFunctions));
      }
  
      accept(vistor) {
        vistor.visitAssign(this);
      }
  
      connect(binding, scope) {}
  
      assign(scope, value) {
        this.value.assign(scope, value);
        this.target.assign(scope, value);
      }
    };
  
    let Conditional = class Conditional extends Expression {
      constructor(condition, yes, no) {
        super();
  
        this.condition = condition;
        this.yes = yes;
        this.no = no;
      }
  
      evaluate(scope, lookupFunctions) {
        return !!this.condition.evaluate(scope, lookupFunctions) ? this.yes.evaluate(scope, lookupFunctions) : this.no.evaluate(scope, lookupFunctions);
      }
  
      accept(visitor) {
        return visitor.visitConditional(this);
      }
  
      connect(binding, scope) {
        this.condition.connect(binding, scope);
        if (this.condition.evaluate(scope)) {
          this.yes.connect(binding, scope);
        } else {
          this.no.connect(binding, scope);
        }
      }
    };
  
    let AccessThis = class AccessThis extends Expression {
      constructor(ancestor) {
        super();
        this.ancestor = ancestor;
      }
  
      evaluate(scope, lookupFunctions) {
        let oc = scope.overrideContext;
        let i = this.ancestor;
        while (i-- && oc) {
          oc = oc.parentOverrideContext;
        }
        return i < 1 && oc ? oc.bindingContext : undefined;
      }
  
      accept(visitor) {
        return visitor.visitAccessThis(this);
      }
  
      connect(binding, scope) {}
    };
  
    let AccessScope = class AccessScope extends Expression {
      constructor(name, ancestor) {
        super();
  
        this.name = name;
        this.ancestor = ancestor;
        this.isAssignable = true;
      }
  
      evaluate(scope, lookupFunctions) {
        let context = getContextFor(this.name, scope, this.ancestor);
        return context[this.name];
      }
  
      assign(scope, value) {
        let context = getContextFor(this.name, scope, this.ancestor);
        return context ? context[this.name] = value : undefined;
      }
  
      accept(visitor) {
        return visitor.visitAccessScope(this);
      }
  
      connect(binding, scope) {
        let context = getContextFor(this.name, scope, this.ancestor);
        binding.observeProperty(context, this.name);
      }
    };
  
    let AccessMember = class AccessMember extends Expression {
      constructor(object, name) {
        super();
  
        this.object = object;
        this.name = name;
        this.isAssignable = true;
      }
  
      evaluate(scope, lookupFunctions) {
        let instance = this.object.evaluate(scope, lookupFunctions);
        return instance === null || instance === undefined ? instance : instance[this.name];
      }
  
      assign(scope, value) {
        let instance = this.object.evaluate(scope);
  
        if (instance === null || instance === undefined) {
          instance = {};
          this.object.assign(scope, instance);
        }
  
        instance[this.name] = value;
        return value;
      }
  
      accept(visitor) {
        return visitor.visitAccessMember(this);
      }
  
      connect(binding, scope) {
        this.object.connect(binding, scope);
        let obj = this.object.evaluate(scope);
        if (obj) {
          binding.observeProperty(obj, this.name);
        }
      }
    };
  
    let AccessKeyed = class AccessKeyed extends Expression {
      constructor(object, key) {
        super();
  
        this.object = object;
        this.key = key;
        this.isAssignable = true;
      }
  
      evaluate(scope, lookupFunctions) {
        let instance = this.object.evaluate(scope, lookupFunctions);
        let lookup = this.key.evaluate(scope, lookupFunctions);
        return getKeyed(instance, lookup);
      }
  
      assign(scope, value) {
        let instance = this.object.evaluate(scope);
        let lookup = this.key.evaluate(scope);
        return setKeyed(instance, lookup, value);
      }
  
      accept(visitor) {
        return visitor.visitAccessKeyed(this);
      }
  
      connect(binding, scope) {
        this.object.connect(binding, scope);
        let obj = this.object.evaluate(scope);
        if (obj instanceof Object) {
          this.key.connect(binding, scope);
          let key = this.key.evaluate(scope);
  
          if (key !== null && key !== undefined && !(Array.isArray(obj) && typeof key === 'number')) {
            binding.observeProperty(obj, key);
          }
        }
      }
    };
  
    let CallScope = class CallScope extends Expression {
      constructor(name, args, ancestor) {
        super();
  
        this.name = name;
        this.args = args;
        this.ancestor = ancestor;
      }
  
      evaluate(scope, lookupFunctions, mustEvaluate) {
        let args = evalList(scope, this.args, lookupFunctions);
        let context = getContextFor(this.name, scope, this.ancestor);
        let func = getFunction(context, this.name, mustEvaluate);
        if (func) {
          return func.apply(context, args);
        }
        return undefined;
      }
  
      accept(visitor) {
        return visitor.visitCallScope(this);
      }
  
      connect(binding, scope) {
        let args = this.args;
        let i = args.length;
        while (i--) {
          args[i].connect(binding, scope);
        }
      }
    };
  
    let CallMember = class CallMember extends Expression {
      constructor(object, name, args) {
        super();
  
        this.object = object;
        this.name = name;
        this.args = args;
      }
  
      evaluate(scope, lookupFunctions, mustEvaluate) {
        let instance = this.object.evaluate(scope, lookupFunctions);
        let args = evalList(scope, this.args, lookupFunctions);
        let func = getFunction(instance, this.name, mustEvaluate);
        if (func) {
          return func.apply(instance, args);
        }
        return undefined;
      }
  
      accept(visitor) {
        return visitor.visitCallMember(this);
      }
  
      connect(binding, scope) {
        this.object.connect(binding, scope);
        let obj = this.object.evaluate(scope);
        if (getFunction(obj, this.name, false)) {
          let args = this.args;
          let i = args.length;
          while (i--) {
            args[i].connect(binding, scope);
          }
        }
      }
    };
  
    let CallFunction = class CallFunction extends Expression {
      constructor(func, args) {
        super();
  
        this.func = func;
        this.args = args;
      }
  
      evaluate(scope, lookupFunctions, mustEvaluate) {
        let func = this.func.evaluate(scope, lookupFunctions);
        if (typeof func === 'function') {
          return func.apply(null, evalList(scope, this.args, lookupFunctions));
        }
        if (!mustEvaluate && (func === null || func === undefined)) {
          return undefined;
        }
        throw new Error(`${this.func} is not a function`);
      }
  
      accept(visitor) {
        return visitor.visitCallFunction(this);
      }
  
      connect(binding, scope) {
        this.func.connect(binding, scope);
        let func = this.func.evaluate(scope);
        if (typeof func === 'function') {
          let args = this.args;
          let i = args.length;
          while (i--) {
            args[i].connect(binding, scope);
          }
        }
      }
    };
  
    let Binary = class Binary extends Expression {
      constructor(operation, left, right) {
        super();
  
        this.operation = operation;
        this.left = left;
        this.right = right;
      }
  
      evaluate(scope, lookupFunctions) {
        let left = this.left.evaluate(scope, lookupFunctions);
  
        switch (this.operation) {
          case '&&':
            return left && this.right.evaluate(scope, lookupFunctions);
          case '||':
            return left || this.right.evaluate(scope, lookupFunctions);
        }
  
        let right = this.right.evaluate(scope, lookupFunctions);
  
        switch (this.operation) {
          case '==':
            return left == right;
          case '===':
            return left === right;
          case '!=':
            return left != right;
          case '!==':
            return left !== right;
          case 'instanceof':
            return typeof right === 'function' && left instanceof right;
          case 'in':
            return typeof right === 'object' && right !== null && left in right;
        }
  
        if (left === null || right === null || left === undefined || right === undefined) {
          switch (this.operation) {
            case '+':
              if (left !== null && left !== undefined) return left;
              if (right !== null && right !== undefined) return right;
              return 0;
            case '-':
              if (left !== null && left !== undefined) return left;
              if (right !== null && right !== undefined) return 0 - right;
              return 0;
          }
  
          return null;
        }
  
        switch (this.operation) {
          case '+':
            return autoConvertAdd(left, right);
          case '-':
            return left - right;
          case '*':
            return left * right;
          case '/':
            return left / right;
          case '%':
            return left % right;
          case '<':
            return left < right;
          case '>':
            return left > right;
          case '<=':
            return left <= right;
          case '>=':
            return left >= right;
          case '^':
            return left ^ right;
        }
  
        throw new Error(`Internal error [${this.operation}] not handled`);
      }
  
      accept(visitor) {
        return visitor.visitBinary(this);
      }
  
      connect(binding, scope) {
        this.left.connect(binding, scope);
        let left = this.left.evaluate(scope);
        if (this.operation === '&&' && !left || this.operation === '||' && left) {
          return;
        }
        this.right.connect(binding, scope);
      }
    };
  
    let Unary = class Unary extends Expression {
      constructor(operation, expression) {
        super();
  
        this.operation = operation;
        this.expression = expression;
      }
  
      evaluate(scope, lookupFunctions) {
        switch (this.operation) {
          case '!':
            return !this.expression.evaluate(scope, lookupFunctions);
          case 'typeof':
            return typeof this.expression.evaluate(scope, lookupFunctions);
          case 'void':
            return void this.expression.evaluate(scope, lookupFunctions);
        }
  
        throw new Error(`Internal error [${this.operation}] not handled`);
      }
  
      accept(visitor) {
        return visitor.visitPrefix(this);
      }
  
      connect(binding, scope) {
        this.expression.connect(binding, scope);
      }
    };
  
    let LiteralPrimitive = class LiteralPrimitive extends Expression {
      constructor(value) {
        super();
  
        this.value = value;
      }
  
      evaluate(scope, lookupFunctions) {
        return this.value;
      }
  
      accept(visitor) {
        return visitor.visitLiteralPrimitive(this);
      }
  
      connect(binding, scope) {}
    };
  
    let LiteralString = class LiteralString extends Expression {
      constructor(value) {
        super();
  
        this.value = value;
      }
  
      evaluate(scope, lookupFunctions) {
        return this.value;
      }
  
      accept(visitor) {
        return visitor.visitLiteralString(this);
      }
  
      connect(binding, scope) {}
    };
  
    let LiteralTemplate = class LiteralTemplate extends Expression {
      constructor(cooked, expressions, raw, tag) {
        super();
        this.cooked = cooked;
        this.expressions = expressions || [];
        this.length = this.expressions.length;
        this.tagged = tag !== undefined;
        if (this.tagged) {
          this.cooked.raw = raw;
          this.tag = tag;
          if (tag instanceof AccessScope) {
            this.contextType = 'Scope';
          } else if (tag instanceof AccessMember || tag instanceof AccessKeyed) {
            this.contextType = 'Object';
          } else {
            throw new Error(`${this.tag} is not a valid template tag`);
          }
        }
      }
  
      getScopeContext(scope, lookupFunctions) {
        return getContextFor(this.tag.name, scope, this.tag.ancestor);
      }
  
      getObjectContext(scope, lookupFunctions) {
        return this.tag.object.evaluate(scope, lookupFunctions);
      }
  
      evaluate(scope, lookupFunctions, mustEvaluate) {
        const results = new Array(this.length);
        for (let i = 0; i < this.length; i++) {
          results[i] = this.expressions[i].evaluate(scope, lookupFunctions);
        }
        if (this.tagged) {
          const func = this.tag.evaluate(scope, lookupFunctions);
          if (typeof func === 'function') {
            const context = this[`get${this.contextType}Context`](scope, lookupFunctions);
            return func.call(context, this.cooked, ...results);
          }
          if (!mustEvaluate) {
            return null;
          }
          throw new Error(`${this.tag} is not a function`);
        }
        let result = this.cooked[0];
        for (let i = 0; i < this.length; i++) {
          result = String.prototype.concat(result, results[i], this.cooked[i + 1]);
        }
        return result;
      }
  
      accept(visitor) {
        return visitor.visitLiteralTemplate(this);
      }
  
      connect(binding, scope) {
        for (let i = 0; i < this.length; i++) {
          this.expressions[i].connect(binding, scope);
        }
        if (this.tagged) {
          this.tag.connect(binding, scope);
        }
      }
    };
  
    let LiteralArray = class LiteralArray extends Expression {
      constructor(elements) {
        super();
  
        this.elements = elements;
      }
  
      evaluate(scope, lookupFunctions) {
        let elements = this.elements;
        let result = [];
  
        for (let i = 0, length = elements.length; i < length; ++i) {
          result[i] = elements[i].evaluate(scope, lookupFunctions);
        }
  
        return result;
      }
  
      accept(visitor) {
        return visitor.visitLiteralArray(this);
      }
  
      connect(binding, scope) {
        let length = this.elements.length;
        for (let i = 0; i < length; i++) {
          this.elements[i].connect(binding, scope);
        }
      }
    };
  
    let LiteralObject = class LiteralObject extends Expression {
      constructor(keys, values) {
        super();
  
        this.keys = keys;
        this.values = values;
      }
  
      evaluate(scope, lookupFunctions) {
        let instance = {};
        let keys = this.keys;
        let values = this.values;
  
        for (let i = 0, length = keys.length; i < length; ++i) {
          instance[keys[i]] = values[i].evaluate(scope, lookupFunctions);
        }
  
        return instance;
      }
  
      accept(visitor) {
        return visitor.visitLiteralObject(this);
      }
  
      connect(binding, scope) {
        let length = this.keys.length;
        for (let i = 0; i < length; i++) {
          this.values[i].connect(binding, scope);
        }
      }
    };
  
    function evalList(scope, list, lookupFunctions) {
      const length = list.length;
      const result = [];
      for (let i = 0; i < length; i++) {
        result[i] = list[i].evaluate(scope, lookupFunctions);
      }
      return result;
    }
  
    function autoConvertAdd(a, b) {
      if (a !== null && b !== null) {
        if (typeof a === 'string' && typeof b !== 'string') {
          return a + b.toString();
        }
  
        if (typeof a !== 'string' && typeof b === 'string') {
          return a.toString() + b;
        }
  
        return a + b;
      }
  
      if (a !== null) {
        return a;
      }
  
      if (b !== null) {
        return b;
      }
  
      return 0;
    }
  
    function getFunction(obj, name, mustExist) {
      let func = obj === null || obj === undefined ? null : obj[name];
      if (typeof func === 'function') {
        return func;
      }
      if (!mustExist && (func === null || func === undefined)) {
        return null;
      }
      throw new Error(`${name} is not a function`);
    }
  
    function getKeyed(obj, key) {
      if (Array.isArray(obj)) {
        return obj[parseInt(key, 10)];
      } else if (obj) {
        return obj[key];
      } else if (obj === null || obj === undefined) {
        return undefined;
      }
  
      return obj[key];
    }
  
    function setKeyed(obj, key, value) {
      if (Array.isArray(obj)) {
        let index = parseInt(key, 10);
  
        if (obj.length <= index) {
          obj.length = index + 1;
        }
  
        obj[index] = value;
      } else {
        obj[key] = value;
      }
  
      return value;
    }
  
    exports.Unparser = null;
  
    let ExpressionCloner = class ExpressionCloner {
      cloneExpressionArray(array) {
        let clonedArray = [];
        let i = array.length;
        while (i--) {
          clonedArray[i] = array[i].accept(this);
        }
        return clonedArray;
      }
  
      visitBindingBehavior(behavior) {
        return new BindingBehavior(behavior.expression.accept(this), behavior.name, this.cloneExpressionArray(behavior.args));
      }
  
      visitValueConverter(converter) {
        return new ValueConverter(converter.expression.accept(this), converter.name, this.cloneExpressionArray(converter.args));
      }
  
      visitAssign(assign) {
        return new Assign(assign.target.accept(this), assign.value.accept(this));
      }
  
      visitConditional(conditional) {
        return new Conditional(conditional.condition.accept(this), conditional.yes.accept(this), conditional.no.accept(this));
      }
  
      visitAccessThis(access) {
        return new AccessThis(access.ancestor);
      }
  
      visitAccessScope(access) {
        return new AccessScope(access.name, access.ancestor);
      }
  
      visitAccessMember(access) {
        return new AccessMember(access.object.accept(this), access.name);
      }
  
      visitAccessKeyed(access) {
        return new AccessKeyed(access.object.accept(this), access.key.accept(this));
      }
  
      visitCallScope(call) {
        return new CallScope(call.name, this.cloneExpressionArray(call.args), call.ancestor);
      }
  
      visitCallFunction(call) {
        return new CallFunction(call.func.accept(this), this.cloneExpressionArray(call.args));
      }
  
      visitCallMember(call) {
        return new CallMember(call.object.accept(this), call.name, this.cloneExpressionArray(call.args));
      }
  
      visitUnary(unary) {
        return new Unary(prefix.operation, prefix.expression.accept(this));
      }
  
      visitBinary(binary) {
        return new Binary(binary.operation, binary.left.accept(this), binary.right.accept(this));
      }
  
      visitLiteralPrimitive(literal) {
        return new LiteralPrimitive(literal);
      }
  
      visitLiteralArray(literal) {
        return new LiteralArray(this.cloneExpressionArray(literal.elements));
      }
  
      visitLiteralObject(literal) {
        return new LiteralObject(literal.keys, this.cloneExpressionArray(literal.values));
      }
  
      visitLiteralString(literal) {
        return new LiteralString(literal.value);
      }
  
      visitLiteralTemplate(literal) {
        return new LiteralTemplate(literal.cooked, this.cloneExpressionArray(literal.expressions), literal.raw, literal.tag && literal.tag.accept(this));
      }
    };
  
    function cloneExpression(expression) {
      let visitor = new ExpressionCloner();
      return expression.accept(visitor);
    }
  
    const bindingMode = {
      oneTime: 0,
      toView: 1,
      oneWay: 1,
      twoWay: 2,
      fromView: 3
    };
  
    let Parser = class Parser {
      constructor() {
        this.cache = Object.create(null);
      }
  
      parse(src) {
        src = src || '';
  
        return this.cache[src] || (this.cache[src] = new ParserImplementation(src).parseBindingBehavior());
      }
    };
  
    const fromCharCode = String.fromCharCode;
  
    let ParserImplementation = class ParserImplementation {
      get raw() {
        return this.src.slice(this.start, this.idx);
      }
  
      constructor(src) {
        this.idx = 0;
  
        this.start = 0;
  
        this.src = src;
        this.len = src.length;
  
        this.tkn = T$EOF;
  
        this.val = undefined;
  
        this.ch = src.charCodeAt(0);
      }
  
      parseBindingBehavior() {
        this.nextToken();
        if (this.tkn & T$ExpressionTerminal) {
          this.err('Invalid start of expression');
        }
        let result = this.parseValueConverter();
        while (this.opt(T$Ampersand)) {
          result = new BindingBehavior(result, this.val, this.parseVariadicArgs());
        }
        if (this.tkn !== T$EOF) {
          this.err(`Unconsumed token ${this.raw}`);
        }
        return result;
      }
  
      parseValueConverter() {
        let result = this.parseExpression();
        while (this.opt(T$Bar)) {
          result = new ValueConverter(result, this.val, this.parseVariadicArgs());
        }
        return result;
      }
  
      parseVariadicArgs() {
        this.nextToken();
        const result = [];
        while (this.opt(T$Colon)) {
          result.push(this.parseExpression());
        }
        return result;
      }
  
      parseExpression() {
        let exprStart = this.idx;
        let result = this.parseConditional();
  
        while (this.tkn === T$Eq) {
          if (!result.isAssignable) {
            this.err(`Expression ${this.src.slice(exprStart, this.start)} is not assignable`);
          }
          this.nextToken();
          exprStart = this.idx;
          result = new Assign(result, this.parseConditional());
        }
        return result;
      }
  
      parseConditional() {
        let result = this.parseBinary(0);
  
        if (this.opt(T$Question)) {
          let yes = this.parseExpression();
          this.expect(T$Colon);
          result = new Conditional(result, yes, this.parseExpression());
        }
        return result;
      }
  
      parseBinary(minPrecedence) {
        let left = this.parseLeftHandSide(0);
  
        while (this.tkn & T$BinaryOp) {
          const opToken = this.tkn;
          if ((opToken & T$Precedence) <= minPrecedence) {
            break;
          }
          this.nextToken();
          left = new Binary(TokenValues[opToken & T$TokenMask], left, this.parseBinary(opToken & T$Precedence));
        }
        return left;
      }
  
      parseLeftHandSide(context) {
        let result;
  
        primary: switch (this.tkn) {
          case T$Plus:
            this.nextToken();
            return this.parseLeftHandSide(0);
          case T$Minus:
            this.nextToken();
            return new Binary('-', new LiteralPrimitive(0), this.parseLeftHandSide(0));
          case T$Bang:
          case T$TypeofKeyword:
          case T$VoidKeyword:
            const op = TokenValues[this.tkn & T$TokenMask];
            this.nextToken();
            return new Unary(op, this.parseLeftHandSide(0));
          case T$ParentScope:
            {
              do {
                this.nextToken();
                context++;
                if (this.opt(T$Period)) {
                  if (this.tkn === T$Period) {
                    this.err();
                  }
                  continue;
                } else if (this.tkn & T$AccessScopeTerminal) {
                  result = new AccessThis(context & C$Ancestor);
  
                  context = context & C$ShorthandProp | C$This;
                  break primary;
                } else {
                  this.err();
                }
              } while (this.tkn === T$ParentScope);
            }
  
          case T$Identifier:
            {
              result = new AccessScope(this.val, context & C$Ancestor);
              this.nextToken();
              context = context & C$ShorthandProp | C$Scope;
              break;
            }
          case T$ThisScope:
            this.nextToken();
            result = new AccessThis(0);
            context = context & C$ShorthandProp | C$This;
            break;
          case T$LParen:
            this.nextToken();
            result = this.parseExpression();
            this.expect(T$RParen);
            context = C$Primary;
            break;
          case T$LBracket:
            {
              this.nextToken();
              const elements = [];
              if (this.tkn !== T$RBracket) {
                do {
                  elements.push(this.parseExpression());
                } while (this.opt(T$Comma));
              }
              this.expect(T$RBracket);
              result = new LiteralArray(elements);
              context = C$Primary;
              break;
            }
          case T$LBrace:
            {
              const keys = [];
              const values = [];
              this.nextToken();
              while (this.tkn !== T$RBrace) {
                if (this.tkn & T$IdentifierOrKeyword) {
                  const { ch, tkn, idx } = this;
                  keys.push(this.val);
                  this.nextToken();
                  if (this.opt(T$Colon)) {
                    values.push(this.parseExpression());
                  } else {
                    this.ch = ch;
                    this.tkn = tkn;
                    this.idx = idx;
                    values.push(this.parseLeftHandSide(C$ShorthandProp));
                  }
                } else if (this.tkn & T$Literal) {
                  keys.push(this.val);
                  this.nextToken();
                  this.expect(T$Colon);
                  values.push(this.parseExpression());
                } else {
                  this.err();
                }
                if (this.tkn !== T$RBrace) {
                  this.expect(T$Comma);
                }
              }
              this.expect(T$RBrace);
              result = new LiteralObject(keys, values);
              context = C$Primary;
              break;
            }
          case T$StringLiteral:
            result = new LiteralString(this.val);
            this.nextToken();
            context = C$Primary;
            break;
          case T$TemplateTail:
            result = new LiteralTemplate([this.val]);
            this.nextToken();
            context = C$Primary;
            break;
          case T$TemplateContinuation:
            result = this.parseTemplate(0);
            context = C$Primary;
            break;
          case T$NumericLiteral:
            {
              result = new LiteralPrimitive(this.val);
              this.nextToken();
  
              break;
            }
          case T$NullKeyword:
          case T$UndefinedKeyword:
          case T$TrueKeyword:
          case T$FalseKeyword:
            result = new LiteralPrimitive(TokenValues[this.tkn & T$TokenMask]);
            this.nextToken();
            context = C$Primary;
            break;
          default:
            if (this.idx >= this.len) {
              this.err('Unexpected end of expression');
            } else {
              this.err();
            }
        }
  
        if (context & C$ShorthandProp) {
          return result;
        }
  
        let name = this.val;
        while (this.tkn & T$MemberOrCallExpression) {
          switch (this.tkn) {
            case T$Period:
              this.nextToken();
              if (!(this.tkn & T$IdentifierOrKeyword)) {
                this.err();
              }
              name = this.val;
              this.nextToken();
  
              context = context & C$Primary | (context & (C$This | C$Scope)) << 1 | context & C$Member | (context & C$Keyed) >> 1 | (context & C$Call) >> 2;
              if (this.tkn === T$LParen) {
                continue;
              }
              if (context & C$Scope) {
                result = new AccessScope(name, result.ancestor);
              } else {
                result = new AccessMember(result, name);
              }
              continue;
            case T$LBracket:
              this.nextToken();
              context = C$Keyed;
              result = new AccessKeyed(result, this.parseExpression());
              this.expect(T$RBracket);
              break;
            case T$LParen:
              this.nextToken();
              const args = [];
              while (this.tkn !== T$RParen) {
                args.push(this.parseExpression());
                if (!this.opt(T$Comma)) {
                  break;
                }
              }
              this.expect(T$RParen);
              if (context & C$Scope) {
                result = new CallScope(name, args, result.ancestor);
              } else if (context & (C$Member | C$Primary)) {
                result = new CallMember(result, name, args);
              } else {
                result = new CallFunction(result, args);
              }
              context = C$Call;
              break;
            case T$TemplateTail:
              result = new LiteralTemplate([this.val], [], [this.raw], result);
              this.nextToken();
              break;
            case T$TemplateContinuation:
              result = this.parseTemplate(context | C$Tagged, result);
          }
        }
  
        return result;
      }
  
      parseTemplate(context, func) {
        const cooked = [this.val];
        const raw = context & C$Tagged ? [this.raw] : undefined;
        this.expect(T$TemplateContinuation);
        const expressions = [this.parseExpression()];
  
        while ((this.tkn = this.scanTemplateTail()) !== T$TemplateTail) {
          cooked.push(this.val);
          if (context & C$Tagged) {
            raw.push(this.raw);
          }
          this.expect(T$TemplateContinuation);
          expressions.push(this.parseExpression());
        }
  
        cooked.push(this.val);
        if (context & C$Tagged) {
          raw.push(this.raw);
        }
        this.nextToken();
        return new LiteralTemplate(cooked, expressions, raw, func);
      }
  
      nextToken() {
        while (this.idx < this.len) {
          if (this.ch <= 0x20) {
            this.next();
            continue;
          }
          this.start = this.idx;
          if (this.ch === 0x24 || this.ch >= 0x61 && this.ch <= 0x7A) {
            this.tkn = this.scanIdentifier();
            return;
          }
  
          if ((this.tkn = CharScanners[this.ch](this)) !== null) {
            return;
          }
        }
        this.tkn = T$EOF;
      }
  
      next() {
        return this.ch = this.src.charCodeAt(++this.idx);
      }
  
      scanIdentifier() {
        while (AsciiIdParts.has(this.next()) || this.ch > 0x7F && IdParts[this.ch]) {}
  
        return KeywordLookup[this.val = this.raw] || T$Identifier;
      }
  
      scanNumber(isFloat) {
        if (isFloat) {
          this.val = 0;
        } else {
          this.val = this.ch - 0x30;
          while (this.next() <= 0x39 && this.ch >= 0x30) {
            this.val = this.val * 10 + this.ch - 0x30;
          }
        }
  
        if (isFloat || this.ch === 0x2E) {
          if (!isFloat) {
            this.next();
          }
          const start = this.idx;
          let value = this.ch - 0x30;
          while (this.next() <= 0x39 && this.ch >= 0x30) {
            value = value * 10 + this.ch - 0x30;
          }
          this.val = this.val + value / Math.pow(10, this.idx - start);
        }
  
        if (this.ch === 0x65 || this.ch === 0x45) {
          const start = this.idx;
  
          this.next();
          if (this.ch === 0x2D || this.ch === 0x2B) {
            this.next();
          }
  
          if (!(this.ch >= 0x30 && this.ch <= 0x39)) {
            this.idx = start;
            this.err('Invalid exponent');
          }
          while (this.next() <= 0x39 && this.ch >= 0x30) {}
          this.val = parseFloat(this.src.slice(this.start, this.idx));
        }
  
        return T$NumericLiteral;
      }
  
      scanString() {
        let quote = this.ch;
        this.next();
  
        let buffer;
        let marker = this.idx;
  
        while (this.ch !== quote) {
          if (this.ch === 0x5C) {
            if (!buffer) {
              buffer = [];
            }
  
            buffer.push(this.src.slice(marker, this.idx));
  
            this.next();
  
            let unescaped;
  
            if (this.ch === 0x75) {
              this.next();
  
              if (this.idx + 4 < this.len) {
                let hex = this.src.slice(this.idx, this.idx + 4);
  
                if (!/[A-Z0-9]{4}/i.test(hex)) {
                  this.err(`Invalid unicode escape [\\u${hex}]`);
                }
  
                unescaped = parseInt(hex, 16);
                this.idx += 4;
                this.ch = this.src.charCodeAt(this.idx);
              } else {
                this.err();
              }
            } else {
              unescaped = unescape(this.ch);
              this.next();
            }
  
            buffer.push(fromCharCode(unescaped));
            marker = this.idx;
          } else if (this.ch === 0 || this.idx >= this.len) {
            this.err('Unterminated quote');
          } else {
            this.next();
          }
        }
  
        let last = this.src.slice(marker, this.idx);
        this.next();
        let unescaped = last;
  
        if (buffer !== null && buffer !== undefined) {
          buffer.push(last);
          unescaped = buffer.join('');
        }
  
        this.val = unescaped;
        return T$StringLiteral;
      }
  
      scanTemplate() {
        let tail = true;
        let result = '';
  
        while (this.next() !== 0x60) {
          if (this.ch === 0x24) {
            if (this.idx + 1 < this.len && this.src.charCodeAt(this.idx + 1) === 0x7B) {
              this.idx++;
              tail = false;
              break;
            } else {
              result += '$';
            }
          } else if (this.ch === 0x5C) {
            result += fromCharCode(unescape(this.next()));
          } else if (this.ch === 0 || this.idx >= this.len) {
            this.err('Unterminated template literal');
          } else {
            result += fromCharCode(this.ch);
          }
        }
  
        this.next();
        this.val = result;
        if (tail) {
          return T$TemplateTail;
        }
        return T$TemplateContinuation;
      }
  
      scanTemplateTail() {
        if (this.idx >= this.len) {
          this.err('Unterminated template');
        }
        this.idx--;
        return this.scanTemplate();
      }
  
      err(message = `Unexpected token ${this.raw}`, column = this.start) {
        throw new Error(`Parser Error: ${message} at column ${column} in expression [${this.src}]`);
      }
  
      opt(token) {
        if (this.tkn === token) {
          this.nextToken();
          return true;
        }
  
        return false;
      }
  
      expect(token) {
        if (this.tkn === token) {
          this.nextToken();
        } else {
          this.err(`Missing expected token ${TokenValues[token & T$TokenMask]}`, this.idx);
        }
      }
    };
  
    function unescape(code) {
      switch (code) {
        case 0x66:
          return 0xC;
        case 0x6E:
          return 0xA;
        case 0x72:
          return 0xD;
        case 0x74:
          return 0x9;
        case 0x76:
          return 0xB;
        default:
          return code;
      }
    }
  
    const C$This = 1 << 10;
    const C$Scope = 1 << 11;
    const C$Member = 1 << 12;
    const C$Keyed = 1 << 13;
    const C$Call = 1 << 14;
    const C$Primary = 1 << 15;
    const C$ShorthandProp = 1 << 16;
    const C$Tagged = 1 << 17;
  
    const C$Ancestor = (1 << 9) - 1;
  
    const T$TokenMask = (1 << 6) - 1;
  
    const T$PrecShift = 6;
  
    const T$Precedence = 7 << T$PrecShift;
  
    const T$ExpressionTerminal = 1 << 11;
  
    const T$ClosingToken = 1 << 12;
  
    const T$OpeningToken = 1 << 13;
  
    const T$AccessScopeTerminal = 1 << 14;
    const T$Keyword = 1 << 15;
    const T$EOF = 1 << 16 | T$AccessScopeTerminal | T$ExpressionTerminal;
    const T$Identifier = 1 << 17;
    const T$IdentifierOrKeyword = T$Identifier | T$Keyword;
    const T$Literal = 1 << 18;
    const T$NumericLiteral = 1 << 19 | T$Literal;
    const T$StringLiteral = 1 << 20 | T$Literal;
    const T$BinaryOp = 1 << 21;
  
    const T$UnaryOp = 1 << 22;
  
    const T$MemberExpression = 1 << 23;
  
    const T$MemberOrCallExpression = 1 << 24;
    const T$TemplateTail = 1 << 25 | T$MemberOrCallExpression;
    const T$TemplateContinuation = 1 << 26 | T$MemberOrCallExpression;
  
    const T$FalseKeyword = 0 | T$Keyword | T$Literal;
    const T$TrueKeyword = 1 | T$Keyword | T$Literal;
    const T$NullKeyword = 2 | T$Keyword | T$Literal;
    const T$UndefinedKeyword = 3 | T$Keyword | T$Literal;
    const T$ThisScope = 4 | T$IdentifierOrKeyword;
    const T$ParentScope = 5 | T$IdentifierOrKeyword;
  
    const T$LParen = 6 | T$OpeningToken | T$AccessScopeTerminal | T$MemberOrCallExpression;
    const T$LBrace = 7 | T$OpeningToken;
    const T$Period = 8 | T$MemberExpression | T$MemberOrCallExpression;
    const T$RBrace = 9 | T$AccessScopeTerminal | T$ClosingToken | T$ExpressionTerminal;
    const T$RParen = 10 | T$AccessScopeTerminal | T$ClosingToken | T$ExpressionTerminal;
    const T$Comma = 11 | T$AccessScopeTerminal;
    const T$LBracket = 12 | T$OpeningToken | T$AccessScopeTerminal | T$MemberExpression | T$MemberOrCallExpression;
    const T$RBracket = 13 | T$ClosingToken | T$ExpressionTerminal;
    const T$Colon = 14 | T$AccessScopeTerminal;
    const T$Question = 15;
  
    const T$Ampersand = 18 | T$AccessScopeTerminal;
    const T$Bar = 19 | T$AccessScopeTerminal;
    const T$BarBar = 20 | 1 << T$PrecShift | T$BinaryOp;
    const T$AmpersandAmpersand = 21 | 2 << T$PrecShift | T$BinaryOp;
    const T$Caret = 22 | 3 << T$PrecShift | T$BinaryOp;
    const T$EqEq = 23 | 4 << T$PrecShift | T$BinaryOp;
    const T$BangEq = 24 | 4 << T$PrecShift | T$BinaryOp;
    const T$EqEqEq = 25 | 4 << T$PrecShift | T$BinaryOp;
    const T$BangEqEq = 26 | 4 << T$PrecShift | T$BinaryOp;
    const T$Lt = 27 | 5 << T$PrecShift | T$BinaryOp;
    const T$Gt = 28 | 5 << T$PrecShift | T$BinaryOp;
    const T$LtEq = 29 | 5 << T$PrecShift | T$BinaryOp;
    const T$GtEq = 30 | 5 << T$PrecShift | T$BinaryOp;
    const T$InKeyword = 31 | 5 << T$PrecShift | T$BinaryOp | T$Keyword;
    const T$InstanceOfKeyword = 32 | 5 << T$PrecShift | T$BinaryOp | T$Keyword;
    const T$Plus = 33 | 6 << T$PrecShift | T$BinaryOp | T$UnaryOp;
    const T$Minus = 34 | 6 << T$PrecShift | T$BinaryOp | T$UnaryOp;
    const T$TypeofKeyword = 35 | T$UnaryOp | T$Keyword;
    const T$VoidKeyword = 36 | T$UnaryOp | T$Keyword;
    const T$Star = 37 | 7 << T$PrecShift | T$BinaryOp;
    const T$Percent = 38 | 7 << T$PrecShift | T$BinaryOp;
    const T$Slash = 39 | 7 << T$PrecShift | T$BinaryOp;
    const T$Eq = 40;
    const T$Bang = 41 | T$UnaryOp;
  
    const KeywordLookup = Object.create(null);
    KeywordLookup.true = T$TrueKeyword;
    KeywordLookup.null = T$NullKeyword;
    KeywordLookup.false = T$FalseKeyword;
    KeywordLookup.undefined = T$UndefinedKeyword;
    KeywordLookup.$this = T$ThisScope;
    KeywordLookup.$parent = T$ParentScope;
    KeywordLookup.in = T$InKeyword;
    KeywordLookup.instanceof = T$InstanceOfKeyword;
    KeywordLookup.typeof = T$TypeofKeyword;
    KeywordLookup.void = T$VoidKeyword;
  
    const TokenValues = [false, true, null, undefined, '$this', '$parent', '(', '{', '.', '}', ')', ',', '[', ']', ':', '?', '\'', '"', '&', '|', '||', '&&', '^', '==', '!=', '===', '!==', '<', '>', '<=', '>=', 'in', 'instanceof', '+', '-', 'typeof', 'void', '*', '%', '/', '=', '!'];
  
    const codes = {
      AsciiIdPart: [0x24, 0, 0x30, 0x3A, 0x41, 0x5B, 0x5F, 0, 0x61, 0x7B],
      IdStart: [0x24, 0, 0x41, 0x5B, 0x5F, 0, 0x61, 0x7B, 0xAA, 0, 0xBA, 0, 0xC0, 0xD7, 0xD8, 0xF7, 0xF8, 0x2B9, 0x2E0, 0x2E5, 0x1D00, 0x1D26, 0x1D2C, 0x1D5D, 0x1D62, 0x1D66, 0x1D6B, 0x1D78, 0x1D79, 0x1DBF, 0x1E00, 0x1F00, 0x2071, 0, 0x207F, 0, 0x2090, 0x209D, 0x212A, 0x212C, 0x2132, 0, 0x214E, 0, 0x2160, 0x2189, 0x2C60, 0x2C80, 0xA722, 0xA788, 0xA78B, 0xA7AF, 0xA7B0, 0xA7B8, 0xA7F7, 0xA800, 0xAB30, 0xAB5B, 0xAB5C, 0xAB65, 0xFB00, 0xFB07, 0xFF21, 0xFF3B, 0xFF41, 0xFF5B],
      Digit: [0x30, 0x3A],
      Skip: [0, 0x21, 0x7F, 0xA1]
    };
  
    function decompress(lookup, set, compressed, value) {
      let rangeCount = compressed.length;
      for (let i = 0; i < rangeCount; i += 2) {
        const start = compressed[i];
        let end = compressed[i + 1];
        end = end > 0 ? end : start + 1;
        if (lookup) {
          let j = start;
          while (j < end) {
            lookup[j] = value;
            j++;
          }
        }
        if (set) {
          for (let ch = start; ch < end; ch++) {
            set.add(ch);
          }
        }
      }
    }
  
    function returnToken(token) {
      return p => {
        p.next();
        return token;
      };
    }
    function unexpectedCharacter(p) {
      p.err(`Unexpected character [${fromCharCode(p.ch)}]`);
      return null;
    }
  
    const AsciiIdParts = new Set();
    decompress(null, AsciiIdParts, codes.AsciiIdPart, true);
  
    const IdParts = new Uint8Array(0xFFFF);
    decompress(IdParts, null, codes.IdStart, 1);
    decompress(IdParts, null, codes.Digit, 1);
  
    const CharScanners = new Array(0xFFFF);
    let ci = 0;
    while (ci < 0xFFFF) {
      CharScanners[ci] = unexpectedCharacter;
      ci++;
    }
  
    decompress(CharScanners, null, codes.Skip, p => {
      p.next();
      return null;
    });
    decompress(CharScanners, null, codes.IdStart, p => p.scanIdentifier());
    decompress(CharScanners, null, codes.Digit, p => p.scanNumber(false));
  
    CharScanners[0x22] = CharScanners[0x27] = p => {
      return p.scanString();
    };
    CharScanners[0x60] = p => {
      return p.scanTemplate();
    };
  
    CharScanners[0x21] = p => {
      if (p.next() !== 0x3D) {
        return T$Bang;
      }
      if (p.next() !== 0x3D) {
        return T$BangEq;
      }
      p.next();
      return T$BangEqEq;
    };
  
    CharScanners[0x3D] = p => {
      if (p.next() !== 0x3D) {
        return T$Eq;
      }
      if (p.next() !== 0x3D) {
        return T$EqEq;
      }
      p.next();
      return T$EqEqEq;
    };
  
    CharScanners[0x26] = p => {
      if (p.next() !== 0x26) {
        return T$Ampersand;
      }
      p.next();
      return T$AmpersandAmpersand;
    };
  
    CharScanners[0x7C] = p => {
      if (p.next() !== 0x7C) {
        return T$Bar;
      }
      p.next();
      return T$BarBar;
    };
  
    CharScanners[0x2E] = p => {
      if (p.next() <= 0x39 && p.ch >= 0x30) {
        return p.scanNumber(true);
      }
      return T$Period;
    };
  
    CharScanners[0x3C] = p => {
      if (p.next() !== 0x3D) {
        return T$Lt;
      }
      p.next();
      return T$LtEq;
    };
  
    CharScanners[0x3E] = p => {
      if (p.next() !== 0x3D) {
        return T$Gt;
      }
      p.next();
      return T$GtEq;
    };
  
    CharScanners[0x25] = returnToken(T$Percent);
    CharScanners[0x28] = returnToken(T$LParen);
    CharScanners[0x29] = returnToken(T$RParen);
    CharScanners[0x2A] = returnToken(T$Star);
    CharScanners[0x2B] = returnToken(T$Plus);
    CharScanners[0x2C] = returnToken(T$Comma);
    CharScanners[0x2D] = returnToken(T$Minus);
    CharScanners[0x2F] = returnToken(T$Slash);
    CharScanners[0x3A] = returnToken(T$Colon);
    CharScanners[0x3F] = returnToken(T$Question);
    CharScanners[0x5B] = returnToken(T$LBracket);
    CharScanners[0x5D] = returnToken(T$RBracket);
    CharScanners[0x5E] = returnToken(T$Caret);
    CharScanners[0x7B] = returnToken(T$LBrace);
    CharScanners[0x7D] = returnToken(T$RBrace);
  
    let mapProto = Map.prototype;
  
    function getMapObserver(taskQueue, map) {
      return ModifyMapObserver.for(taskQueue, map);
    }
  
    let ModifyMapObserver = class ModifyMapObserver extends ModifyCollectionObserver {
      constructor(taskQueue, map) {
        super(taskQueue, map);
      }
  
      static for(taskQueue, map) {
        if (!('__map_observer__' in map)) {
          Reflect.defineProperty(map, '__map_observer__', {
            value: ModifyMapObserver.create(taskQueue, map),
            enumerable: false, configurable: false
          });
        }
        return map.__map_observer__;
      }
  
      static create(taskQueue, map) {
        let observer = new ModifyMapObserver(taskQueue, map);
  
        let proto = mapProto;
        if (proto.set !== map.set || proto.delete !== map.delete || proto.clear !== map.clear) {
          proto = {
            set: map.set,
            delete: map.delete,
            clear: map.clear
          };
        }
  
        map.set = function () {
          let hasValue = map.has(arguments[0]);
          let type = hasValue ? 'update' : 'add';
          let oldValue = map.get(arguments[0]);
          let methodCallResult = proto.set.apply(map, arguments);
          if (!hasValue || oldValue !== map.get(arguments[0])) {
            observer.addChangeRecord({
              type: type,
              object: map,
              key: arguments[0],
              oldValue: oldValue
            });
          }
          return methodCallResult;
        };
  
        map.delete = function () {
          let hasValue = map.has(arguments[0]);
          let oldValue = map.get(arguments[0]);
          let methodCallResult = proto.delete.apply(map, arguments);
          if (hasValue) {
            observer.addChangeRecord({
              type: 'delete',
              object: map,
              key: arguments[0],
              oldValue: oldValue
            });
          }
          return methodCallResult;
        };
  
        map.clear = function () {
          let methodCallResult = proto.clear.apply(map, arguments);
          observer.addChangeRecord({
            type: 'clear',
            object: map
          });
          return methodCallResult;
        };
  
        return observer;
      }
    };
  
    function findOriginalEventTarget(event) {
      return event.path && event.path[0] || event.deepPath && event.deepPath[0] || event.target;
    }
  
    function stopPropagation() {
      this.standardStopPropagation();
      this.propagationStopped = true;
    }
  
    function handleCapturedEvent(event) {
      event.propagationStopped = false;
      let target = findOriginalEventTarget(event);
  
      let orderedCallbacks = [];
  
      while (target) {
        if (target.capturedCallbacks) {
          let callback = target.capturedCallbacks[event.type];
          if (callback) {
            if (event.stopPropagation !== stopPropagation) {
              event.standardStopPropagation = event.stopPropagation;
              event.stopPropagation = stopPropagation;
            }
            orderedCallbacks.push(callback);
          }
        }
        target = target.parentNode;
      }
      for (let i = orderedCallbacks.length - 1; i >= 0 && !event.propagationStopped; i--) {
        let orderedCallback = orderedCallbacks[i];
        if ('handleEvent' in orderedCallback) {
          orderedCallback.handleEvent(event);
        } else {
          orderedCallback(event);
        }
      }
    }
  
    let CapturedHandlerEntry = class CapturedHandlerEntry {
      constructor(eventName) {
        this.eventName = eventName;
        this.count = 0;
      }
  
      increment() {
        this.count++;
  
        if (this.count === 1) {
          DOM.addEventListener(this.eventName, handleCapturedEvent, true);
        }
      }
  
      decrement() {
        this.count--;
  
        if (this.count === 0) {
          DOM.removeEventListener(this.eventName, handleCapturedEvent, true);
        }
      }
    };
  
  
    function handleDelegatedEvent(event) {
      event.propagationStopped = false;
      let target = findOriginalEventTarget(event);
  
      while (target && !event.propagationStopped) {
        if (target.delegatedCallbacks) {
          let callback = target.delegatedCallbacks[event.type];
          if (callback) {
            if (event.stopPropagation !== stopPropagation) {
              event.standardStopPropagation = event.stopPropagation;
              event.stopPropagation = stopPropagation;
            }
            if ('handleEvent' in callback) {
              callback.handleEvent(event);
            } else {
              callback(event);
            }
          }
        }
  
        target = target.parentNode;
      }
    }
  
    let DelegateHandlerEntry = class DelegateHandlerEntry {
      constructor(eventName) {
        this.eventName = eventName;
        this.count = 0;
      }
  
      increment() {
        this.count++;
  
        if (this.count === 1) {
          DOM.addEventListener(this.eventName, handleDelegatedEvent, false);
        }
      }
  
      decrement() {
        this.count--;
  
        if (this.count === 0) {
          DOM.removeEventListener(this.eventName, handleDelegatedEvent, false);
        }
      }
    };
    let DelegationEntryHandler = class DelegationEntryHandler {
      constructor(entry, lookup, targetEvent) {
        this.entry = entry;
        this.lookup = lookup;
        this.targetEvent = targetEvent;
      }
  
      dispose() {
        this.entry.decrement();
        this.lookup[this.targetEvent] = null;
      }
    };
    let EventHandler = class EventHandler {
      constructor(target, targetEvent, callback) {
        this.target = target;
        this.targetEvent = targetEvent;
        this.callback = callback;
      }
  
      dispose() {
        this.target.removeEventListener(this.targetEvent, this.callback);
      }
    };
    let DefaultEventStrategy = class DefaultEventStrategy {
      constructor() {
        this.delegatedHandlers = {};
        this.capturedHandlers = {};
      }
  
      subscribe(target, targetEvent, callback, strategy, disposable) {
        let delegatedHandlers;
        let capturedHandlers;
        let handlerEntry;
  
        if (strategy === delegationStrategy.bubbling) {
          delegatedHandlers = this.delegatedHandlers;
          handlerEntry = delegatedHandlers[targetEvent] || (delegatedHandlers[targetEvent] = new DelegateHandlerEntry(targetEvent));
          let delegatedCallbacks = target.delegatedCallbacks || (target.delegatedCallbacks = {});
  
          handlerEntry.increment();
          delegatedCallbacks[targetEvent] = callback;
  
          if (disposable === true) {
            return new DelegationEntryHandler(handlerEntry, delegatedCallbacks, targetEvent);
          }
  
          return function () {
            handlerEntry.decrement();
            delegatedCallbacks[targetEvent] = null;
          };
        }
        if (strategy === delegationStrategy.capturing) {
          capturedHandlers = this.capturedHandlers;
          handlerEntry = capturedHandlers[targetEvent] || (capturedHandlers[targetEvent] = new CapturedHandlerEntry(targetEvent));
          let capturedCallbacks = target.capturedCallbacks || (target.capturedCallbacks = {});
  
          handlerEntry.increment();
          capturedCallbacks[targetEvent] = callback;
  
          if (disposable === true) {
            return new DelegationEntryHandler(handlerEntry, capturedCallbacks, targetEvent);
          }
  
          return function () {
            handlerEntry.decrement();
            capturedCallbacks[targetEvent] = null;
          };
        }
  
        target.addEventListener(targetEvent, callback);
  
        if (disposable === true) {
          return new EventHandler(target, targetEvent, callback);
        }
  
        return function () {
          target.removeEventListener(targetEvent, callback);
        };
      }
    };
  
  
    const delegationStrategy = {
      none: 0,
      capturing: 1,
      bubbling: 2
    };
  
    let EventManager = class EventManager {
      constructor() {
        this.elementHandlerLookup = {};
        this.eventStrategyLookup = {};
  
        this.registerElementConfig({
          tagName: 'input',
          properties: {
            value: ['change', 'input'],
            checked: ['change', 'input'],
            files: ['change', 'input']
          }
        });
  
        this.registerElementConfig({
          tagName: 'textarea',
          properties: {
            value: ['change', 'input']
          }
        });
  
        this.registerElementConfig({
          tagName: 'select',
          properties: {
            value: ['change']
          }
        });
  
        this.registerElementConfig({
          tagName: 'content editable',
          properties: {
            value: ['change', 'input', 'blur', 'keyup', 'paste']
          }
        });
  
        this.registerElementConfig({
          tagName: 'scrollable element',
          properties: {
            scrollTop: ['scroll'],
            scrollLeft: ['scroll']
          }
        });
  
        this.defaultEventStrategy = new DefaultEventStrategy();
      }
  
      registerElementConfig(config) {
        let tagName = config.tagName.toLowerCase();
        let properties = config.properties;
        let propertyName;
  
        let lookup = this.elementHandlerLookup[tagName] = {};
  
        for (propertyName in properties) {
          if (properties.hasOwnProperty(propertyName)) {
            lookup[propertyName] = properties[propertyName];
          }
        }
      }
  
      registerEventStrategy(eventName, strategy) {
        this.eventStrategyLookup[eventName] = strategy;
      }
  
      getElementHandler(target, propertyName) {
        let tagName;
        let lookup = this.elementHandlerLookup;
  
        if (target.tagName) {
          tagName = target.tagName.toLowerCase();
  
          if (lookup[tagName] && lookup[tagName][propertyName]) {
            return new EventSubscriber(lookup[tagName][propertyName]);
          }
  
          if (propertyName === 'textContent' || propertyName === 'innerHTML') {
            return new EventSubscriber(lookup['content editable'].value);
          }
  
          if (propertyName === 'scrollTop' || propertyName === 'scrollLeft') {
            return new EventSubscriber(lookup['scrollable element'][propertyName]);
          }
        }
  
        return null;
      }
  
      addEventListener(target, targetEvent, callbackOrListener, delegate, disposable) {
        return (this.eventStrategyLookup[targetEvent] || this.defaultEventStrategy).subscribe(target, targetEvent, callbackOrListener, delegate, disposable);
      }
    };
  
    let EventSubscriber = class EventSubscriber {
      constructor(events) {
        this.events = events;
        this.element = null;
        this.handler = null;
      }
  
      subscribe(element, callbackOrListener) {
        this.element = element;
        this.handler = callbackOrListener;
  
        let events = this.events;
        for (let i = 0, ii = events.length; ii > i; ++i) {
          element.addEventListener(events[i], callbackOrListener);
        }
      }
  
      dispose() {
        if (this.element === null) {
          return;
        }
        let element = this.element;
        let callbackOrListener = this.handler;
        let events = this.events;
        for (let i = 0, ii = events.length; ii > i; ++i) {
          element.removeEventListener(events[i], callbackOrListener);
        }
        this.element = this.handler = null;
      }
    };
  
    let DirtyChecker = class DirtyChecker {
      constructor() {
        this.tracked = [];
        this.checkDelay = 120;
      }
  
      addProperty(property) {
        let tracked = this.tracked;
  
        tracked.push(property);
  
        if (tracked.length === 1) {
          this.scheduleDirtyCheck();
        }
      }
  
      removeProperty(property) {
        let tracked = this.tracked;
        tracked.splice(tracked.indexOf(property), 1);
      }
  
      scheduleDirtyCheck() {
        setTimeout(() => this.check(), this.checkDelay);
      }
  
      check() {
        let tracked = this.tracked;
        let i = tracked.length;
  
        while (i--) {
          let current = tracked[i];
  
          if (current.isDirty()) {
            current.call();
          }
        }
  
        if (tracked.length) {
          this.scheduleDirtyCheck();
        }
      }
    };
  
    let DirtyCheckProperty = (_dec5$1 = subscriberCollection(), _dec5$1(_class5$1 = class DirtyCheckProperty {
      constructor(dirtyChecker, obj, propertyName) {
        this.dirtyChecker = dirtyChecker;
        this.obj = obj;
        this.propertyName = propertyName;
      }
  
      getValue() {
        return this.obj[this.propertyName];
      }
  
      setValue(newValue) {
        this.obj[this.propertyName] = newValue;
      }
  
      call() {
        let oldValue = this.oldValue;
        let newValue = this.getValue();
  
        this.callSubscribers(newValue, oldValue);
  
        this.oldValue = newValue;
      }
  
      isDirty() {
        return this.oldValue !== this.obj[this.propertyName];
      }
  
      subscribe(context, callable) {
        if (!this.hasSubscribers()) {
          this.oldValue = this.getValue();
          this.dirtyChecker.addProperty(this);
        }
        this.addSubscriber(context, callable);
      }
  
      unsubscribe(context, callable) {
        if (this.removeSubscriber(context, callable) && !this.hasSubscribers()) {
          this.dirtyChecker.removeProperty(this);
        }
      }
    }) || _class5$1);
  
    const logger = getLogger('property-observation');
  
    const propertyAccessor = {
      getValue: (obj, propertyName) => obj[propertyName],
      setValue: (value, obj, propertyName) => {
        obj[propertyName] = value;
      }
    };
  
    let PrimitiveObserver = class PrimitiveObserver {
  
      constructor(primitive, propertyName) {
        this.doNotCache = true;
  
        this.primitive = primitive;
        this.propertyName = propertyName;
      }
  
      getValue() {
        return this.primitive[this.propertyName];
      }
  
      setValue() {
        let type = typeof this.primitive;
        throw new Error(`The ${this.propertyName} property of a ${type} (${this.primitive}) cannot be assigned.`);
      }
  
      subscribe() {}
  
      unsubscribe() {}
    };
  
    let SetterObserver = (_dec6$1 = subscriberCollection(), _dec6$1(_class7$1 = class SetterObserver {
      constructor(taskQueue, obj, propertyName) {
        this.taskQueue = taskQueue;
        this.obj = obj;
        this.propertyName = propertyName;
        this.queued = false;
        this.observing = false;
      }
  
      getValue() {
        return this.obj[this.propertyName];
      }
  
      setValue(newValue) {
        this.obj[this.propertyName] = newValue;
      }
  
      getterValue() {
        return this.currentValue;
      }
  
      setterValue(newValue) {
        let oldValue = this.currentValue;
  
        if (oldValue !== newValue) {
          if (!this.queued) {
            this.oldValue = oldValue;
            this.queued = true;
            this.taskQueue.queueMicroTask(this);
          }
  
          this.currentValue = newValue;
        }
      }
  
      call() {
        let oldValue = this.oldValue;
        let newValue = this.currentValue;
  
        this.queued = false;
  
        this.callSubscribers(newValue, oldValue);
      }
  
      subscribe(context, callable) {
        if (!this.observing) {
          this.convertProperty();
        }
        this.addSubscriber(context, callable);
      }
  
      unsubscribe(context, callable) {
        this.removeSubscriber(context, callable);
      }
  
      convertProperty() {
        this.observing = true;
        this.currentValue = this.obj[this.propertyName];
        this.setValue = this.setterValue;
        this.getValue = this.getterValue;
  
        if (!Reflect.defineProperty(this.obj, this.propertyName, {
          configurable: true,
          enumerable: this.propertyName in this.obj ? this.obj.propertyIsEnumerable(this.propertyName) : true,
          get: this.getValue.bind(this),
          set: this.setValue.bind(this)
        })) {
          logger.warn(`Cannot observe property '${this.propertyName}' of object`, this.obj);
        }
      }
    }) || _class7$1);
  
    let XLinkAttributeObserver = class XLinkAttributeObserver {
      constructor(element, propertyName, attributeName) {
        this.element = element;
        this.propertyName = propertyName;
        this.attributeName = attributeName;
      }
  
      getValue() {
        return this.element.getAttributeNS('http://www.w3.org/1999/xlink', this.attributeName);
      }
  
      setValue(newValue) {
        return this.element.setAttributeNS('http://www.w3.org/1999/xlink', this.attributeName, newValue);
      }
  
      subscribe() {
        throw new Error(`Observation of a "${this.element.nodeName}" element\'s "${this.propertyName}" property is not supported.`);
      }
    };
  
    const dataAttributeAccessor = {
      getValue: (obj, propertyName) => obj.getAttribute(propertyName),
      setValue: (value, obj, propertyName) => {
        if (value === null || value === undefined) {
          obj.removeAttribute(propertyName);
        } else {
          obj.setAttribute(propertyName, value);
        }
      }
    };
  
    let DataAttributeObserver = class DataAttributeObserver {
      constructor(element, propertyName) {
        this.element = element;
        this.propertyName = propertyName;
      }
  
      getValue() {
        return this.element.getAttribute(this.propertyName);
      }
  
      setValue(newValue) {
        if (newValue === null || newValue === undefined) {
          return this.element.removeAttribute(this.propertyName);
        }
        return this.element.setAttribute(this.propertyName, newValue);
      }
  
      subscribe() {
        throw new Error(`Observation of a "${this.element.nodeName}" element\'s "${this.propertyName}" property is not supported.`);
      }
    };
  
    let StyleObserver = class StyleObserver {
      constructor(element, propertyName) {
        this.element = element;
        this.propertyName = propertyName;
  
        this.styles = null;
        this.version = 0;
      }
  
      getValue() {
        return this.element.style.cssText;
      }
  
      _setProperty(style, value) {
        let priority = '';
  
        if (value !== null && value !== undefined && typeof value.indexOf === 'function' && value.indexOf('!important') !== -1) {
          priority = 'important';
          value = value.replace('!important', '');
        }
        this.element.style.setProperty(style, value, priority);
      }
  
      setValue(newValue) {
        let styles = this.styles || {};
        let style;
        let version = this.version;
  
        if (newValue !== null && newValue !== undefined) {
          if (newValue instanceof Object) {
            let value;
            for (style in newValue) {
              if (newValue.hasOwnProperty(style)) {
                value = newValue[style];
                style = style.replace(/([A-Z])/g, m => '-' + m.toLowerCase());
                styles[style] = version;
                this._setProperty(style, value);
              }
            }
          } else if (newValue.length) {
            let rx = /\s*([\w\-]+)\s*:\s*((?:(?:[\w\-]+\(\s*(?:"(?:\\"|[^"])*"|'(?:\\'|[^'])*'|[\w\-]+\(\s*(?:^"(?:\\"|[^"])*"|'(?:\\'|[^'])*'|[^\)]*)\),?|[^\)]*)\),?|"(?:\\"|[^"])*"|'(?:\\'|[^'])*'|[^;]*),?\s*)+);?/g;
            let pair;
            while ((pair = rx.exec(newValue)) !== null) {
              style = pair[1];
              if (!style) {
                continue;
              }
  
              styles[style] = version;
              this._setProperty(style, pair[2]);
            }
          }
        }
  
        this.styles = styles;
        this.version += 1;
  
        if (version === 0) {
          return;
        }
  
        version -= 1;
        for (style in styles) {
          if (!styles.hasOwnProperty(style) || styles[style] !== version) {
            continue;
          }
  
          this.element.style.removeProperty(style);
        }
      }
  
      subscribe() {
        throw new Error(`Observation of a "${this.element.nodeName}" element\'s "${this.propertyName}" property is not supported.`);
      }
    };
  
    let ValueAttributeObserver = (_dec7$1 = subscriberCollection(), _dec7$1(_class8 = class ValueAttributeObserver {
      constructor(element, propertyName, handler) {
        this.element = element;
        this.propertyName = propertyName;
        this.handler = handler;
        if (propertyName === 'files') {
          this.setValue = () => {};
        }
      }
  
      getValue() {
        return this.element[this.propertyName];
      }
  
      setValue(newValue) {
        newValue = newValue === undefined || newValue === null ? '' : newValue;
        if (this.element[this.propertyName] !== newValue) {
          this.element[this.propertyName] = newValue;
          this.notify();
        }
      }
  
      notify() {
        let oldValue = this.oldValue;
        let newValue = this.getValue();
  
        this.callSubscribers(newValue, oldValue);
  
        this.oldValue = newValue;
      }
  
      handleEvent() {
        this.notify();
      }
  
      subscribe(context, callable) {
        if (!this.hasSubscribers()) {
          this.oldValue = this.getValue();
          this.handler.subscribe(this.element, this);
        }
  
        this.addSubscriber(context, callable);
      }
  
      unsubscribe(context, callable) {
        if (this.removeSubscriber(context, callable) && !this.hasSubscribers()) {
          this.handler.dispose();
        }
      }
    }) || _class8);
  
    const checkedArrayContext = 'CheckedObserver:array';
    const checkedValueContext = 'CheckedObserver:value';
  
    let CheckedObserver = (_dec8 = subscriberCollection(), _dec8(_class9 = class CheckedObserver {
      constructor(element, handler, observerLocator) {
        this.element = element;
        this.handler = handler;
        this.observerLocator = observerLocator;
      }
  
      getValue() {
        return this.value;
      }
  
      setValue(newValue) {
        if (this.initialSync && this.value === newValue) {
          return;
        }
  
        if (this.arrayObserver) {
          this.arrayObserver.unsubscribe(checkedArrayContext, this);
          this.arrayObserver = null;
        }
  
        if (this.element.type === 'checkbox' && Array.isArray(newValue)) {
          this.arrayObserver = this.observerLocator.getArrayObserver(newValue);
          this.arrayObserver.subscribe(checkedArrayContext, this);
        }
  
        this.oldValue = this.value;
        this.value = newValue;
        this.synchronizeElement();
        this.notify();
  
        if (!this.initialSync) {
          this.initialSync = true;
          this.observerLocator.taskQueue.queueMicroTask(this);
        }
      }
  
      call(context, splices) {
        this.synchronizeElement();
  
        if (!this.valueObserver) {
          this.valueObserver = this.element.__observers__.model || this.element.__observers__.value;
          if (this.valueObserver) {
            this.valueObserver.subscribe(checkedValueContext, this);
          }
        }
      }
  
      synchronizeElement() {
        let value = this.value;
        let element = this.element;
        let elementValue = element.hasOwnProperty('model') ? element.model : element.value;
        let isRadio = element.type === 'radio';
        let matcher = element.matcher || ((a, b) => a === b);
  
        element.checked = isRadio && !!matcher(value, elementValue) || !isRadio && value === true || !isRadio && Array.isArray(value) && value.findIndex(item => !!matcher(item, elementValue)) !== -1;
      }
  
      synchronizeValue() {
        let value = this.value;
        let element = this.element;
        let elementValue = element.hasOwnProperty('model') ? element.model : element.value;
        let index;
        let matcher = element.matcher || ((a, b) => a === b);
  
        if (element.type === 'checkbox') {
          if (Array.isArray(value)) {
            index = value.findIndex(item => !!matcher(item, elementValue));
            if (element.checked && index === -1) {
              value.push(elementValue);
            } else if (!element.checked && index !== -1) {
              value.splice(index, 1);
            }
  
            return;
          }
  
          value = element.checked;
        } else if (element.checked) {
          value = elementValue;
        } else {
          return;
        }
  
        this.oldValue = this.value;
        this.value = value;
        this.notify();
      }
  
      notify() {
        let oldValue = this.oldValue;
        let newValue = this.value;
  
        if (newValue === oldValue) {
          return;
        }
  
        this.callSubscribers(newValue, oldValue);
      }
  
      handleEvent() {
        this.synchronizeValue();
      }
  
      subscribe(context, callable) {
        if (!this.hasSubscribers()) {
          this.handler.subscribe(this.element, this);
        }
        this.addSubscriber(context, callable);
      }
  
      unsubscribe(context, callable) {
        if (this.removeSubscriber(context, callable) && !this.hasSubscribers()) {
          this.handler.dispose();
        }
      }
  
      unbind() {
        if (this.arrayObserver) {
          this.arrayObserver.unsubscribe(checkedArrayContext, this);
          this.arrayObserver = null;
        }
        if (this.valueObserver) {
          this.valueObserver.unsubscribe(checkedValueContext, this);
        }
      }
    }) || _class9);
  
    const selectArrayContext = 'SelectValueObserver:array';
  
    let SelectValueObserver = (_dec9 = subscriberCollection(), _dec9(_class10 = class SelectValueObserver {
      constructor(element, handler, observerLocator) {
        this.element = element;
        this.handler = handler;
        this.observerLocator = observerLocator;
      }
  
      getValue() {
        return this.value;
      }
  
      setValue(newValue) {
        if (newValue !== null && newValue !== undefined && this.element.multiple && !Array.isArray(newValue)) {
          throw new Error('Only null or Array instances can be bound to a multi-select.');
        }
        if (this.value === newValue) {
          return;
        }
  
        if (this.arrayObserver) {
          this.arrayObserver.unsubscribe(selectArrayContext, this);
          this.arrayObserver = null;
        }
  
        if (Array.isArray(newValue)) {
          this.arrayObserver = this.observerLocator.getArrayObserver(newValue);
          this.arrayObserver.subscribe(selectArrayContext, this);
        }
  
        this.oldValue = this.value;
        this.value = newValue;
        this.synchronizeOptions();
        this.notify();
  
        if (!this.initialSync) {
          this.initialSync = true;
          this.observerLocator.taskQueue.queueMicroTask(this);
        }
      }
  
      call(context, splices) {
        this.synchronizeOptions();
      }
  
      synchronizeOptions() {
        let value = this.value;
        let isArray;
  
        if (Array.isArray(value)) {
          isArray = true;
        }
  
        let options = this.element.options;
        let i = options.length;
        let matcher = this.element.matcher || ((a, b) => a === b);
        while (i--) {
          let option = options.item(i);
          let optionValue = option.hasOwnProperty('model') ? option.model : option.value;
          if (isArray) {
            option.selected = value.findIndex(item => !!matcher(optionValue, item)) !== -1;
            continue;
          }
          option.selected = !!matcher(optionValue, value);
        }
      }
  
      synchronizeValue() {
        let options = this.element.options;
        let count = 0;
        let value = [];
  
        for (let i = 0, ii = options.length; i < ii; i++) {
          let option = options.item(i);
          if (!option.selected) {
            continue;
          }
          value.push(option.hasOwnProperty('model') ? option.model : option.value);
          count++;
        }
  
        if (this.element.multiple) {
          if (Array.isArray(this.value)) {
            let matcher = this.element.matcher || ((a, b) => a === b);
  
            let i = 0;
            while (i < this.value.length) {
              let a = this.value[i];
              if (value.findIndex(b => matcher(a, b)) === -1) {
                this.value.splice(i, 1);
              } else {
                i++;
              }
            }
  
            i = 0;
            while (i < value.length) {
              let a = value[i];
              if (this.value.findIndex(b => matcher(a, b)) === -1) {
                this.value.push(a);
              }
              i++;
            }
            return;
          }
        } else {
          if (count === 0) {
            value = null;
          } else {
            value = value[0];
          }
        }
  
        if (value !== this.value) {
          this.oldValue = this.value;
          this.value = value;
          this.notify();
        }
      }
  
      notify() {
        let oldValue = this.oldValue;
        let newValue = this.value;
  
        this.callSubscribers(newValue, oldValue);
      }
  
      handleEvent() {
        this.synchronizeValue();
      }
  
      subscribe(context, callable) {
        if (!this.hasSubscribers()) {
          this.handler.subscribe(this.element, this);
        }
        this.addSubscriber(context, callable);
      }
  
      unsubscribe(context, callable) {
        if (this.removeSubscriber(context, callable) && !this.hasSubscribers()) {
          this.handler.dispose();
        }
      }
  
      bind() {
        this.domObserver = DOM.createMutationObserver(() => {
          this.synchronizeOptions();
          this.synchronizeValue();
        });
        this.domObserver.observe(this.element, { childList: true, subtree: true, characterData: true });
      }
  
      unbind() {
        this.domObserver.disconnect();
        this.domObserver = null;
  
        if (this.arrayObserver) {
          this.arrayObserver.unsubscribe(selectArrayContext, this);
          this.arrayObserver = null;
        }
      }
    }) || _class10);
  
    let ClassObserver = class ClassObserver {
      constructor(element) {
        this.element = element;
        this.doNotCache = true;
        this.value = '';
        this.version = 0;
      }
  
      getValue() {
        return this.value;
      }
  
      setValue(newValue) {
        let nameIndex = this.nameIndex || {};
        let version = this.version;
        let names;
        let name;
  
        if (newValue !== null && newValue !== undefined && newValue.length) {
          names = newValue.split(/\s+/);
          for (let i = 0, length = names.length; i < length; i++) {
            name = names[i];
            if (name === '') {
              continue;
            }
            nameIndex[name] = version;
            this.element.classList.add(name);
          }
        }
  
        this.value = newValue;
        this.nameIndex = nameIndex;
        this.version += 1;
  
        if (version === 0) {
          return;
        }
  
        version -= 1;
        for (name in nameIndex) {
          if (!nameIndex.hasOwnProperty(name) || nameIndex[name] !== version) {
            continue;
          }
          this.element.classList.remove(name);
        }
      }
  
      subscribe() {
        throw new Error(`Observation of a "${this.element.nodeName}" element\'s "class" property is not supported.`);
      }
    };
  
    function hasDeclaredDependencies(descriptor) {
      return !!(descriptor && descriptor.get && descriptor.get.dependencies);
    }
  
    function declarePropertyDependencies(ctor, propertyName, dependencies) {
      let descriptor = Object.getOwnPropertyDescriptor(ctor.prototype, propertyName);
      descriptor.get.dependencies = dependencies;
    }
  
    function computedFrom(...rest) {
      return function (target, key, descriptor) {
        descriptor.get.dependencies = rest;
        return descriptor;
      };
    }
  
    let ComputedExpression = class ComputedExpression extends Expression {
      constructor(name, dependencies) {
        super();
  
        this.name = name;
        this.dependencies = dependencies;
        this.isAssignable = true;
      }
  
      evaluate(scope, lookupFunctions) {
        return scope.bindingContext[this.name];
      }
  
      assign(scope, value) {
        scope.bindingContext[this.name] = value;
      }
  
      accept(visitor) {
        throw new Error('not implemented');
      }
  
      connect(binding, scope) {
        let dependencies = this.dependencies;
        let i = dependencies.length;
        while (i--) {
          dependencies[i].connect(binding, scope);
        }
      }
    };
  
    function createComputedObserver(obj, propertyName, descriptor, observerLocator) {
      let dependencies = descriptor.get.dependencies;
      if (!(dependencies instanceof ComputedExpression)) {
        let i = dependencies.length;
        while (i--) {
          dependencies[i] = observerLocator.parser.parse(dependencies[i]);
        }
        dependencies = descriptor.get.dependencies = new ComputedExpression(propertyName, dependencies);
      }
  
      let scope = { bindingContext: obj, overrideContext: createOverrideContext(obj) };
      return new ExpressionObserver(scope, dependencies, observerLocator);
    }
  
    let svgElements;
    let svgPresentationElements;
    let svgPresentationAttributes;
    let svgAnalyzer;
  
    if (typeof FEATURE_NO_SVG === 'undefined') {
      svgElements = {
        a: ['class', 'externalResourcesRequired', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'target', 'transform', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space'],
        altGlyph: ['class', 'dx', 'dy', 'externalResourcesRequired', 'format', 'glyphRef', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'rotate', 'style', 'systemLanguage', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        altGlyphDef: ['id', 'xml:base', 'xml:lang', 'xml:space'],
        altGlyphItem: ['id', 'xml:base', 'xml:lang', 'xml:space'],
        animate: ['accumulate', 'additive', 'attributeName', 'attributeType', 'begin', 'by', 'calcMode', 'dur', 'end', 'externalResourcesRequired', 'fill', 'from', 'id', 'keySplines', 'keyTimes', 'max', 'min', 'onbegin', 'onend', 'onload', 'onrepeat', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'restart', 'systemLanguage', 'to', 'values', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space'],
        animateColor: ['accumulate', 'additive', 'attributeName', 'attributeType', 'begin', 'by', 'calcMode', 'dur', 'end', 'externalResourcesRequired', 'fill', 'from', 'id', 'keySplines', 'keyTimes', 'max', 'min', 'onbegin', 'onend', 'onload', 'onrepeat', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'restart', 'systemLanguage', 'to', 'values', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space'],
        animateMotion: ['accumulate', 'additive', 'begin', 'by', 'calcMode', 'dur', 'end', 'externalResourcesRequired', 'fill', 'from', 'id', 'keyPoints', 'keySplines', 'keyTimes', 'max', 'min', 'onbegin', 'onend', 'onload', 'onrepeat', 'origin', 'path', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'restart', 'rotate', 'systemLanguage', 'to', 'values', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space'],
        animateTransform: ['accumulate', 'additive', 'attributeName', 'attributeType', 'begin', 'by', 'calcMode', 'dur', 'end', 'externalResourcesRequired', 'fill', 'from', 'id', 'keySplines', 'keyTimes', 'max', 'min', 'onbegin', 'onend', 'onload', 'onrepeat', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'restart', 'systemLanguage', 'to', 'type', 'values', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space'],
        circle: ['class', 'cx', 'cy', 'externalResourcesRequired', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'r', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'xml:base', 'xml:lang', 'xml:space'],
        clipPath: ['class', 'clipPathUnits', 'externalResourcesRequired', 'id', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'xml:base', 'xml:lang', 'xml:space'],
        'color-profile': ['id', 'local', 'name', 'rendering-intent', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space'],
        cursor: ['externalResourcesRequired', 'id', 'requiredExtensions', 'requiredFeatures', 'systemLanguage', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        defs: ['class', 'externalResourcesRequired', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'xml:base', 'xml:lang', 'xml:space'],
        desc: ['class', 'id', 'style', 'xml:base', 'xml:lang', 'xml:space'],
        ellipse: ['class', 'cx', 'cy', 'externalResourcesRequired', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'rx', 'ry', 'style', 'systemLanguage', 'transform', 'xml:base', 'xml:lang', 'xml:space'],
        feBlend: ['class', 'height', 'id', 'in', 'in2', 'mode', 'result', 'style', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feColorMatrix: ['class', 'height', 'id', 'in', 'result', 'style', 'type', 'values', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feComponentTransfer: ['class', 'height', 'id', 'in', 'result', 'style', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feComposite: ['class', 'height', 'id', 'in', 'in2', 'k1', 'k2', 'k3', 'k4', 'operator', 'result', 'style', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feConvolveMatrix: ['bias', 'class', 'divisor', 'edgeMode', 'height', 'id', 'in', 'kernelMatrix', 'kernelUnitLength', 'order', 'preserveAlpha', 'result', 'style', 'targetX', 'targetY', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feDiffuseLighting: ['class', 'diffuseConstant', 'height', 'id', 'in', 'kernelUnitLength', 'result', 'style', 'surfaceScale', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feDisplacementMap: ['class', 'height', 'id', 'in', 'in2', 'result', 'scale', 'style', 'width', 'x', 'xChannelSelector', 'xml:base', 'xml:lang', 'xml:space', 'y', 'yChannelSelector'],
        feDistantLight: ['azimuth', 'elevation', 'id', 'xml:base', 'xml:lang', 'xml:space'],
        feFlood: ['class', 'height', 'id', 'result', 'style', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feFuncA: ['amplitude', 'exponent', 'id', 'intercept', 'offset', 'slope', 'tableValues', 'type', 'xml:base', 'xml:lang', 'xml:space'],
        feFuncB: ['amplitude', 'exponent', 'id', 'intercept', 'offset', 'slope', 'tableValues', 'type', 'xml:base', 'xml:lang', 'xml:space'],
        feFuncG: ['amplitude', 'exponent', 'id', 'intercept', 'offset', 'slope', 'tableValues', 'type', 'xml:base', 'xml:lang', 'xml:space'],
        feFuncR: ['amplitude', 'exponent', 'id', 'intercept', 'offset', 'slope', 'tableValues', 'type', 'xml:base', 'xml:lang', 'xml:space'],
        feGaussianBlur: ['class', 'height', 'id', 'in', 'result', 'stdDeviation', 'style', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feImage: ['class', 'externalResourcesRequired', 'height', 'id', 'preserveAspectRatio', 'result', 'style', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feMerge: ['class', 'height', 'id', 'result', 'style', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feMergeNode: ['id', 'xml:base', 'xml:lang', 'xml:space'],
        feMorphology: ['class', 'height', 'id', 'in', 'operator', 'radius', 'result', 'style', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feOffset: ['class', 'dx', 'dy', 'height', 'id', 'in', 'result', 'style', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        fePointLight: ['id', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y', 'z'],
        feSpecularLighting: ['class', 'height', 'id', 'in', 'kernelUnitLength', 'result', 'specularConstant', 'specularExponent', 'style', 'surfaceScale', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feSpotLight: ['id', 'limitingConeAngle', 'pointsAtX', 'pointsAtY', 'pointsAtZ', 'specularExponent', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y', 'z'],
        feTile: ['class', 'height', 'id', 'in', 'result', 'style', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        feTurbulence: ['baseFrequency', 'class', 'height', 'id', 'numOctaves', 'result', 'seed', 'stitchTiles', 'style', 'type', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        filter: ['class', 'externalResourcesRequired', 'filterRes', 'filterUnits', 'height', 'id', 'primitiveUnits', 'style', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        font: ['class', 'externalResourcesRequired', 'horiz-adv-x', 'horiz-origin-x', 'horiz-origin-y', 'id', 'style', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'xml:base', 'xml:lang', 'xml:space'],
        'font-face': ['accent-height', 'alphabetic', 'ascent', 'bbox', 'cap-height', 'descent', 'font-family', 'font-size', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'hanging', 'id', 'ideographic', 'mathematical', 'overline-position', 'overline-thickness', 'panose-1', 'slope', 'stemh', 'stemv', 'strikethrough-position', 'strikethrough-thickness', 'underline-position', 'underline-thickness', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'widths', 'x-height', 'xml:base', 'xml:lang', 'xml:space'],
        'font-face-format': ['id', 'string', 'xml:base', 'xml:lang', 'xml:space'],
        'font-face-name': ['id', 'name', 'xml:base', 'xml:lang', 'xml:space'],
        'font-face-src': ['id', 'xml:base', 'xml:lang', 'xml:space'],
        'font-face-uri': ['id', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space'],
        foreignObject: ['class', 'externalResourcesRequired', 'height', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        g: ['class', 'externalResourcesRequired', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'xml:base', 'xml:lang', 'xml:space'],
        glyph: ['arabic-form', 'class', 'd', 'glyph-name', 'horiz-adv-x', 'id', 'lang', 'orientation', 'style', 'unicode', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'xml:base', 'xml:lang', 'xml:space'],
        glyphRef: ['class', 'dx', 'dy', 'format', 'glyphRef', 'id', 'style', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        hkern: ['g1', 'g2', 'id', 'k', 'u1', 'u2', 'xml:base', 'xml:lang', 'xml:space'],
        image: ['class', 'externalResourcesRequired', 'height', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'preserveAspectRatio', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        line: ['class', 'externalResourcesRequired', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'x1', 'x2', 'xml:base', 'xml:lang', 'xml:space', 'y1', 'y2'],
        linearGradient: ['class', 'externalResourcesRequired', 'gradientTransform', 'gradientUnits', 'id', 'spreadMethod', 'style', 'x1', 'x2', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space', 'y1', 'y2'],
        marker: ['class', 'externalResourcesRequired', 'id', 'markerHeight', 'markerUnits', 'markerWidth', 'orient', 'preserveAspectRatio', 'refX', 'refY', 'style', 'viewBox', 'xml:base', 'xml:lang', 'xml:space'],
        mask: ['class', 'externalResourcesRequired', 'height', 'id', 'maskContentUnits', 'maskUnits', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        metadata: ['id', 'xml:base', 'xml:lang', 'xml:space'],
        'missing-glyph': ['class', 'd', 'horiz-adv-x', 'id', 'style', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'xml:base', 'xml:lang', 'xml:space'],
        mpath: ['externalResourcesRequired', 'id', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space'],
        path: ['class', 'd', 'externalResourcesRequired', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'pathLength', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'xml:base', 'xml:lang', 'xml:space'],
        pattern: ['class', 'externalResourcesRequired', 'height', 'id', 'patternContentUnits', 'patternTransform', 'patternUnits', 'preserveAspectRatio', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'viewBox', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        polygon: ['class', 'externalResourcesRequired', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'points', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'xml:base', 'xml:lang', 'xml:space'],
        polyline: ['class', 'externalResourcesRequired', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'points', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'xml:base', 'xml:lang', 'xml:space'],
        radialGradient: ['class', 'cx', 'cy', 'externalResourcesRequired', 'fx', 'fy', 'gradientTransform', 'gradientUnits', 'id', 'r', 'spreadMethod', 'style', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space'],
        rect: ['class', 'externalResourcesRequired', 'height', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'rx', 'ry', 'style', 'systemLanguage', 'transform', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        script: ['externalResourcesRequired', 'id', 'type', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space'],
        set: ['attributeName', 'attributeType', 'begin', 'dur', 'end', 'externalResourcesRequired', 'fill', 'id', 'max', 'min', 'onbegin', 'onend', 'onload', 'onrepeat', 'repeatCount', 'repeatDur', 'requiredExtensions', 'requiredFeatures', 'restart', 'systemLanguage', 'to', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space'],
        stop: ['class', 'id', 'offset', 'style', 'xml:base', 'xml:lang', 'xml:space'],
        style: ['id', 'media', 'title', 'type', 'xml:base', 'xml:lang', 'xml:space'],
        svg: ['baseProfile', 'class', 'contentScriptType', 'contentStyleType', 'externalResourcesRequired', 'height', 'id', 'onabort', 'onactivate', 'onclick', 'onerror', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onresize', 'onscroll', 'onunload', 'onzoom', 'preserveAspectRatio', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'version', 'viewBox', 'width', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y', 'zoomAndPan'],
        switch: ['class', 'externalResourcesRequired', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'xml:base', 'xml:lang', 'xml:space'],
        symbol: ['class', 'externalResourcesRequired', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'preserveAspectRatio', 'style', 'viewBox', 'xml:base', 'xml:lang', 'xml:space'],
        text: ['class', 'dx', 'dy', 'externalResourcesRequired', 'id', 'lengthAdjust', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'rotate', 'style', 'systemLanguage', 'textLength', 'transform', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        textPath: ['class', 'externalResourcesRequired', 'id', 'lengthAdjust', 'method', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'spacing', 'startOffset', 'style', 'systemLanguage', 'textLength', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space'],
        title: ['class', 'id', 'style', 'xml:base', 'xml:lang', 'xml:space'],
        tref: ['class', 'dx', 'dy', 'externalResourcesRequired', 'id', 'lengthAdjust', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'rotate', 'style', 'systemLanguage', 'textLength', 'x', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        tspan: ['class', 'dx', 'dy', 'externalResourcesRequired', 'id', 'lengthAdjust', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'rotate', 'style', 'systemLanguage', 'textLength', 'x', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        use: ['class', 'externalResourcesRequired', 'height', 'id', 'onactivate', 'onclick', 'onfocusin', 'onfocusout', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'requiredExtensions', 'requiredFeatures', 'style', 'systemLanguage', 'transform', 'width', 'x', 'xlink:actuate', 'xlink:arcrole', 'xlink:href', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type', 'xml:base', 'xml:lang', 'xml:space', 'y'],
        view: ['externalResourcesRequired', 'id', 'preserveAspectRatio', 'viewBox', 'viewTarget', 'xml:base', 'xml:lang', 'xml:space', 'zoomAndPan'],
        vkern: ['g1', 'g2', 'id', 'k', 'u1', 'u2', 'xml:base', 'xml:lang', 'xml:space']
      };
  
  
      svgPresentationElements = {
        'a': true,
        'altGlyph': true,
        'animate': true,
        'animateColor': true,
        'circle': true,
        'clipPath': true,
        'defs': true,
        'ellipse': true,
        'feBlend': true,
        'feColorMatrix': true,
        'feComponentTransfer': true,
        'feComposite': true,
        'feConvolveMatrix': true,
        'feDiffuseLighting': true,
        'feDisplacementMap': true,
        'feFlood': true,
        'feGaussianBlur': true,
        'feImage': true,
        'feMerge': true,
        'feMorphology': true,
        'feOffset': true,
        'feSpecularLighting': true,
        'feTile': true,
        'feTurbulence': true,
        'filter': true,
        'font': true,
        'foreignObject': true,
        'g': true,
        'glyph': true,
        'glyphRef': true,
        'image': true,
        'line': true,
        'linearGradient': true,
        'marker': true,
        'mask': true,
        'missing-glyph': true,
        'path': true,
        'pattern': true,
        'polygon': true,
        'polyline': true,
        'radialGradient': true,
        'rect': true,
        'stop': true,
        'svg': true,
        'switch': true,
        'symbol': true,
        'text': true,
        'textPath': true,
        'tref': true,
        'tspan': true,
        'use': true
      };
  
      svgPresentationAttributes = {
        'alignment-baseline': true,
        'baseline-shift': true,
        'clip-path': true,
        'clip-rule': true,
        'clip': true,
        'color-interpolation-filters': true,
        'color-interpolation': true,
        'color-profile': true,
        'color-rendering': true,
        'color': true,
        'cursor': true,
        'direction': true,
        'display': true,
        'dominant-baseline': true,
        'enable-background': true,
        'fill-opacity': true,
        'fill-rule': true,
        'fill': true,
        'filter': true,
        'flood-color': true,
        'flood-opacity': true,
        'font-family': true,
        'font-size-adjust': true,
        'font-size': true,
        'font-stretch': true,
        'font-style': true,
        'font-variant': true,
        'font-weight': true,
        'glyph-orientation-horizontal': true,
        'glyph-orientation-vertical': true,
        'image-rendering': true,
        'kerning': true,
        'letter-spacing': true,
        'lighting-color': true,
        'marker-end': true,
        'marker-mid': true,
        'marker-start': true,
        'mask': true,
        'opacity': true,
        'overflow': true,
        'pointer-events': true,
        'shape-rendering': true,
        'stop-color': true,
        'stop-opacity': true,
        'stroke-dasharray': true,
        'stroke-dashoffset': true,
        'stroke-linecap': true,
        'stroke-linejoin': true,
        'stroke-miterlimit': true,
        'stroke-opacity': true,
        'stroke-width': true,
        'stroke': true,
        'text-anchor': true,
        'text-decoration': true,
        'text-rendering': true,
        'unicode-bidi': true,
        'visibility': true,
        'word-spacing': true,
        'writing-mode': true
      };
  
      let createElement = function (html) {
        let div = DOM.createElement('div');
        div.innerHTML = html;
        return div.firstChild;
      };
  
      svgAnalyzer = class SVGAnalyzer {
        constructor() {
          if (createElement('<svg><altGlyph /></svg>').firstElementChild.nodeName === 'altglyph' && elements.altGlyph) {
            elements.altglyph = elements.altGlyph;
            delete elements.altGlyph;
            elements.altglyphdef = elements.altGlyphDef;
            delete elements.altGlyphDef;
            elements.altglyphitem = elements.altGlyphItem;
            delete elements.altGlyphItem;
            elements.glyphref = elements.glyphRef;
            delete elements.glyphRef;
          }
        }
  
        isStandardSvgAttribute(nodeName, attributeName) {
          return presentationElements[nodeName] && presentationAttributes[attributeName] || elements[nodeName] && elements[nodeName].indexOf(attributeName) !== -1;
        }
      };
    }
  
    const elements = svgElements;
    const presentationElements = svgPresentationElements;
    const presentationAttributes = svgPresentationAttributes;
    const SVGAnalyzer = svgAnalyzer || class {
      isStandardSvgAttribute() {
        return false;
      }
    };
  
    let ObserverLocator = (_temp = _class11 = class ObserverLocator {
      constructor(taskQueue, eventManager, dirtyChecker, svgAnalyzer, parser) {
        this.taskQueue = taskQueue;
        this.eventManager = eventManager;
        this.dirtyChecker = dirtyChecker;
        this.svgAnalyzer = svgAnalyzer;
        this.parser = parser;
  
        this.adapters = [];
        this.logger = getLogger('observer-locator');
      }
  
      getObserver(obj, propertyName) {
        let observersLookup = obj.__observers__;
        let observer;
  
        if (observersLookup && propertyName in observersLookup) {
          return observersLookup[propertyName];
        }
  
        observer = this.createPropertyObserver(obj, propertyName);
  
        if (!observer.doNotCache) {
          if (observersLookup === undefined) {
            observersLookup = this.getOrCreateObserversLookup(obj);
          }
  
          observersLookup[propertyName] = observer;
        }
  
        return observer;
      }
  
      getOrCreateObserversLookup(obj) {
        return obj.__observers__ || this.createObserversLookup(obj);
      }
  
      createObserversLookup(obj) {
        let value = {};
  
        if (!Reflect.defineProperty(obj, '__observers__', {
          enumerable: false,
          configurable: false,
          writable: false,
          value: value
        })) {
          this.logger.warn('Cannot add observers to object', obj);
        }
  
        return value;
      }
  
      addAdapter(adapter) {
        this.adapters.push(adapter);
      }
  
      getAdapterObserver(obj, propertyName, descriptor) {
        for (let i = 0, ii = this.adapters.length; i < ii; i++) {
          let adapter = this.adapters[i];
          let observer = adapter.getObserver(obj, propertyName, descriptor);
          if (observer) {
            return observer;
          }
        }
        return null;
      }
  
      createPropertyObserver(obj, propertyName) {
        let descriptor;
        let handler;
        let xlinkResult;
  
        if (!(obj instanceof Object)) {
          return new PrimitiveObserver(obj, propertyName);
        }
  
        if (obj instanceof DOM.Element) {
          if (propertyName === 'class') {
            return new ClassObserver(obj);
          }
          if (propertyName === 'style' || propertyName === 'css') {
            return new StyleObserver(obj, propertyName);
          }
          handler = this.eventManager.getElementHandler(obj, propertyName);
          if (propertyName === 'value' && obj.tagName.toLowerCase() === 'select') {
            return new SelectValueObserver(obj, handler, this);
          }
          if (propertyName === 'checked' && obj.tagName.toLowerCase() === 'input') {
            return new CheckedObserver(obj, handler, this);
          }
          if (handler) {
            return new ValueAttributeObserver(obj, propertyName, handler);
          }
          xlinkResult = /^xlink:(.+)$/.exec(propertyName);
          if (xlinkResult) {
            return new XLinkAttributeObserver(obj, propertyName, xlinkResult[1]);
          }
          if (propertyName === 'role' && (obj instanceof DOM.Element || obj instanceof DOM.SVGElement) || /^\w+:|^data-|^aria-/.test(propertyName) || obj instanceof DOM.SVGElement && this.svgAnalyzer.isStandardSvgAttribute(obj.nodeName, propertyName)) {
            return new DataAttributeObserver(obj, propertyName);
          }
        }
  
        descriptor = Object.getPropertyDescriptor(obj, propertyName);
  
        if (hasDeclaredDependencies(descriptor)) {
          return createComputedObserver(obj, propertyName, descriptor, this);
        }
  
        if (descriptor) {
          const existingGetterOrSetter = descriptor.get || descriptor.set;
          if (existingGetterOrSetter) {
            if (existingGetterOrSetter.getObserver) {
              return existingGetterOrSetter.getObserver(obj);
            }
  
            let adapterObserver = this.getAdapterObserver(obj, propertyName, descriptor);
            if (adapterObserver) {
              return adapterObserver;
            }
            return new DirtyCheckProperty(this.dirtyChecker, obj, propertyName);
          }
        }
  
        if (obj instanceof Array) {
          if (propertyName === 'length') {
            return this.getArrayObserver(obj).getLengthObserver();
          }
  
          return new DirtyCheckProperty(this.dirtyChecker, obj, propertyName);
        } else if (obj instanceof Map) {
          if (propertyName === 'size') {
            return this.getMapObserver(obj).getLengthObserver();
          }
  
          return new DirtyCheckProperty(this.dirtyChecker, obj, propertyName);
        } else if (obj instanceof Set) {
          if (propertyName === 'size') {
            return this.getSetObserver(obj).getLengthObserver();
          }
  
          return new DirtyCheckProperty(this.dirtyChecker, obj, propertyName);
        }
  
        return new SetterObserver(this.taskQueue, obj, propertyName);
      }
  
      getAccessor(obj, propertyName) {
        if (obj instanceof DOM.Element) {
          if (propertyName === 'class' || propertyName === 'style' || propertyName === 'css' || propertyName === 'value' && (obj.tagName.toLowerCase() === 'input' || obj.tagName.toLowerCase() === 'select') || propertyName === 'checked' && obj.tagName.toLowerCase() === 'input' || propertyName === 'model' && obj.tagName.toLowerCase() === 'input' || /^xlink:.+$/.exec(propertyName)) {
            return this.getObserver(obj, propertyName);
          }
          if (/^\w+:|^data-|^aria-/.test(propertyName) || obj instanceof DOM.SVGElement && this.svgAnalyzer.isStandardSvgAttribute(obj.nodeName, propertyName) || obj.tagName.toLowerCase() === 'img' && propertyName === 'src' || obj.tagName.toLowerCase() === 'a' && propertyName === 'href') {
            return dataAttributeAccessor;
          }
        }
        return propertyAccessor;
      }
  
      getArrayObserver(array) {
        return getArrayObserver(this.taskQueue, array);
      }
  
      getMapObserver(map) {
        return getMapObserver(this.taskQueue, map);
      }
  
      getSetObserver(set) {
        return getSetObserver(this.taskQueue, set);
      }
    }, _class11.inject = [TaskQueue, EventManager, DirtyChecker, SVGAnalyzer, Parser], _temp);
  
    let ObjectObservationAdapter = class ObjectObservationAdapter {
      getObserver(object, propertyName, descriptor) {
        throw new Error('BindingAdapters must implement getObserver(object, propertyName).');
      }
    };
  
    let BindingExpression = class BindingExpression {
      constructor(observerLocator, targetProperty, sourceExpression, mode, lookupFunctions, attribute) {
        this.observerLocator = observerLocator;
        this.targetProperty = targetProperty;
        this.sourceExpression = sourceExpression;
        this.mode = mode;
        this.lookupFunctions = lookupFunctions;
        this.attribute = attribute;
        this.discrete = false;
      }
  
      createBinding(target) {
        return new Binding(this.observerLocator, this.sourceExpression, target, this.targetProperty, this.mode, this.lookupFunctions);
      }
    };
  
    let Binding = (_dec10 = connectable(), _dec10(_class12 = class Binding {
      constructor(observerLocator, sourceExpression, target, targetProperty, mode, lookupFunctions) {
        this.observerLocator = observerLocator;
        this.sourceExpression = sourceExpression;
        this.target = target;
        this.targetProperty = targetProperty;
        this.mode = mode;
        this.lookupFunctions = lookupFunctions;
      }
  
      updateTarget(value) {
        this.targetObserver.setValue(value, this.target, this.targetProperty);
      }
  
      updateSource(value) {
        this.sourceExpression.assign(this.source, value, this.lookupFunctions);
      }
  
      call(context, newValue, oldValue) {
        if (!this.isBound) {
          return;
        }
        if (context === sourceContext) {
          oldValue = this.targetObserver.getValue(this.target, this.targetProperty);
          newValue = this.sourceExpression.evaluate(this.source, this.lookupFunctions);
          if (newValue !== oldValue) {
            this.updateTarget(newValue);
          }
          if (this.mode !== bindingMode.oneTime) {
            this._version++;
            this.sourceExpression.connect(this, this.source);
            this.unobserve(false);
          }
          return;
        }
        if (context === targetContext) {
          if (newValue !== this.sourceExpression.evaluate(this.source, this.lookupFunctions)) {
            this.updateSource(newValue);
          }
          return;
        }
        throw new Error(`Unexpected call context ${context}`);
      }
  
      bind(source) {
        if (this.isBound) {
          if (this.source === source) {
            return;
          }
          this.unbind();
        }
        this.isBound = true;
        this.source = source;
  
        if (this.sourceExpression.bind) {
          this.sourceExpression.bind(this, source, this.lookupFunctions);
        }
  
        let mode = this.mode;
        if (!this.targetObserver) {
          let method = mode === bindingMode.twoWay || mode === bindingMode.fromView ? 'getObserver' : 'getAccessor';
          this.targetObserver = this.observerLocator[method](this.target, this.targetProperty);
        }
  
        if ('bind' in this.targetObserver) {
          this.targetObserver.bind();
        }
        if (this.mode !== bindingMode.fromView) {
          let value = this.sourceExpression.evaluate(source, this.lookupFunctions);
          this.updateTarget(value);
        }
  
        if (mode === bindingMode.oneTime) {
          return;
        } else if (mode === bindingMode.toView) {
          enqueueBindingConnect(this);
        } else if (mode === bindingMode.twoWay) {
          this.sourceExpression.connect(this, source);
          this.targetObserver.subscribe(targetContext, this);
        } else if (mode === bindingMode.fromView) {
          this.targetObserver.subscribe(targetContext, this);
        }
      }
  
      unbind() {
        if (!this.isBound) {
          return;
        }
        this.isBound = false;
        if (this.sourceExpression.unbind) {
          this.sourceExpression.unbind(this, this.source);
        }
        this.source = null;
        if ('unbind' in this.targetObserver) {
          this.targetObserver.unbind();
        }
        if (this.targetObserver.unsubscribe) {
          this.targetObserver.unsubscribe(targetContext, this);
        }
        this.unobserve(true);
      }
  
      connect(evaluate) {
        if (!this.isBound) {
          return;
        }
        if (evaluate) {
          let value = this.sourceExpression.evaluate(this.source, this.lookupFunctions);
          this.updateTarget(value);
        }
        this.sourceExpression.connect(this, this.source);
      }
    }) || _class12);
  
    let CallExpression = class CallExpression {
      constructor(observerLocator, targetProperty, sourceExpression, lookupFunctions) {
        this.observerLocator = observerLocator;
        this.targetProperty = targetProperty;
        this.sourceExpression = sourceExpression;
        this.lookupFunctions = lookupFunctions;
      }
  
      createBinding(target) {
        return new Call(this.observerLocator, this.sourceExpression, target, this.targetProperty, this.lookupFunctions);
      }
    };
  
    let Call = class Call {
      constructor(observerLocator, sourceExpression, target, targetProperty, lookupFunctions) {
        this.sourceExpression = sourceExpression;
        this.target = target;
        this.targetProperty = observerLocator.getObserver(target, targetProperty);
        this.lookupFunctions = lookupFunctions;
      }
  
      callSource($event) {
        let overrideContext = this.source.overrideContext;
        Object.assign(overrideContext, $event);
        overrideContext.$event = $event;
        let mustEvaluate = true;
        let result = this.sourceExpression.evaluate(this.source, this.lookupFunctions, mustEvaluate);
        delete overrideContext.$event;
        for (let prop in $event) {
          delete overrideContext[prop];
        }
        return result;
      }
  
      bind(source) {
        if (this.isBound) {
          if (this.source === source) {
            return;
          }
          this.unbind();
        }
        this.isBound = true;
        this.source = source;
  
        if (this.sourceExpression.bind) {
          this.sourceExpression.bind(this, source, this.lookupFunctions);
        }
        this.targetProperty.setValue($event => this.callSource($event));
      }
  
      unbind() {
        if (!this.isBound) {
          return;
        }
        this.isBound = false;
        if (this.sourceExpression.unbind) {
          this.sourceExpression.unbind(this, this.source);
        }
        this.source = null;
        this.targetProperty.setValue(null);
      }
    };
  
    let ValueConverterResource = class ValueConverterResource {
      constructor(name) {
        this.name = name;
      }
  
      static convention(name) {
        if (name.endsWith('ValueConverter')) {
          return new ValueConverterResource(camelCase(name.substring(0, name.length - 14)));
        }
      }
  
      initialize(container, target) {
        this.instance = container.get(target);
      }
  
      register(registry, name) {
        registry.registerValueConverter(name || this.name, this.instance);
      }
  
      load(container, target) {}
    };
  
    function valueConverter(nameOrTarget) {
      if (nameOrTarget === undefined || typeof nameOrTarget === 'string') {
        return function (target) {
          metadata.define(metadata.resource, new ValueConverterResource(nameOrTarget), target);
        };
      }
  
      metadata.define(metadata.resource, new ValueConverterResource(), nameOrTarget);
    }
  
    let BindingBehaviorResource = class BindingBehaviorResource {
      constructor(name) {
        this.name = name;
      }
  
      static convention(name) {
        if (name.endsWith('BindingBehavior')) {
          return new BindingBehaviorResource(camelCase(name.substring(0, name.length - 15)));
        }
      }
  
      initialize(container, target) {
        this.instance = container.get(target);
      }
  
      register(registry, name) {
        registry.registerBindingBehavior(name || this.name, this.instance);
      }
  
      load(container, target) {}
    };
  
    function bindingBehavior(nameOrTarget) {
      if (nameOrTarget === undefined || typeof nameOrTarget === 'string') {
        return function (target) {
          metadata.define(metadata.resource, new BindingBehaviorResource(nameOrTarget), target);
        };
      }
  
      metadata.define(metadata.resource, new BindingBehaviorResource(), nameOrTarget);
    }
  
    let ListenerExpression = class ListenerExpression {
      constructor(eventManager, targetEvent, sourceExpression, delegationStrategy, preventDefault, lookupFunctions) {
        this.eventManager = eventManager;
        this.targetEvent = targetEvent;
        this.sourceExpression = sourceExpression;
        this.delegationStrategy = delegationStrategy;
        this.discrete = true;
        this.preventDefault = preventDefault;
        this.lookupFunctions = lookupFunctions;
      }
  
      createBinding(target) {
        return new Listener(this.eventManager, this.targetEvent, this.delegationStrategy, this.sourceExpression, target, this.preventDefault, this.lookupFunctions);
      }
    };
  
    let Listener = class Listener {
      constructor(eventManager, targetEvent, delegationStrategy, sourceExpression, target, preventDefault, lookupFunctions) {
        this.eventManager = eventManager;
        this.targetEvent = targetEvent;
        this.delegationStrategy = delegationStrategy;
        this.sourceExpression = sourceExpression;
        this.target = target;
        this.preventDefault = preventDefault;
        this.lookupFunctions = lookupFunctions;
      }
  
      callSource(event) {
        let overrideContext = this.source.overrideContext;
        overrideContext.$event = event;
        let mustEvaluate = true;
        let result = this.sourceExpression.evaluate(this.source, this.lookupFunctions, mustEvaluate);
        delete overrideContext.$event;
        if (result !== true && this.preventDefault) {
          event.preventDefault();
        }
        return result;
      }
  
      handleEvent(event) {
        this.callSource(event);
      }
  
      bind(source) {
        if (this.isBound) {
          if (this.source === source) {
            return;
          }
          this.unbind();
        }
        this.isBound = true;
        this.source = source;
  
        if (this.sourceExpression.bind) {
          this.sourceExpression.bind(this, source, this.lookupFunctions);
        }
        this._handler = this.eventManager.addEventListener(this.target, this.targetEvent, this, this.delegationStrategy, true);
      }
  
      unbind() {
        if (!this.isBound) {
          return;
        }
        this.isBound = false;
        if (this.sourceExpression.unbind) {
          this.sourceExpression.unbind(this, this.source);
        }
        this.source = null;
        this._handler.dispose();
        this._handler = null;
      }
    };
  
    function getAU(element) {
      let au = element.au;
  
      if (au === undefined) {
        throw new Error(`No Aurelia APIs are defined for the element: "${element.tagName}".`);
      }
  
      return au;
    }
  
    let NameExpression = class NameExpression {
      constructor(sourceExpression, apiName, lookupFunctions) {
        this.sourceExpression = sourceExpression;
        this.apiName = apiName;
        this.lookupFunctions = lookupFunctions;
        this.discrete = true;
      }
  
      createBinding(target) {
        return new NameBinder(this.sourceExpression, NameExpression.locateAPI(target, this.apiName), this.lookupFunctions);
      }
  
      static locateAPI(element, apiName) {
        switch (apiName) {
          case 'element':
            return element;
          case 'controller':
            return getAU(element).controller;
          case 'view-model':
            return getAU(element).controller.viewModel;
          case 'view':
            return getAU(element).controller.view;
          default:
            let target = getAU(element)[apiName];
  
            if (target === undefined) {
              throw new Error(`Attempted to reference "${apiName}", but it was not found amongst the target's API.`);
            }
  
            return target.viewModel;
        }
      }
    };
  
    let NameBinder = class NameBinder {
      constructor(sourceExpression, target, lookupFunctions) {
        this.sourceExpression = sourceExpression;
        this.target = target;
        this.lookupFunctions = lookupFunctions;
      }
  
      bind(source) {
        if (this.isBound) {
          if (this.source === source) {
            return;
          }
          this.unbind();
        }
        this.isBound = true;
        this.source = source;
        if (this.sourceExpression.bind) {
          this.sourceExpression.bind(this, source, this.lookupFunctions);
        }
        this.sourceExpression.assign(this.source, this.target, this.lookupFunctions);
      }
  
      unbind() {
        if (!this.isBound) {
          return;
        }
        this.isBound = false;
        if (this.sourceExpression.evaluate(this.source, this.lookupFunctions) === this.target) {
          this.sourceExpression.assign(this.source, null, this.lookupFunctions);
        }
        if (this.sourceExpression.unbind) {
          this.sourceExpression.unbind(this, this.source);
        }
        this.source = null;
      }
    };
  
  
    const LookupFunctions = {
      bindingBehaviors: name => null,
      valueConverters: name => null
    };
  
    let BindingEngine = (_temp2 = _class13 = class BindingEngine {
  
      constructor(observerLocator, parser) {
        this.observerLocator = observerLocator;
        this.parser = parser;
      }
  
      createBindingExpression(targetProperty, sourceExpression, mode = bindingMode.toView, lookupFunctions = LookupFunctions) {
        return new BindingExpression(this.observerLocator, targetProperty, this.parser.parse(sourceExpression), mode, lookupFunctions);
      }
  
      propertyObserver(obj, propertyName) {
        return {
          subscribe: callback => {
            let observer = this.observerLocator.getObserver(obj, propertyName);
            observer.subscribe(callback);
            return {
              dispose: () => observer.unsubscribe(callback)
            };
          }
        };
      }
  
      collectionObserver(collection) {
        return {
          subscribe: callback => {
            let observer;
            if (collection instanceof Array) {
              observer = this.observerLocator.getArrayObserver(collection);
            } else if (collection instanceof Map) {
              observer = this.observerLocator.getMapObserver(collection);
            } else if (collection instanceof Set) {
              observer = this.observerLocator.getSetObserver(collection);
            } else {
              throw new Error('collection must be an instance of Array, Map or Set.');
            }
            observer.subscribe(callback);
            return {
              dispose: () => observer.unsubscribe(callback)
            };
          }
        };
      }
  
      expressionObserver(bindingContext, expression) {
        let scope = { bindingContext, overrideContext: createOverrideContext(bindingContext) };
        return new ExpressionObserver(scope, this.parser.parse(expression), this.observerLocator, LookupFunctions);
      }
  
      parseExpression(expression) {
        return this.parser.parse(expression);
      }
  
      registerAdapter(adapter) {
        this.observerLocator.addAdapter(adapter);
      }
    }, _class13.inject = [ObserverLocator, Parser], _temp2);
  
    let setProto = Set.prototype;
  
    function getSetObserver(taskQueue, set) {
      return ModifySetObserver.for(taskQueue, set);
    }
  
    let ModifySetObserver = class ModifySetObserver extends ModifyCollectionObserver {
      constructor(taskQueue, set) {
        super(taskQueue, set);
      }
  
      static for(taskQueue, set) {
        if (!('__set_observer__' in set)) {
          Reflect.defineProperty(set, '__set_observer__', {
            value: ModifySetObserver.create(taskQueue, set),
            enumerable: false, configurable: false
          });
        }
        return set.__set_observer__;
      }
  
      static create(taskQueue, set) {
        let observer = new ModifySetObserver(taskQueue, set);
  
        let proto = setProto;
        if (proto.add !== set.add || proto.delete !== set.delete || proto.clear !== set.clear) {
          proto = {
            add: set.add,
            delete: set.delete,
            clear: set.clear
          };
        }
  
        set.add = function () {
          let type = 'add';
          let oldSize = set.size;
          let methodCallResult = proto.add.apply(set, arguments);
          let hasValue = set.size === oldSize;
          if (!hasValue) {
            observer.addChangeRecord({
              type: type,
              object: set,
              value: Array.from(set).pop()
            });
          }
          return methodCallResult;
        };
  
        set.delete = function () {
          let hasValue = set.has(arguments[0]);
          let methodCallResult = proto.delete.apply(set, arguments);
          if (hasValue) {
            observer.addChangeRecord({
              type: 'delete',
              object: set,
              value: arguments[0]
            });
          }
          return methodCallResult;
        };
  
        set.clear = function () {
          let methodCallResult = proto.clear.apply(set, arguments);
          observer.addChangeRecord({
            type: 'clear',
            object: set
          });
          return methodCallResult;
        };
  
        return observer;
      }
    };
  
  
    function observable(targetOrConfig, key, descriptor) {
      function deco(target, key, descriptor, config) {
        const isClassDecorator = key === undefined;
        if (isClassDecorator) {
          target = target.prototype;
          key = typeof config === 'string' ? config : config.name;
        }
  
        let innerPropertyName = `_${key}`;
        const innerPropertyDescriptor = {
          configurable: true,
          enumerable: false,
          writable: true
        };
  
        const callbackName = config && config.changeHandler || `${key}Changed`;
  
        if (descriptor) {
          if (typeof descriptor.initializer === 'function') {
            innerPropertyDescriptor.value = descriptor.initializer();
          }
        } else {
          descriptor = {};
        }
  
        if (!('enumerable' in descriptor)) {
          descriptor.enumerable = true;
        }
  
        delete descriptor.value;
        delete descriptor.writable;
        delete descriptor.initializer;
  
        Reflect.defineProperty(target, innerPropertyName, innerPropertyDescriptor);
  
        descriptor.get = function () {
          return this[innerPropertyName];
        };
        descriptor.set = function (newValue) {
          let oldValue = this[innerPropertyName];
          if (newValue === oldValue) {
            return;
          }
  
          this[innerPropertyName] = newValue;
          Reflect.defineProperty(this, innerPropertyName, { enumerable: false });
  
          if (this[callbackName]) {
            this[callbackName](newValue, oldValue, key);
          }
        };
  
        descriptor.get.dependencies = [innerPropertyName];
  
        if (isClassDecorator) {
          Reflect.defineProperty(target, key, descriptor);
        } else {
          return descriptor;
        }
      }
  
      if (key === undefined) {
        return (t, k, d) => deco(t, k, d, targetOrConfig);
      }
      return deco(targetOrConfig, key, descriptor);
    }
  
    const signals = {};
  
    function connectBindingToSignal(binding, name) {
      if (!signals.hasOwnProperty(name)) {
        signals[name] = 0;
      }
      binding.observeProperty(signals, name);
    }
  
    function signalBindings(name) {
      if (signals.hasOwnProperty(name)) {
        signals[name]++;
      }
    }
  
    var _class$2, _temp$1, _dec$2, _class2$2, _dec2$2, _class3$2, _dec3$2, _class4$1, _dec4$2, _class5$2, _dec5$2, _class6$1, _dec6$2, _class7$2, _class8$1, _temp2$1, _class9$1, _temp3, _class11$1, _dec7$2, _class13$1, _dec8$1, _class14, _class15, _temp4, _dec9$1, _class16, _dec10$1, _class17, _dec11, _class18;
  
    const animationEvent = {
      enterBegin: 'animation:enter:begin',
      enterActive: 'animation:enter:active',
      enterDone: 'animation:enter:done',
      enterTimeout: 'animation:enter:timeout',
  
      leaveBegin: 'animation:leave:begin',
      leaveActive: 'animation:leave:active',
      leaveDone: 'animation:leave:done',
      leaveTimeout: 'animation:leave:timeout',
  
      staggerNext: 'animation:stagger:next',
  
      removeClassBegin: 'animation:remove-class:begin',
      removeClassActive: 'animation:remove-class:active',
      removeClassDone: 'animation:remove-class:done',
      removeClassTimeout: 'animation:remove-class:timeout',
  
      addClassBegin: 'animation:add-class:begin',
      addClassActive: 'animation:add-class:active',
      addClassDone: 'animation:add-class:done',
      addClassTimeout: 'animation:add-class:timeout',
  
      animateBegin: 'animation:animate:begin',
      animateActive: 'animation:animate:active',
      animateDone: 'animation:animate:done',
      animateTimeout: 'animation:animate:timeout',
  
      sequenceBegin: 'animation:sequence:begin',
      sequenceDone: 'animation:sequence:done'
    };
  
    let Animator = class Animator {
      enter(element) {
        return Promise.resolve(false);
      }
  
      leave(element) {
        return Promise.resolve(false);
      }
  
      removeClass(element, className) {
        element.classList.remove(className);
        return Promise.resolve(false);
      }
  
      addClass(element, className) {
        element.classList.add(className);
        return Promise.resolve(false);
      }
  
      animate(element, className) {
        return Promise.resolve(false);
      }
  
      runSequence(animations) {}
  
      registerEffect(effectName, properties) {}
  
      unregisterEffect(effectName) {}
    };
  
    let CompositionTransactionNotifier = class CompositionTransactionNotifier {
      constructor(owner) {
        this.owner = owner;
        this.owner._compositionCount++;
      }
  
      done() {
        this.owner._compositionCount--;
        this.owner._tryCompleteTransaction();
      }
    };
  
    let CompositionTransactionOwnershipToken = class CompositionTransactionOwnershipToken {
      constructor(owner) {
        this.owner = owner;
        this.owner._ownershipToken = this;
        this.thenable = this._createThenable();
      }
  
      waitForCompositionComplete() {
        this.owner._tryCompleteTransaction();
        return this.thenable;
      }
  
      resolve() {
        this._resolveCallback();
      }
  
      _createThenable() {
        return new Promise((resolve, reject) => {
          this._resolveCallback = resolve;
        });
      }
    };
  
    let CompositionTransaction = class CompositionTransaction {
      constructor() {
        this._ownershipToken = null;
        this._compositionCount = 0;
      }
  
      tryCapture() {
        return this._ownershipToken === null ? new CompositionTransactionOwnershipToken(this) : null;
      }
  
      enlist() {
        return new CompositionTransactionNotifier(this);
      }
  
      _tryCompleteTransaction() {
        if (this._compositionCount <= 0) {
          this._compositionCount = 0;
  
          if (this._ownershipToken !== null) {
            let token = this._ownershipToken;
            this._ownershipToken = null;
            token.resolve();
          }
        }
      }
    };
  
    const capitalMatcher = /([A-Z])/g;
  
    function addHyphenAndLower(char) {
      return '-' + char.toLowerCase();
    }
  
    function _hyphenate(name) {
      return (name.charAt(0).toLowerCase() + name.slice(1)).replace(capitalMatcher, addHyphenAndLower);
    }
  
    function _isAllWhitespace(node) {
      return !(node.auInterpolationTarget || /[^\t\n\r ]/.test(node.textContent));
    }
  
    let ViewEngineHooksResource = class ViewEngineHooksResource {
      constructor() {}
  
      initialize(container, target) {
        this.instance = container.get(target);
      }
  
      register(registry, name) {
        registry.registerViewEngineHooks(this.instance);
      }
  
      load(container, target) {}
  
      static convention(name) {
        if (name.endsWith('ViewEngineHooks')) {
          return new ViewEngineHooksResource();
        }
      }
    };
  
    function viewEngineHooks(target) {
      let deco = function (t) {
        metadata.define(metadata.resource, new ViewEngineHooksResource(), t);
      };
  
      return target ? deco(target) : deco;
    }
  
    let ElementEvents = class ElementEvents {
      constructor(element) {
        this.element = element;
        this.subscriptions = {};
      }
  
      _enqueueHandler(handler) {
        this.subscriptions[handler.eventName] = this.subscriptions[handler.eventName] || [];
        this.subscriptions[handler.eventName].push(handler);
      }
  
      _dequeueHandler(handler) {
        let index;
        let subscriptions = this.subscriptions[handler.eventName];
        if (subscriptions) {
          index = subscriptions.indexOf(handler);
          if (index > -1) {
            subscriptions.splice(index, 1);
          }
        }
        return handler;
      }
  
      publish(eventName, detail = {}, bubbles = true, cancelable = true) {
        let event = DOM.createCustomEvent(eventName, { cancelable, bubbles, detail });
        this.element.dispatchEvent(event);
      }
  
      subscribe(eventName, handler, captureOrOptions = true) {
        if (typeof handler === 'function') {
          const eventHandler = new EventHandlerImpl(this, eventName, handler, captureOrOptions, false);
          return eventHandler;
        }
  
        return undefined;
      }
  
      subscribeOnce(eventName, handler, captureOrOptions = true) {
        if (typeof handler === 'function') {
          const eventHandler = new EventHandlerImpl(this, eventName, handler, captureOrOptions, true);
          return eventHandler;
        }
  
        return undefined;
      }
  
      dispose(eventName) {
        if (eventName && typeof eventName === 'string') {
          let subscriptions = this.subscriptions[eventName];
          if (subscriptions) {
            while (subscriptions.length) {
              let subscription = subscriptions.pop();
              if (subscription) {
                subscription.dispose();
              }
            }
          }
        } else {
          this.disposeAll();
        }
      }
  
      disposeAll() {
        for (let key in this.subscriptions) {
          this.dispose(key);
        }
      }
    };
  
    let EventHandlerImpl = class EventHandlerImpl {
      constructor(owner, eventName, handler, captureOrOptions, once) {
        this.owner = owner;
        this.eventName = eventName;
        this.handler = handler;
  
        this.capture = typeof captureOrOptions === 'boolean' ? captureOrOptions : captureOrOptions.capture;
        this.bubbles = !this.capture;
        this.captureOrOptions = captureOrOptions;
        this.once = once;
        owner.element.addEventListener(eventName, this, captureOrOptions);
        owner._enqueueHandler(this);
      }
  
      handleEvent(e) {
        const fn = this.handler;
        fn(e);
        if (this.once) {
          this.dispose();
        }
      }
  
      dispose() {
        this.owner.element.removeEventListener(this.eventName, this, this.captureOrOptions);
        this.owner._dequeueHandler(this);
        this.owner = this.handler = null;
      }
    };
  
    let ResourceLoadContext = class ResourceLoadContext {
      constructor() {
        this.dependencies = {};
      }
  
      addDependency(url) {
        this.dependencies[url] = true;
      }
  
      hasDependency(url) {
        return url in this.dependencies;
      }
    };
  
    let ViewCompileInstruction = class ViewCompileInstruction {
      constructor(targetShadowDOM = false, compileSurrogate = false) {
        this.targetShadowDOM = targetShadowDOM;
        this.compileSurrogate = compileSurrogate;
        this.associatedModuleId = null;
      }
    };
  
    ViewCompileInstruction.normal = new ViewCompileInstruction();
  
    let BehaviorInstruction = class BehaviorInstruction {
      static enhance() {
        let instruction = new BehaviorInstruction();
        instruction.enhance = true;
        return instruction;
      }
  
      static unitTest(type, attributes) {
        let instruction = new BehaviorInstruction();
        instruction.type = type;
        instruction.attributes = attributes || {};
        return instruction;
      }
  
      static element(node, type) {
        let instruction = new BehaviorInstruction();
        instruction.type = type;
        instruction.attributes = {};
        instruction.anchorIsContainer = !(node.hasAttribute('containerless') || type.containerless);
        instruction.initiatedByBehavior = true;
        return instruction;
      }
  
      static attribute(attrName, type) {
        let instruction = new BehaviorInstruction();
        instruction.attrName = attrName;
        instruction.type = type || null;
        instruction.attributes = {};
        return instruction;
      }
  
      static dynamic(host, viewModel, viewFactory) {
        let instruction = new BehaviorInstruction();
        instruction.host = host;
        instruction.viewModel = viewModel;
        instruction.viewFactory = viewFactory;
        instruction.inheritBindingContext = true;
        return instruction;
      }
    };
  
    const biProto = BehaviorInstruction.prototype;
    biProto.initiatedByBehavior = false;
    biProto.enhance = false;
    biProto.partReplacements = null;
    biProto.viewFactory = null;
    biProto.originalAttrName = null;
    biProto.skipContentProcessing = false;
    biProto.contentFactory = null;
    biProto.viewModel = null;
    biProto.anchorIsContainer = false;
    biProto.host = null;
    biProto.attributes = null;
    biProto.type = null;
    biProto.attrName = null;
    biProto.inheritBindingContext = false;
  
    BehaviorInstruction.normal = new BehaviorInstruction();
  
    let TargetInstruction = (_temp$1 = _class$2 = class TargetInstruction {
      static shadowSlot(parentInjectorId) {
        let instruction = new TargetInstruction();
        instruction.parentInjectorId = parentInjectorId;
        instruction.shadowSlot = true;
        return instruction;
      }
  
      static contentExpression(expression) {
        let instruction = new TargetInstruction();
        instruction.contentExpression = expression;
        return instruction;
      }
  
      static letElement(expressions) {
        let instruction = new TargetInstruction();
        instruction.expressions = expressions;
        instruction.letElement = true;
        return instruction;
      }
  
      static lifting(parentInjectorId, liftingInstruction) {
        let instruction = new TargetInstruction();
        instruction.parentInjectorId = parentInjectorId;
        instruction.expressions = TargetInstruction.noExpressions;
        instruction.behaviorInstructions = [liftingInstruction];
        instruction.viewFactory = liftingInstruction.viewFactory;
        instruction.providers = [liftingInstruction.type.target];
        instruction.lifting = true;
        return instruction;
      }
  
      static normal(injectorId, parentInjectorId, providers, behaviorInstructions, expressions, elementInstruction) {
        let instruction = new TargetInstruction();
        instruction.injectorId = injectorId;
        instruction.parentInjectorId = parentInjectorId;
        instruction.providers = providers;
        instruction.behaviorInstructions = behaviorInstructions;
        instruction.expressions = expressions;
        instruction.anchorIsContainer = elementInstruction ? elementInstruction.anchorIsContainer : true;
        instruction.elementInstruction = elementInstruction;
        return instruction;
      }
  
      static surrogate(providers, behaviorInstructions, expressions, values) {
        let instruction = new TargetInstruction();
        instruction.expressions = expressions;
        instruction.behaviorInstructions = behaviorInstructions;
        instruction.providers = providers;
        instruction.values = values;
        return instruction;
      }
    }, _class$2.noExpressions = Object.freeze([]), _temp$1);
  
    const tiProto = TargetInstruction.prototype;
  
    tiProto.injectorId = null;
    tiProto.parentInjectorId = null;
  
    tiProto.shadowSlot = false;
    tiProto.slotName = null;
    tiProto.slotFallbackFactory = null;
  
    tiProto.contentExpression = null;
    tiProto.letElement = false;
  
    tiProto.expressions = null;
    tiProto.expressions = null;
    tiProto.providers = null;
  
    tiProto.viewFactory = null;
  
    tiProto.anchorIsContainer = false;
    tiProto.elementInstruction = null;
    tiProto.lifting = false;
  
    tiProto.values = null;
  
    const viewStrategy = protocol.create('aurelia:view-strategy', {
      validate(target) {
        if (!(typeof target.loadViewFactory === 'function')) {
          return 'View strategies must implement: loadViewFactory(viewEngine: ViewEngine, compileInstruction: ViewCompileInstruction, loadContext?: ResourceLoadContext): Promise<ViewFactory>';
        }
  
        return true;
      },
      compose(target) {
        if (!(typeof target.makeRelativeTo === 'function')) {
          target.makeRelativeTo = PLATFORM.noop;
        }
      }
    });
  
    let RelativeViewStrategy = (_dec$2 = viewStrategy(), _dec$2(_class2$2 = class RelativeViewStrategy {
      constructor(path) {
        this.path = path;
        this.absolutePath = null;
      }
  
      loadViewFactory(viewEngine, compileInstruction, loadContext, target) {
        if (this.absolutePath === null && this.moduleId) {
          this.absolutePath = relativeToFile(this.path, this.moduleId);
        }
  
        compileInstruction.associatedModuleId = this.moduleId;
        return viewEngine.loadViewFactory(this.absolutePath || this.path, compileInstruction, loadContext, target);
      }
  
      makeRelativeTo(file) {
        if (this.absolutePath === null) {
          this.absolutePath = relativeToFile(this.path, file);
        }
      }
    }) || _class2$2);
  
    let ConventionalViewStrategy = (_dec2$2 = viewStrategy(), _dec2$2(_class3$2 = class ConventionalViewStrategy {
      constructor(viewLocator, origin) {
        this.moduleId = origin.moduleId;
        this.viewUrl = viewLocator.convertOriginToViewUrl(origin);
      }
  
      loadViewFactory(viewEngine, compileInstruction, loadContext, target) {
        compileInstruction.associatedModuleId = this.moduleId;
        return viewEngine.loadViewFactory(this.viewUrl, compileInstruction, loadContext, target);
      }
    }) || _class3$2);
  
    let NoViewStrategy = (_dec3$2 = viewStrategy(), _dec3$2(_class4$1 = class NoViewStrategy {
      constructor(dependencies, dependencyBaseUrl) {
        this.dependencies = dependencies || null;
        this.dependencyBaseUrl = dependencyBaseUrl || '';
      }
  
      loadViewFactory(viewEngine, compileInstruction, loadContext, target) {
        let entry = this.entry;
        let dependencies = this.dependencies;
  
        if (entry && entry.factoryIsReady) {
          return Promise.resolve(null);
        }
  
        this.entry = entry = new TemplateRegistryEntry(this.moduleId || this.dependencyBaseUrl);
  
        entry.dependencies = [];
        entry.templateIsLoaded = true;
  
        if (dependencies !== null) {
          for (let i = 0, ii = dependencies.length; i < ii; ++i) {
            let current = dependencies[i];
  
            if (typeof current === 'string' || typeof current === 'function') {
              entry.addDependency(current);
            } else {
              entry.addDependency(current.from, current.as);
            }
          }
        }
  
        compileInstruction.associatedModuleId = this.moduleId;
  
        return viewEngine.loadViewFactory(entry, compileInstruction, loadContext, target);
      }
    }) || _class4$1);
  
    let TemplateRegistryViewStrategy = (_dec4$2 = viewStrategy(), _dec4$2(_class5$2 = class TemplateRegistryViewStrategy {
      constructor(moduleId, entry) {
        this.moduleId = moduleId;
        this.entry = entry;
      }
  
      loadViewFactory(viewEngine, compileInstruction, loadContext, target) {
        let entry = this.entry;
  
        if (entry.factoryIsReady) {
          return Promise.resolve(entry.factory);
        }
  
        compileInstruction.associatedModuleId = this.moduleId;
        return viewEngine.loadViewFactory(entry, compileInstruction, loadContext, target);
      }
    }) || _class5$2);
  
    let InlineViewStrategy = (_dec5$2 = viewStrategy(), _dec5$2(_class6$1 = class InlineViewStrategy {
      constructor(markup, dependencies, dependencyBaseUrl) {
        this.markup = markup;
        this.dependencies = dependencies || null;
        this.dependencyBaseUrl = dependencyBaseUrl || '';
      }
  
      loadViewFactory(viewEngine, compileInstruction, loadContext, target) {
        let entry = this.entry;
        let dependencies = this.dependencies;
  
        if (entry && entry.factoryIsReady) {
          return Promise.resolve(entry.factory);
        }
  
        this.entry = entry = new TemplateRegistryEntry(this.moduleId || this.dependencyBaseUrl);
        entry.template = DOM.createTemplateFromMarkup(this.markup);
  
        if (dependencies !== null) {
          for (let i = 0, ii = dependencies.length; i < ii; ++i) {
            let current = dependencies[i];
  
            if (typeof current === 'string' || typeof current === 'function') {
              entry.addDependency(current);
            } else {
              entry.addDependency(current.from, current.as);
            }
          }
        }
  
        compileInstruction.associatedModuleId = this.moduleId;
        return viewEngine.loadViewFactory(entry, compileInstruction, loadContext, target);
      }
    }) || _class6$1);
  
    let StaticViewStrategy = (_dec6$2 = viewStrategy(), _dec6$2(_class7$2 = class StaticViewStrategy {
  
      constructor(config) {
        if (typeof config === 'string' || config instanceof DOM.Element && config.tagName === 'TEMPLATE') {
          config = {
            template: config
          };
        }
        this.template = config.template;
        this.dependencies = config.dependencies || [];
        this.factoryIsReady = false;
        this.onReady = null;
        this.moduleId = 'undefined';
      }
  
      loadViewFactory(viewEngine, compileInstruction, loadContext, target) {
        if (this.factoryIsReady) {
          return Promise.resolve(this.factory);
        }
        let deps = this.dependencies;
        deps = typeof deps === 'function' ? deps() : deps;
        deps = deps ? deps : [];
        deps = Array.isArray(deps) ? deps : [deps];
  
        return Promise.all(deps).then(dependencies => {
          const container = viewEngine.container;
          const appResources = viewEngine.appResources;
          const viewCompiler = viewEngine.viewCompiler;
          const viewResources = new ViewResources(appResources);
  
          let resource;
          let elDeps = [];
  
          if (target) {
            viewResources.autoRegister(container, target);
          }
  
          for (let dep of dependencies) {
            if (typeof dep === 'function') {
              resource = viewResources.autoRegister(container, dep);
              if (resource.elementName !== null) {
                elDeps.push(resource);
              }
            } else if (dep && typeof dep === 'object') {
              for (let key in dep) {
                let exported = dep[key];
                if (typeof exported === 'function') {
                  resource = viewResources.autoRegister(container, exported);
                  if (resource.elementName !== null) {
                    elDeps.push(resource);
                  }
                }
              }
            } else {
              throw new Error(`dependency neither function nor object. Received: "${typeof dep}"`);
            }
          }
  
          return Promise.all(elDeps.map(el => el.load(container, el.target))).then(() => {
            const factory = this.template !== null ? viewCompiler.compile(this.template, viewResources, compileInstruction) : null;
            this.factoryIsReady = true;
            this.factory = factory;
            return factory;
          });
        });
      }
    }) || _class7$2);
  
    let ViewLocator = (_temp2$1 = _class8$1 = class ViewLocator {
      getViewStrategy(value) {
        if (!value) {
          return null;
        }
  
        if (typeof value === 'object' && 'getViewStrategy' in value) {
          let origin = Origin.get(value.constructor);
  
          value = value.getViewStrategy();
  
          if (typeof value === 'string') {
            value = new RelativeViewStrategy(value);
          }
  
          viewStrategy.assert(value);
  
          if (origin.moduleId) {
            value.makeRelativeTo(origin.moduleId);
          }
  
          return value;
        }
  
        if (typeof value === 'string') {
          value = new RelativeViewStrategy(value);
        }
  
        if (viewStrategy.validate(value)) {
          return value;
        }
  
        if (typeof value !== 'function') {
          value = value.constructor;
        }
  
        if ('$view' in value) {
          let c = value.$view;
          let view;
          c = typeof c === 'function' ? c.call(value) : c;
          if (c === null) {
            view = new NoViewStrategy();
          } else {
            view = c instanceof StaticViewStrategy ? c : new StaticViewStrategy(c);
          }
          metadata.define(ViewLocator.viewStrategyMetadataKey, view, value);
          return view;
        }
  
        let origin = Origin.get(value);
        let strategy = metadata.get(ViewLocator.viewStrategyMetadataKey, value);
  
        if (!strategy) {
          if (!origin.moduleId) {
            throw new Error('Cannot determine default view strategy for object.', value);
          }
  
          strategy = this.createFallbackViewStrategy(origin);
        } else if (origin.moduleId) {
          strategy.moduleId = origin.moduleId;
        }
  
        return strategy;
      }
  
      createFallbackViewStrategy(origin) {
        return new ConventionalViewStrategy(this, origin);
      }
  
      convertOriginToViewUrl(origin) {
        let moduleId = origin.moduleId;
        let id = moduleId.endsWith('.js') || moduleId.endsWith('.ts') ? moduleId.substring(0, moduleId.length - 3) : moduleId;
        return id + '.html';
      }
    }, _class8$1.viewStrategyMetadataKey = 'aurelia:view-strategy', _temp2$1);
  
    function mi(name) {
      throw new Error(`BindingLanguage must implement ${name}().`);
    }
  
    let BindingLanguage = class BindingLanguage {
      inspectAttribute(resources, elementName, attrName, attrValue) {
        mi('inspectAttribute');
      }
  
      createAttributeInstruction(resources, element, info, existingInstruction) {
        mi('createAttributeInstruction');
      }
  
      createLetExpressions(resources, element) {
        mi('createLetExpressions');
      }
  
      inspectTextContent(resources, value) {
        mi('inspectTextContent');
      }
    };
  
    let noNodes = Object.freeze([]);
  
    let SlotCustomAttribute = class SlotCustomAttribute {
      static inject() {
        return [DOM.Element];
      }
  
      constructor(element) {
        this.element = element;
        this.element.auSlotAttribute = this;
      }
  
      valueChanged(newValue, oldValue) {}
    };
  
    let PassThroughSlot = class PassThroughSlot {
      constructor(anchor, name, destinationName, fallbackFactory) {
        this.anchor = anchor;
        this.anchor.viewSlot = this;
        this.name = name;
        this.destinationName = destinationName;
        this.fallbackFactory = fallbackFactory;
        this.destinationSlot = null;
        this.projections = 0;
        this.contentView = null;
  
        let attr = new SlotCustomAttribute(this.anchor);
        attr.value = this.destinationName;
      }
  
      get needsFallbackRendering() {
        return this.fallbackFactory && this.projections === 0;
      }
  
      renderFallbackContent(view, nodes, projectionSource, index) {
        if (this.contentView === null) {
          this.contentView = this.fallbackFactory.create(this.ownerView.container);
          this.contentView.bind(this.ownerView.bindingContext, this.ownerView.overrideContext);
  
          let slots = Object.create(null);
          slots[this.destinationSlot.name] = this.destinationSlot;
  
          ShadowDOM.distributeView(this.contentView, slots, projectionSource, index, this.destinationSlot.name);
        }
      }
  
      passThroughTo(destinationSlot) {
        this.destinationSlot = destinationSlot;
      }
  
      addNode(view, node, projectionSource, index) {
        if (this.contentView !== null) {
          this.contentView.removeNodes();
          this.contentView.detached();
          this.contentView.unbind();
          this.contentView = null;
        }
  
        if (node.viewSlot instanceof PassThroughSlot) {
          node.viewSlot.passThroughTo(this);
          return;
        }
  
        this.projections++;
        this.destinationSlot.addNode(view, node, projectionSource, index);
      }
  
      removeView(view, projectionSource) {
        this.projections--;
        this.destinationSlot.removeView(view, projectionSource);
  
        if (this.needsFallbackRendering) {
          this.renderFallbackContent(null, noNodes, projectionSource);
        }
      }
  
      removeAll(projectionSource) {
        this.projections = 0;
        this.destinationSlot.removeAll(projectionSource);
  
        if (this.needsFallbackRendering) {
          this.renderFallbackContent(null, noNodes, projectionSource);
        }
      }
  
      projectFrom(view, projectionSource) {
        this.destinationSlot.projectFrom(view, projectionSource);
      }
  
      created(ownerView) {
        this.ownerView = ownerView;
      }
  
      bind(view) {
        if (this.contentView) {
          this.contentView.bind(view.bindingContext, view.overrideContext);
        }
      }
  
      attached() {
        if (this.contentView) {
          this.contentView.attached();
        }
      }
  
      detached() {
        if (this.contentView) {
          this.contentView.detached();
        }
      }
  
      unbind() {
        if (this.contentView) {
          this.contentView.unbind();
        }
      }
    };
  
    let ShadowSlot = class ShadowSlot {
      constructor(anchor, name, fallbackFactory) {
        this.anchor = anchor;
        this.anchor.isContentProjectionSource = true;
        this.anchor.viewSlot = this;
        this.name = name;
        this.fallbackFactory = fallbackFactory;
        this.contentView = null;
        this.projections = 0;
        this.children = [];
        this.projectFromAnchors = null;
        this.destinationSlots = null;
      }
  
      get needsFallbackRendering() {
        return this.fallbackFactory && this.projections === 0;
      }
  
      addNode(view, node, projectionSource, index, destination) {
        if (this.contentView !== null) {
          this.contentView.removeNodes();
          this.contentView.detached();
          this.contentView.unbind();
          this.contentView = null;
        }
  
        if (node.viewSlot instanceof PassThroughSlot) {
          node.viewSlot.passThroughTo(this);
          return;
        }
  
        if (this.destinationSlots !== null) {
          ShadowDOM.distributeNodes(view, [node], this.destinationSlots, this, index);
        } else {
          node.auOwnerView = view;
          node.auProjectionSource = projectionSource;
          node.auAssignedSlot = this;
  
          let anchor = this._findAnchor(view, node, projectionSource, index);
          let parent = anchor.parentNode;
  
          parent.insertBefore(node, anchor);
          this.children.push(node);
          this.projections++;
        }
      }
  
      removeView(view, projectionSource) {
        if (this.destinationSlots !== null) {
          ShadowDOM.undistributeView(view, this.destinationSlots, this);
        } else if (this.contentView && this.contentView.hasSlots) {
          ShadowDOM.undistributeView(view, this.contentView.slots, projectionSource);
        } else {
          let found = this.children.find(x => x.auSlotProjectFrom === projectionSource);
          if (found) {
            let children = found.auProjectionChildren;
  
            for (let i = 0, ii = children.length; i < ii; ++i) {
              let child = children[i];
  
              if (child.auOwnerView === view) {
                children.splice(i, 1);
                view.fragment.appendChild(child);
                i--;ii--;
                this.projections--;
              }
            }
  
            if (this.needsFallbackRendering) {
              this.renderFallbackContent(view, noNodes, projectionSource);
            }
          }
        }
      }
  
      removeAll(projectionSource) {
        if (this.destinationSlots !== null) {
          ShadowDOM.undistributeAll(this.destinationSlots, this);
        } else if (this.contentView && this.contentView.hasSlots) {
          ShadowDOM.undistributeAll(this.contentView.slots, projectionSource);
        } else {
          let found = this.children.find(x => x.auSlotProjectFrom === projectionSource);
  
          if (found) {
            let children = found.auProjectionChildren;
            for (let i = 0, ii = children.length; i < ii; ++i) {
              let child = children[i];
              child.auOwnerView.fragment.appendChild(child);
              this.projections--;
            }
  
            found.auProjectionChildren = [];
  
            if (this.needsFallbackRendering) {
              this.renderFallbackContent(null, noNodes, projectionSource);
            }
          }
        }
      }
  
      _findAnchor(view, node, projectionSource, index) {
        if (projectionSource) {
          let found = this.children.find(x => x.auSlotProjectFrom === projectionSource);
          if (found) {
            if (index !== undefined) {
              let children = found.auProjectionChildren;
              let viewIndex = -1;
              let lastView;
  
              for (let i = 0, ii = children.length; i < ii; ++i) {
                let current = children[i];
  
                if (current.auOwnerView !== lastView) {
                  viewIndex++;
                  lastView = current.auOwnerView;
  
                  if (viewIndex >= index && lastView !== view) {
                    children.splice(i, 0, node);
                    return current;
                  }
                }
              }
            }
  
            found.auProjectionChildren.push(node);
            return found;
          }
        }
  
        return this.anchor;
      }
  
      projectTo(slots) {
        this.destinationSlots = slots;
      }
  
      projectFrom(view, projectionSource) {
        let anchor = DOM.createComment('anchor');
        let parent = this.anchor.parentNode;
        anchor.auSlotProjectFrom = projectionSource;
        anchor.auOwnerView = view;
        anchor.auProjectionChildren = [];
        parent.insertBefore(anchor, this.anchor);
        this.children.push(anchor);
  
        if (this.projectFromAnchors === null) {
          this.projectFromAnchors = [];
        }
  
        this.projectFromAnchors.push(anchor);
      }
  
      renderFallbackContent(view, nodes, projectionSource, index) {
        if (this.contentView === null) {
          this.contentView = this.fallbackFactory.create(this.ownerView.container);
          this.contentView.bind(this.ownerView.bindingContext, this.ownerView.overrideContext);
          this.contentView.insertNodesBefore(this.anchor);
        }
  
        if (this.contentView.hasSlots) {
          let slots = this.contentView.slots;
          let projectFromAnchors = this.projectFromAnchors;
  
          if (projectFromAnchors !== null) {
            for (let slotName in slots) {
              let slot = slots[slotName];
  
              for (let i = 0, ii = projectFromAnchors.length; i < ii; ++i) {
                let anchor = projectFromAnchors[i];
                slot.projectFrom(anchor.auOwnerView, anchor.auSlotProjectFrom);
              }
            }
          }
  
          this.fallbackSlots = slots;
          ShadowDOM.distributeNodes(view, nodes, slots, projectionSource, index);
        }
      }
  
      created(ownerView) {
        this.ownerView = ownerView;
      }
  
      bind(view) {
        if (this.contentView) {
          this.contentView.bind(view.bindingContext, view.overrideContext);
        }
      }
  
      attached() {
        if (this.contentView) {
          this.contentView.attached();
        }
      }
  
      detached() {
        if (this.contentView) {
          this.contentView.detached();
        }
      }
  
      unbind() {
        if (this.contentView) {
          this.contentView.unbind();
        }
      }
    };
  
    let ShadowDOM = (_temp3 = _class9$1 = class ShadowDOM {
  
      static getSlotName(node) {
        if (node.auSlotAttribute === undefined) {
          return ShadowDOM.defaultSlotKey;
        }
  
        return node.auSlotAttribute.value;
      }
  
      static distributeView(view, slots, projectionSource, index, destinationOverride) {
        let nodes;
  
        if (view === null) {
          nodes = noNodes;
        } else {
          let childNodes = view.fragment.childNodes;
          let ii = childNodes.length;
          nodes = new Array(ii);
  
          for (let i = 0; i < ii; ++i) {
            nodes[i] = childNodes[i];
          }
        }
  
        ShadowDOM.distributeNodes(view, nodes, slots, projectionSource, index, destinationOverride);
      }
  
      static undistributeView(view, slots, projectionSource) {
        for (let slotName in slots) {
          slots[slotName].removeView(view, projectionSource);
        }
      }
  
      static undistributeAll(slots, projectionSource) {
        for (let slotName in slots) {
          slots[slotName].removeAll(projectionSource);
        }
      }
  
      static distributeNodes(view, nodes, slots, projectionSource, index, destinationOverride) {
        for (let i = 0, ii = nodes.length; i < ii; ++i) {
          let currentNode = nodes[i];
          let nodeType = currentNode.nodeType;
  
          if (currentNode.isContentProjectionSource) {
            currentNode.viewSlot.projectTo(slots);
  
            for (let slotName in slots) {
              slots[slotName].projectFrom(view, currentNode.viewSlot);
            }
  
            nodes.splice(i, 1);
            ii--;i--;
          } else if (nodeType === 1 || nodeType === 3 || currentNode.viewSlot instanceof PassThroughSlot) {
            if (nodeType === 3 && _isAllWhitespace(currentNode)) {
              nodes.splice(i, 1);
              ii--;i--;
            } else {
              let found = slots[destinationOverride || ShadowDOM.getSlotName(currentNode)];
  
              if (found) {
                found.addNode(view, currentNode, projectionSource, index);
                nodes.splice(i, 1);
                ii--;i--;
              }
            }
          } else {
            nodes.splice(i, 1);
            ii--;i--;
          }
        }
  
        for (let slotName in slots) {
          let slot = slots[slotName];
  
          if (slot.needsFallbackRendering) {
            slot.renderFallbackContent(view, nodes, projectionSource, index);
          }
        }
      }
    }, _class9$1.defaultSlotKey = '__au-default-slot-key__', _temp3);
  
    function register(lookup, name, resource, type) {
      if (!name) {
        return;
      }
  
      let existing = lookup[name];
      if (existing) {
        if (existing !== resource) {
          throw new Error(`Attempted to register ${type} when one with the same name already exists. Name: ${name}.`);
        }
  
        return;
      }
  
      lookup[name] = resource;
    }
  
    function validateBehaviorName(name, type) {
      if (/[A-Z]/.test(name)) {
        let newName = _hyphenate(name);
        getLogger('templating').warn(`'${name}' is not a valid ${type} name and has been converted to '${newName}'. Upper-case letters are not allowed because the DOM is not case-sensitive.`);
        return newName;
      }
      return name;
    }
  
    const conventionMark = '__au_resource__';
  
    let ViewResources = class ViewResources {
      static convention(target, existing) {
        let resource;
  
        if (existing && conventionMark in existing) {
          return existing;
        }
        if ('$resource' in target) {
          let config = target.$resource;
  
          if (typeof config === 'string') {
            resource = existing || new HtmlBehaviorResource();
            resource[conventionMark] = true;
            if (!resource.elementName) {
              resource.elementName = validateBehaviorName(config, 'custom element');
            }
          } else {
            if (typeof config === 'function') {
              config = config.call(target);
            }
            if (typeof config === 'string') {
              config = { name: config };
            }
  
            config = Object.assign({}, config);
  
            let resourceType = config.type || 'element';
  
            let name = config.name;
            switch (resourceType) {
              case 'element':case 'attribute':
                resource = existing || new HtmlBehaviorResource();
                resource[conventionMark] = true;
                if (resourceType === 'element') {
                  if (!resource.elementName) {
                    resource.elementName = name ? validateBehaviorName(name, 'custom element') : _hyphenate(target.name);
                  }
                } else {
                  if (!resource.attributeName) {
                    resource.attributeName = name ? validateBehaviorName(name, 'custom attribute') : _hyphenate(target.name);
                  }
                }
                if ('templateController' in config) {
                  config.liftsContent = config.templateController;
                  delete config.templateController;
                }
                if ('defaultBindingMode' in config && resource.attributeDefaultBindingMode !== undefined) {
                  config.attributeDefaultBindingMode = config.defaultBindingMode;
                  delete config.defaultBindingMode;
                }
  
                delete config.name;
  
                Object.assign(resource, config);
                break;
              case 'valueConverter':
                resource = new ValueConverterResource(camelCase(name || target.name));
                break;
              case 'bindingBehavior':
                resource = new BindingBehaviorResource(camelCase(name || target.name));
                break;
              case 'viewEngineHooks':
                resource = new ViewEngineHooksResource();
                break;
            }
          }
  
          if (resource instanceof HtmlBehaviorResource) {
            let bindables = typeof config === 'string' ? undefined : config.bindables;
            let currentProps = resource.properties;
            if (Array.isArray(bindables)) {
              for (let i = 0, ii = bindables.length; ii > i; ++i) {
                let prop = bindables[i];
                if (!prop || typeof prop !== 'string' && !prop.name) {
                  throw new Error(`Invalid bindable property at "${i}" for class "${target.name}". Expected either a string or an object with "name" property.`);
                }
                let newProp = new BindableProperty(prop);
  
                let existed = false;
                for (let j = 0, jj = currentProps.length; jj > j; ++j) {
                  if (currentProps[j].name === newProp.name) {
                    existed = true;
                    break;
                  }
                }
                if (existed) {
                  continue;
                }
                newProp.registerWith(target, resource);
              }
            }
          }
        }
        return resource;
      }
  
      constructor(parent, viewUrl) {
        this.bindingLanguage = null;
  
        this.parent = parent || null;
        this.hasParent = this.parent !== null;
        this.viewUrl = viewUrl || '';
        this.lookupFunctions = {
          valueConverters: this.getValueConverter.bind(this),
          bindingBehaviors: this.getBindingBehavior.bind(this)
        };
        this.attributes = Object.create(null);
        this.elements = Object.create(null);
        this.valueConverters = Object.create(null);
        this.bindingBehaviors = Object.create(null);
        this.attributeMap = Object.create(null);
        this.values = Object.create(null);
        this.beforeCompile = this.afterCompile = this.beforeCreate = this.afterCreate = this.beforeBind = this.beforeUnbind = false;
      }
  
      _tryAddHook(obj, name) {
        if (typeof obj[name] === 'function') {
          let func = obj[name].bind(obj);
          let counter = 1;
          let callbackName;
  
          while (this[callbackName = name + counter.toString()] !== undefined) {
            counter++;
          }
  
          this[name] = true;
          this[callbackName] = func;
        }
      }
  
      _invokeHook(name, one, two, three, four) {
        if (this.hasParent) {
          this.parent._invokeHook(name, one, two, three, four);
        }
  
        if (this[name]) {
          this[name + '1'](one, two, three, four);
  
          let callbackName = name + '2';
          if (this[callbackName]) {
            this[callbackName](one, two, three, four);
  
            callbackName = name + '3';
            if (this[callbackName]) {
              this[callbackName](one, two, three, four);
  
              let counter = 4;
  
              while (this[callbackName = name + counter.toString()] !== undefined) {
                this[callbackName](one, two, three, four);
                counter++;
              }
            }
          }
        }
      }
  
      registerViewEngineHooks(hooks) {
        this._tryAddHook(hooks, 'beforeCompile');
        this._tryAddHook(hooks, 'afterCompile');
        this._tryAddHook(hooks, 'beforeCreate');
        this._tryAddHook(hooks, 'afterCreate');
        this._tryAddHook(hooks, 'beforeBind');
        this._tryAddHook(hooks, 'beforeUnbind');
      }
  
      getBindingLanguage(bindingLanguageFallback) {
        return this.bindingLanguage || (this.bindingLanguage = bindingLanguageFallback);
      }
  
      patchInParent(newParent) {
        let originalParent = this.parent;
  
        this.parent = newParent || null;
        this.hasParent = this.parent !== null;
  
        if (newParent.parent === null) {
          newParent.parent = originalParent;
          newParent.hasParent = originalParent !== null;
        }
      }
  
      relativeToView(path) {
        return relativeToFile(path, this.viewUrl);
      }
  
      registerElement(tagName, behavior) {
        register(this.elements, tagName, behavior, 'an Element');
      }
  
      getElement(tagName) {
        return this.elements[tagName] || (this.hasParent ? this.parent.getElement(tagName) : null);
      }
  
      mapAttribute(attribute) {
        return this.attributeMap[attribute] || (this.hasParent ? this.parent.mapAttribute(attribute) : null);
      }
  
      registerAttribute(attribute, behavior, knownAttribute) {
        this.attributeMap[attribute] = knownAttribute;
        register(this.attributes, attribute, behavior, 'an Attribute');
      }
  
      getAttribute(attribute) {
        return this.attributes[attribute] || (this.hasParent ? this.parent.getAttribute(attribute) : null);
      }
  
      registerValueConverter(name, valueConverter) {
        register(this.valueConverters, name, valueConverter, 'a ValueConverter');
      }
  
      getValueConverter(name) {
        return this.valueConverters[name] || (this.hasParent ? this.parent.getValueConverter(name) : null);
      }
  
      registerBindingBehavior(name, bindingBehavior) {
        register(this.bindingBehaviors, name, bindingBehavior, 'a BindingBehavior');
      }
  
      getBindingBehavior(name) {
        return this.bindingBehaviors[name] || (this.hasParent ? this.parent.getBindingBehavior(name) : null);
      }
  
      registerValue(name, value) {
        register(this.values, name, value, 'a value');
      }
  
      getValue(name) {
        return this.values[name] || (this.hasParent ? this.parent.getValue(name) : null);
      }
  
      autoRegister(container, impl) {
        let resourceTypeMeta = metadata.getOwn(metadata.resource, impl);
        if (resourceTypeMeta) {
          if (resourceTypeMeta instanceof HtmlBehaviorResource) {
            ViewResources.convention(impl, resourceTypeMeta);
  
            if (resourceTypeMeta.attributeName === null && resourceTypeMeta.elementName === null) {
              HtmlBehaviorResource.convention(impl.name, resourceTypeMeta);
            }
            if (resourceTypeMeta.attributeName === null && resourceTypeMeta.elementName === null) {
              resourceTypeMeta.elementName = _hyphenate(impl.name);
            }
          }
        } else {
          resourceTypeMeta = ViewResources.convention(impl) || HtmlBehaviorResource.convention(impl.name) || ValueConverterResource.convention(impl.name) || BindingBehaviorResource.convention(impl.name) || ViewEngineHooksResource.convention(impl.name);
          if (!resourceTypeMeta) {
            resourceTypeMeta = new HtmlBehaviorResource();
            resourceTypeMeta.elementName = _hyphenate(impl.name);
          }
          metadata.define(metadata.resource, resourceTypeMeta, impl);
        }
        resourceTypeMeta.initialize(container, impl);
        resourceTypeMeta.register(this);
        return resourceTypeMeta;
      }
    };
  
    let View = class View {
      constructor(container, viewFactory, fragment, controllers, bindings, children, slots) {
        this.container = container;
        this.viewFactory = viewFactory;
        this.resources = viewFactory.resources;
        this.fragment = fragment;
        this.firstChild = fragment.firstChild;
        this.lastChild = fragment.lastChild;
        this.controllers = controllers;
        this.bindings = bindings;
        this.children = children;
        this.slots = slots;
        this.hasSlots = false;
        this.fromCache = false;
        this.isBound = false;
        this.isAttached = false;
        this.bindingContext = null;
        this.overrideContext = null;
        this.controller = null;
        this.viewModelScope = null;
        this.animatableElement = undefined;
        this._isUserControlled = false;
        this.contentView = null;
  
        for (let key in slots) {
          this.hasSlots = true;
          break;
        }
      }
  
      returnToCache() {
        this.viewFactory.returnViewToCache(this);
      }
  
      created() {
        let i;
        let ii;
        let controllers = this.controllers;
  
        for (i = 0, ii = controllers.length; i < ii; ++i) {
          controllers[i].created(this);
        }
      }
  
      bind(bindingContext, overrideContext, _systemUpdate) {
        let controllers;
        let bindings;
        let children;
        let i;
        let ii;
  
        if (_systemUpdate && this._isUserControlled) {
          return;
        }
  
        if (this.isBound) {
          if (this.bindingContext === bindingContext) {
            return;
          }
  
          this.unbind();
        }
  
        this.isBound = true;
        this.bindingContext = bindingContext;
        this.overrideContext = overrideContext || createOverrideContext(bindingContext);
  
        this.resources._invokeHook('beforeBind', this);
  
        bindings = this.bindings;
        for (i = 0, ii = bindings.length; i < ii; ++i) {
          bindings[i].bind(this);
        }
  
        if (this.viewModelScope !== null) {
          bindingContext.bind(this.viewModelScope.bindingContext, this.viewModelScope.overrideContext);
          this.viewModelScope = null;
        }
  
        controllers = this.controllers;
        for (i = 0, ii = controllers.length; i < ii; ++i) {
          controllers[i].bind(this);
        }
  
        children = this.children;
        for (i = 0, ii = children.length; i < ii; ++i) {
          children[i].bind(bindingContext, overrideContext, true);
        }
  
        if (this.hasSlots) {
          ShadowDOM.distributeView(this.contentView, this.slots);
        }
      }
  
      addBinding(binding) {
        this.bindings.push(binding);
  
        if (this.isBound) {
          binding.bind(this);
        }
      }
  
      unbind() {
        let controllers;
        let bindings;
        let children;
        let i;
        let ii;
  
        if (this.isBound) {
          this.isBound = false;
          this.resources._invokeHook('beforeUnbind', this);
  
          if (this.controller !== null) {
            this.controller.unbind();
          }
  
          bindings = this.bindings;
          for (i = 0, ii = bindings.length; i < ii; ++i) {
            bindings[i].unbind();
          }
  
          controllers = this.controllers;
          for (i = 0, ii = controllers.length; i < ii; ++i) {
            controllers[i].unbind();
          }
  
          children = this.children;
          for (i = 0, ii = children.length; i < ii; ++i) {
            children[i].unbind();
          }
  
          this.bindingContext = null;
          this.overrideContext = null;
        }
      }
  
      insertNodesBefore(refNode) {
        refNode.parentNode.insertBefore(this.fragment, refNode);
      }
  
      appendNodesTo(parent) {
        parent.appendChild(this.fragment);
      }
  
      removeNodes() {
        let fragment = this.fragment;
        let current = this.firstChild;
        let end = this.lastChild;
        let next;
  
        while (current) {
          next = current.nextSibling;
          fragment.appendChild(current);
  
          if (current === end) {
            break;
          }
  
          current = next;
        }
      }
  
      attached() {
        let controllers;
        let children;
        let i;
        let ii;
  
        if (this.isAttached) {
          return;
        }
  
        this.isAttached = true;
  
        if (this.controller !== null) {
          this.controller.attached();
        }
  
        controllers = this.controllers;
        for (i = 0, ii = controllers.length; i < ii; ++i) {
          controllers[i].attached();
        }
  
        children = this.children;
        for (i = 0, ii = children.length; i < ii; ++i) {
          children[i].attached();
        }
      }
  
      detached() {
        let controllers;
        let children;
        let i;
        let ii;
  
        if (this.isAttached) {
          this.isAttached = false;
  
          if (this.controller !== null) {
            this.controller.detached();
          }
  
          controllers = this.controllers;
          for (i = 0, ii = controllers.length; i < ii; ++i) {
            controllers[i].detached();
          }
  
          children = this.children;
          for (i = 0, ii = children.length; i < ii; ++i) {
            children[i].detached();
          }
        }
      }
    };
  
    function getAnimatableElement(view) {
      if (view.animatableElement !== undefined) {
        return view.animatableElement;
      }
  
      let current = view.firstChild;
  
      while (current && current.nodeType !== 1) {
        current = current.nextSibling;
      }
  
      if (current && current.nodeType === 1) {
        return view.animatableElement = current.classList.contains('au-animate') ? current : null;
      }
  
      return view.animatableElement = null;
    }
  
    let ViewSlot = class ViewSlot {
      constructor(anchor, anchorIsContainer, animator = Animator.instance) {
        this.anchor = anchor;
        this.anchorIsContainer = anchorIsContainer;
        this.bindingContext = null;
        this.overrideContext = null;
        this.animator = animator;
        this.children = [];
        this.isBound = false;
        this.isAttached = false;
        this.contentSelectors = null;
        anchor.viewSlot = this;
        anchor.isContentProjectionSource = false;
      }
  
      animateView(view, direction = 'enter') {
        let animatableElement = getAnimatableElement(view);
  
        if (animatableElement !== null) {
          switch (direction) {
            case 'enter':
              return this.animator.enter(animatableElement);
            case 'leave':
              return this.animator.leave(animatableElement);
            default:
              throw new Error('Invalid animation direction: ' + direction);
          }
        }
      }
  
      transformChildNodesIntoView() {
        let parent = this.anchor;
  
        this.children.push({
          fragment: parent,
          firstChild: parent.firstChild,
          lastChild: parent.lastChild,
          returnToCache() {},
          removeNodes() {
            let last;
  
            while (last = parent.lastChild) {
              parent.removeChild(last);
            }
          },
          created() {},
          bind() {},
          unbind() {},
          attached() {},
          detached() {}
        });
      }
  
      bind(bindingContext, overrideContext) {
        let i;
        let ii;
        let children;
  
        if (this.isBound) {
          if (this.bindingContext === bindingContext) {
            return;
          }
  
          this.unbind();
        }
  
        this.isBound = true;
        this.bindingContext = bindingContext = bindingContext || this.bindingContext;
        this.overrideContext = overrideContext = overrideContext || this.overrideContext;
  
        children = this.children;
        for (i = 0, ii = children.length; i < ii; ++i) {
          children[i].bind(bindingContext, overrideContext, true);
        }
      }
  
      unbind() {
        if (this.isBound) {
          let i;
          let ii;
          let children = this.children;
  
          this.isBound = false;
          this.bindingContext = null;
          this.overrideContext = null;
  
          for (i = 0, ii = children.length; i < ii; ++i) {
            children[i].unbind();
          }
        }
      }
  
      add(view) {
        if (this.anchorIsContainer) {
          view.appendNodesTo(this.anchor);
        } else {
          view.insertNodesBefore(this.anchor);
        }
  
        this.children.push(view);
  
        if (this.isAttached) {
          view.attached();
          return this.animateView(view, 'enter');
        }
      }
  
      insert(index, view) {
        let children = this.children;
        let length = children.length;
  
        if (index === 0 && length === 0 || index >= length) {
          return this.add(view);
        }
  
        view.insertNodesBefore(children[index].firstChild);
        children.splice(index, 0, view);
  
        if (this.isAttached) {
          view.attached();
          return this.animateView(view, 'enter');
        }
      }
  
      move(sourceIndex, targetIndex) {
        if (sourceIndex === targetIndex) {
          return;
        }
  
        const children = this.children;
        const view = children[sourceIndex];
  
        view.removeNodes();
        view.insertNodesBefore(children[targetIndex].firstChild);
        children.splice(sourceIndex, 1);
        children.splice(targetIndex, 0, view);
      }
  
      remove(view, returnToCache, skipAnimation) {
        return this.removeAt(this.children.indexOf(view), returnToCache, skipAnimation);
      }
  
      removeMany(viewsToRemove, returnToCache, skipAnimation) {
        const children = this.children;
        let ii = viewsToRemove.length;
        let i;
        let rmPromises = [];
  
        viewsToRemove.forEach(child => {
          if (skipAnimation) {
            child.removeNodes();
            return;
          }
  
          let animation = this.animateView(child, 'leave');
          if (animation) {
            rmPromises.push(animation.then(() => child.removeNodes()));
          } else {
            child.removeNodes();
          }
        });
  
        let removeAction = () => {
          if (this.isAttached) {
            for (i = 0; i < ii; ++i) {
              viewsToRemove[i].detached();
            }
          }
  
          if (returnToCache) {
            for (i = 0; i < ii; ++i) {
              viewsToRemove[i].returnToCache();
            }
          }
  
          for (i = 0; i < ii; ++i) {
            const index = children.indexOf(viewsToRemove[i]);
            if (index >= 0) {
              children.splice(index, 1);
            }
          }
        };
  
        if (rmPromises.length > 0) {
          return Promise.all(rmPromises).then(() => removeAction());
        }
  
        return removeAction();
      }
  
      removeAt(index, returnToCache, skipAnimation) {
        let view = this.children[index];
  
        let removeAction = () => {
          index = this.children.indexOf(view);
          view.removeNodes();
          this.children.splice(index, 1);
  
          if (this.isAttached) {
            view.detached();
          }
  
          if (returnToCache) {
            view.returnToCache();
          }
  
          return view;
        };
  
        if (!skipAnimation) {
          let animation = this.animateView(view, 'leave');
          if (animation) {
            return animation.then(() => removeAction());
          }
        }
  
        return removeAction();
      }
  
      removeAll(returnToCache, skipAnimation) {
        let children = this.children;
        let ii = children.length;
        let i;
        let rmPromises = [];
  
        children.forEach(child => {
          if (skipAnimation) {
            child.removeNodes();
            return;
          }
  
          let animation = this.animateView(child, 'leave');
          if (animation) {
            rmPromises.push(animation.then(() => child.removeNodes()));
          } else {
            child.removeNodes();
          }
        });
  
        let removeAction = () => {
          if (this.isAttached) {
            for (i = 0; i < ii; ++i) {
              children[i].detached();
            }
          }
  
          if (returnToCache) {
            for (i = 0; i < ii; ++i) {
              const child = children[i];
  
              if (child) {
                child.returnToCache();
              }
            }
          }
  
          this.children = [];
        };
  
        if (rmPromises.length > 0) {
          return Promise.all(rmPromises).then(() => removeAction());
        }
  
        return removeAction();
      }
  
      attached() {
        let i;
        let ii;
        let children;
        let child;
  
        if (this.isAttached) {
          return;
        }
  
        this.isAttached = true;
  
        children = this.children;
        for (i = 0, ii = children.length; i < ii; ++i) {
          child = children[i];
          child.attached();
          this.animateView(child, 'enter');
        }
      }
  
      detached() {
        let i;
        let ii;
        let children;
  
        if (this.isAttached) {
          this.isAttached = false;
          children = this.children;
          for (i = 0, ii = children.length; i < ii; ++i) {
            children[i].detached();
          }
        }
      }
  
      projectTo(slots) {
        this.projectToSlots = slots;
        this.add = this._projectionAdd;
        this.insert = this._projectionInsert;
        this.move = this._projectionMove;
        this.remove = this._projectionRemove;
        this.removeAt = this._projectionRemoveAt;
        this.removeMany = this._projectionRemoveMany;
        this.removeAll = this._projectionRemoveAll;
        this.children.forEach(view => ShadowDOM.distributeView(view, slots, this));
      }
  
      _projectionAdd(view) {
        ShadowDOM.distributeView(view, this.projectToSlots, this);
  
        this.children.push(view);
  
        if (this.isAttached) {
          view.attached();
        }
      }
  
      _projectionInsert(index, view) {
        if (index === 0 && !this.children.length || index >= this.children.length) {
          this.add(view);
        } else {
          ShadowDOM.distributeView(view, this.projectToSlots, this, index);
  
          this.children.splice(index, 0, view);
  
          if (this.isAttached) {
            view.attached();
          }
        }
      }
  
      _projectionMove(sourceIndex, targetIndex) {
        if (sourceIndex === targetIndex) {
          return;
        }
  
        const children = this.children;
        const view = children[sourceIndex];
  
        ShadowDOM.undistributeView(view, this.projectToSlots, this);
        ShadowDOM.distributeView(view, this.projectToSlots, this, targetIndex);
  
        children.splice(sourceIndex, 1);
        children.splice(targetIndex, 0, view);
      }
  
      _projectionRemove(view, returnToCache) {
        ShadowDOM.undistributeView(view, this.projectToSlots, this);
        this.children.splice(this.children.indexOf(view), 1);
  
        if (this.isAttached) {
          view.detached();
        }
        if (returnToCache) {
          view.returnToCache();
        }
      }
  
      _projectionRemoveAt(index, returnToCache) {
        let view = this.children[index];
  
        ShadowDOM.undistributeView(view, this.projectToSlots, this);
        this.children.splice(index, 1);
  
        if (this.isAttached) {
          view.detached();
        }
        if (returnToCache) {
          view.returnToCache();
        }
      }
  
      _projectionRemoveMany(viewsToRemove, returnToCache) {
        viewsToRemove.forEach(view => this.remove(view, returnToCache));
      }
  
      _projectionRemoveAll(returnToCache) {
        ShadowDOM.undistributeAll(this.projectToSlots, this);
  
        let children = this.children;
        let ii = children.length;
  
        for (let i = 0; i < ii; ++i) {
          if (returnToCache) {
            children[i].returnToCache();
          } else if (this.isAttached) {
            children[i].detached();
          }
        }
  
        this.children = [];
      }
    };
  
    let ProviderResolver = resolver(_class11$1 = class ProviderResolver {
      get(container, key) {
        let id = key.__providerId__;
        return id in container ? container[id] : container[id] = container.invoke(key);
      }
    }) || _class11$1;
  
    let providerResolverInstance = new ProviderResolver();
  
    function elementContainerGet(key) {
      if (key === DOM.Element) {
        return this.element;
      }
  
      if (key === BoundViewFactory) {
        if (this.boundViewFactory) {
          return this.boundViewFactory;
        }
  
        let factory = this.instruction.viewFactory;
        let partReplacements = this.partReplacements;
  
        if (partReplacements) {
          factory = partReplacements[factory.part] || factory;
        }
  
        this.boundViewFactory = new BoundViewFactory(this, factory, partReplacements);
        return this.boundViewFactory;
      }
  
      if (key === ViewSlot) {
        if (this.viewSlot === undefined) {
          this.viewSlot = new ViewSlot(this.element, this.instruction.anchorIsContainer);
          this.element.isContentProjectionSource = this.instruction.lifting;
          this.children.push(this.viewSlot);
        }
  
        return this.viewSlot;
      }
  
      if (key === ElementEvents) {
        return this.elementEvents || (this.elementEvents = new ElementEvents(this.element));
      }
  
      if (key === CompositionTransaction) {
        return this.compositionTransaction || (this.compositionTransaction = this.parent.get(key));
      }
  
      if (key === ViewResources) {
        return this.viewResources;
      }
  
      if (key === TargetInstruction) {
        return this.instruction;
      }
  
      return this.superGet(key);
    }
  
    function createElementContainer(parent, element, instruction, children, partReplacements, resources) {
      let container = parent.createChild();
      let providers;
      let i;
  
      container.element = element;
      container.instruction = instruction;
      container.children = children;
      container.viewResources = resources;
      container.partReplacements = partReplacements;
  
      providers = instruction.providers;
      i = providers.length;
  
      while (i--) {
        container._resolvers.set(providers[i], providerResolverInstance);
      }
  
      container.superGet = container.get;
      container.get = elementContainerGet;
  
      return container;
    }
  
    function hasAttribute(name) {
      return this._element.hasAttribute(name);
    }
  
    function getAttribute(name) {
      return this._element.getAttribute(name);
    }
  
    function setAttribute(name, value) {
      this._element.setAttribute(name, value);
    }
  
    function makeElementIntoAnchor(element, elementInstruction) {
      let anchor = DOM.createComment('anchor');
  
      if (elementInstruction) {
        let firstChild = element.firstChild;
  
        if (firstChild && firstChild.tagName === 'AU-CONTENT') {
          anchor.contentElement = firstChild;
        }
  
        anchor._element = element;
  
        anchor.hasAttribute = hasAttribute;
        anchor.getAttribute = getAttribute;
        anchor.setAttribute = setAttribute;
      }
  
      DOM.replaceNode(anchor, element);
  
      return anchor;
    }
  
    function applyInstructions(containers, element, instruction, controllers, bindings, children, shadowSlots, partReplacements, resources) {
      let behaviorInstructions = instruction.behaviorInstructions;
      let expressions = instruction.expressions;
      let elementContainer;
      let i;
      let ii;
      let current;
      let instance;
  
      if (instruction.contentExpression) {
        bindings.push(instruction.contentExpression.createBinding(element.nextSibling));
        element.nextSibling.auInterpolationTarget = true;
        element.parentNode.removeChild(element);
        return;
      }
  
      if (instruction.shadowSlot) {
        let commentAnchor = DOM.createComment('slot');
        let slot;
  
        if (instruction.slotDestination) {
          slot = new PassThroughSlot(commentAnchor, instruction.slotName, instruction.slotDestination, instruction.slotFallbackFactory);
        } else {
          slot = new ShadowSlot(commentAnchor, instruction.slotName, instruction.slotFallbackFactory);
        }
  
        DOM.replaceNode(commentAnchor, element);
        shadowSlots[instruction.slotName] = slot;
        controllers.push(slot);
        return;
      }
  
      if (instruction.letElement) {
        for (i = 0, ii = expressions.length; i < ii; ++i) {
          bindings.push(expressions[i].createBinding());
        }
        element.parentNode.removeChild(element);
        return;
      }
  
      if (behaviorInstructions.length) {
        if (!instruction.anchorIsContainer) {
          element = makeElementIntoAnchor(element, instruction.elementInstruction);
        }
  
        containers[instruction.injectorId] = elementContainer = createElementContainer(containers[instruction.parentInjectorId], element, instruction, children, partReplacements, resources);
  
        for (i = 0, ii = behaviorInstructions.length; i < ii; ++i) {
          current = behaviorInstructions[i];
          instance = current.type.create(elementContainer, current, element, bindings);
          controllers.push(instance);
        }
      }
  
      for (i = 0, ii = expressions.length; i < ii; ++i) {
        bindings.push(expressions[i].createBinding(element));
      }
    }
  
    function styleStringToObject(style, target) {
      let attributes = style.split(';');
      let firstIndexOfColon;
      let i;
      let current;
      let key;
      let value;
  
      target = target || {};
  
      for (i = 0; i < attributes.length; i++) {
        current = attributes[i];
        firstIndexOfColon = current.indexOf(':');
        key = current.substring(0, firstIndexOfColon).trim();
        value = current.substring(firstIndexOfColon + 1).trim();
        target[key] = value;
      }
  
      return target;
    }
  
    function styleObjectToString(obj) {
      let result = '';
  
      for (let key in obj) {
        result += key + ':' + obj[key] + ';';
      }
  
      return result;
    }
  
    function applySurrogateInstruction(container, element, instruction, controllers, bindings, children) {
      let behaviorInstructions = instruction.behaviorInstructions;
      let expressions = instruction.expressions;
      let providers = instruction.providers;
      let values = instruction.values;
      let i;
      let ii;
      let current;
      let instance;
      let currentAttributeValue;
  
      i = providers.length;
      while (i--) {
        container._resolvers.set(providers[i], providerResolverInstance);
      }
  
      for (let key in values) {
        currentAttributeValue = element.getAttribute(key);
  
        if (currentAttributeValue) {
          if (key === 'class') {
            element.setAttribute('class', currentAttributeValue + ' ' + values[key]);
          } else if (key === 'style') {
            let styleObject = styleStringToObject(values[key]);
            styleStringToObject(currentAttributeValue, styleObject);
            element.setAttribute('style', styleObjectToString(styleObject));
          }
        } else {
          element.setAttribute(key, values[key]);
        }
      }
  
      if (behaviorInstructions.length) {
        for (i = 0, ii = behaviorInstructions.length; i < ii; ++i) {
          current = behaviorInstructions[i];
          instance = current.type.create(container, current, element, bindings);
  
          if (instance.contentView) {
            children.push(instance.contentView);
          }
  
          controllers.push(instance);
        }
      }
  
      for (i = 0, ii = expressions.length; i < ii; ++i) {
        bindings.push(expressions[i].createBinding(element));
      }
    }
  
    let BoundViewFactory = class BoundViewFactory {
      constructor(parentContainer, viewFactory, partReplacements) {
        this.parentContainer = parentContainer;
        this.viewFactory = viewFactory;
        this.factoryCreateInstruction = { partReplacements: partReplacements };
      }
  
      create() {
        let view = this.viewFactory.create(this.parentContainer.createChild(), this.factoryCreateInstruction);
        view._isUserControlled = true;
        return view;
      }
  
      get isCaching() {
        return this.viewFactory.isCaching;
      }
  
      setCacheSize(size, doNotOverrideIfAlreadySet) {
        this.viewFactory.setCacheSize(size, doNotOverrideIfAlreadySet);
      }
  
      getCachedView() {
        return this.viewFactory.getCachedView();
      }
  
      returnViewToCache(view) {
        this.viewFactory.returnViewToCache(view);
      }
    };
  
    let ViewFactory = class ViewFactory {
      constructor(template, instructions, resources) {
        this.isCaching = false;
  
        this.template = template;
        this.instructions = instructions;
        this.resources = resources;
        this.cacheSize = -1;
        this.cache = null;
      }
  
      setCacheSize(size, doNotOverrideIfAlreadySet) {
        if (size) {
          if (size === '*') {
            size = Number.MAX_VALUE;
          } else if (typeof size === 'string') {
            size = parseInt(size, 10);
          }
        }
  
        if (this.cacheSize === -1 || !doNotOverrideIfAlreadySet) {
          this.cacheSize = size;
        }
  
        if (this.cacheSize > 0) {
          this.cache = [];
        } else {
          this.cache = null;
        }
  
        this.isCaching = this.cacheSize > 0;
      }
  
      getCachedView() {
        return this.cache !== null ? this.cache.pop() || null : null;
      }
  
      returnViewToCache(view) {
        if (view.isAttached) {
          view.detached();
        }
  
        if (view.isBound) {
          view.unbind();
        }
  
        if (this.cache !== null && this.cache.length < this.cacheSize) {
          view.fromCache = true;
          this.cache.push(view);
        }
      }
  
      create(container, createInstruction, element) {
        createInstruction = createInstruction || BehaviorInstruction.normal;
  
        let cachedView = this.getCachedView();
        if (cachedView !== null) {
          return cachedView;
        }
  
        let fragment = createInstruction.enhance ? this.template : this.template.cloneNode(true);
        let instructables = fragment.querySelectorAll('.au-target');
        let instructions = this.instructions;
        let resources = this.resources;
        let controllers = [];
        let bindings = [];
        let children = [];
        let shadowSlots = Object.create(null);
        let containers = { root: container };
        let partReplacements = createInstruction.partReplacements;
        let i;
        let ii;
        let view;
        let instructable;
        let instruction;
  
        this.resources._invokeHook('beforeCreate', this, container, fragment, createInstruction);
  
        if (element && this.surrogateInstruction !== null) {
          applySurrogateInstruction(container, element, this.surrogateInstruction, controllers, bindings, children);
        }
  
        if (createInstruction.enhance && fragment.hasAttribute('au-target-id')) {
          instructable = fragment;
          instruction = instructions[instructable.getAttribute('au-target-id')];
          applyInstructions(containers, instructable, instruction, controllers, bindings, children, shadowSlots, partReplacements, resources);
        }
  
        for (i = 0, ii = instructables.length; i < ii; ++i) {
          instructable = instructables[i];
          instruction = instructions[instructable.getAttribute('au-target-id')];
          applyInstructions(containers, instructable, instruction, controllers, bindings, children, shadowSlots, partReplacements, resources);
        }
  
        view = new View(container, this, fragment, controllers, bindings, children, shadowSlots);
  
        if (!createInstruction.initiatedByBehavior) {
          view.created();
        }
  
        this.resources._invokeHook('afterCreate', view);
  
        return view;
      }
    };
  
    let nextInjectorId = 0;
    function getNextInjectorId() {
      return ++nextInjectorId;
    }
  
    let lastAUTargetID = 0;
    function getNextAUTargetID() {
      return (++lastAUTargetID).toString();
    }
  
    function makeIntoInstructionTarget(element) {
      let value = element.getAttribute('class');
      let auTargetID = getNextAUTargetID();
  
      element.setAttribute('class', value ? value + ' au-target' : 'au-target');
      element.setAttribute('au-target-id', auTargetID);
  
      return auTargetID;
    }
  
    function makeShadowSlot(compiler, resources, node, instructions, parentInjectorId) {
      let auShadowSlot = DOM.createElement('au-shadow-slot');
      DOM.replaceNode(auShadowSlot, node);
  
      let auTargetID = makeIntoInstructionTarget(auShadowSlot);
      let instruction = TargetInstruction.shadowSlot(parentInjectorId);
  
      instruction.slotName = node.getAttribute('name') || ShadowDOM.defaultSlotKey;
      instruction.slotDestination = node.getAttribute('slot');
  
      if (node.innerHTML.trim()) {
        let fragment = DOM.createDocumentFragment();
        let child;
  
        while (child = node.firstChild) {
          fragment.appendChild(child);
        }
  
        instruction.slotFallbackFactory = compiler.compile(fragment, resources);
      }
  
      instructions[auTargetID] = instruction;
  
      return auShadowSlot;
    }
  
    const defaultLetHandler = BindingLanguage.prototype.createLetExpressions;
  
    let ViewCompiler = (_dec7$2 = inject(BindingLanguage, ViewResources), _dec7$2(_class13$1 = class ViewCompiler {
      constructor(bindingLanguage, resources) {
        this.bindingLanguage = bindingLanguage;
        this.resources = resources;
      }
  
      compile(source, resources, compileInstruction) {
        resources = resources || this.resources;
        compileInstruction = compileInstruction || ViewCompileInstruction.normal;
        source = typeof source === 'string' ? DOM.createTemplateFromMarkup(source) : source;
  
        let content;
        let part;
        let cacheSize;
  
        if (source.content) {
          part = source.getAttribute('part');
          cacheSize = source.getAttribute('view-cache');
          content = DOM.adoptNode(source.content);
        } else {
          content = source;
        }
  
        compileInstruction.targetShadowDOM = compileInstruction.targetShadowDOM && FEATURE.shadowDOM;
        resources._invokeHook('beforeCompile', content, resources, compileInstruction);
  
        let instructions = {};
        this._compileNode(content, resources, instructions, source, 'root', !compileInstruction.targetShadowDOM);
  
        let firstChild = content.firstChild;
        if (firstChild && firstChild.nodeType === 1) {
          let targetId = firstChild.getAttribute('au-target-id');
          if (targetId) {
            let ins = instructions[targetId];
  
            if (ins.shadowSlot || ins.lifting || ins.elementInstruction && !ins.elementInstruction.anchorIsContainer) {
              content.insertBefore(DOM.createComment('view'), firstChild);
            }
          }
        }
  
        let factory = new ViewFactory(content, instructions, resources);
  
        factory.surrogateInstruction = compileInstruction.compileSurrogate ? this._compileSurrogate(source, resources) : null;
        factory.part = part;
  
        if (cacheSize) {
          factory.setCacheSize(cacheSize);
        }
  
        resources._invokeHook('afterCompile', factory);
  
        return factory;
      }
  
      _compileNode(node, resources, instructions, parentNode, parentInjectorId, targetLightDOM) {
        switch (node.nodeType) {
          case 1:
            return this._compileElement(node, resources, instructions, parentNode, parentInjectorId, targetLightDOM);
          case 3:
            let expression = resources.getBindingLanguage(this.bindingLanguage).inspectTextContent(resources, node.wholeText);
            if (expression) {
              let marker = DOM.createElement('au-marker');
              let auTargetID = makeIntoInstructionTarget(marker);
              (node.parentNode || parentNode).insertBefore(marker, node);
              node.textContent = ' ';
              instructions[auTargetID] = TargetInstruction.contentExpression(expression);
  
              while (node.nextSibling && node.nextSibling.nodeType === 3) {
                (node.parentNode || parentNode).removeChild(node.nextSibling);
              }
            } else {
              while (node.nextSibling && node.nextSibling.nodeType === 3) {
                node = node.nextSibling;
              }
            }
            return node.nextSibling;
          case 11:
            let currentChild = node.firstChild;
            while (currentChild) {
              currentChild = this._compileNode(currentChild, resources, instructions, node, parentInjectorId, targetLightDOM);
            }
            break;
          default:
            break;
        }
  
        return node.nextSibling;
      }
  
      _compileSurrogate(node, resources) {
        let tagName = node.tagName.toLowerCase();
        let attributes = node.attributes;
        let bindingLanguage = resources.getBindingLanguage(this.bindingLanguage);
        let knownAttribute;
        let property;
        let instruction;
        let i;
        let ii;
        let attr;
        let attrName;
        let attrValue;
        let info;
        let type;
        let expressions = [];
        let expression;
        let behaviorInstructions = [];
        let values = {};
        let hasValues = false;
        let providers = [];
  
        for (i = 0, ii = attributes.length; i < ii; ++i) {
          attr = attributes[i];
          attrName = attr.name;
          attrValue = attr.value;
  
          info = bindingLanguage.inspectAttribute(resources, tagName, attrName, attrValue);
          type = resources.getAttribute(info.attrName);
  
          if (type) {
            knownAttribute = resources.mapAttribute(info.attrName);
            if (knownAttribute) {
              property = type.attributes[knownAttribute];
  
              if (property) {
                info.defaultBindingMode = property.defaultBindingMode;
  
                if (!info.command && !info.expression) {
                  info.command = property.hasOptions ? 'options' : null;
                }
  
                if (info.command && info.command !== 'options' && type.primaryProperty) {
                  const primaryProperty = type.primaryProperty;
                  attrName = info.attrName = primaryProperty.attribute;
  
                  info.defaultBindingMode = primaryProperty.defaultBindingMode;
                }
              }
            }
          }
  
          instruction = bindingLanguage.createAttributeInstruction(resources, node, info, undefined, type);
  
          if (instruction) {
            if (instruction.alteredAttr) {
              type = resources.getAttribute(instruction.attrName);
            }
  
            if (instruction.discrete) {
              expressions.push(instruction);
            } else {
              if (type) {
                instruction.type = type;
                this._configureProperties(instruction, resources);
  
                if (type.liftsContent) {
                  throw new Error('You cannot place a template controller on a surrogate element.');
                } else {
                  behaviorInstructions.push(instruction);
                }
              } else {
                expressions.push(instruction.attributes[instruction.attrName]);
              }
            }
          } else {
            if (type) {
              instruction = BehaviorInstruction.attribute(attrName, type);
              instruction.attributes[resources.mapAttribute(attrName)] = attrValue;
  
              if (type.liftsContent) {
                throw new Error('You cannot place a template controller on a surrogate element.');
              } else {
                behaviorInstructions.push(instruction);
              }
            } else if (attrName !== 'id' && attrName !== 'part' && attrName !== 'replace-part') {
              hasValues = true;
              values[attrName] = attrValue;
            }
          }
        }
  
        if (expressions.length || behaviorInstructions.length || hasValues) {
          for (i = 0, ii = behaviorInstructions.length; i < ii; ++i) {
            instruction = behaviorInstructions[i];
            instruction.type.compile(this, resources, node, instruction);
            providers.push(instruction.type.target);
          }
  
          for (i = 0, ii = expressions.length; i < ii; ++i) {
            expression = expressions[i];
            if (expression.attrToRemove !== undefined) {
              node.removeAttribute(expression.attrToRemove);
            }
          }
  
          return TargetInstruction.surrogate(providers, behaviorInstructions, expressions, values);
        }
  
        return null;
      }
  
      _compileElement(node, resources, instructions, parentNode, parentInjectorId, targetLightDOM) {
        let tagName = node.tagName.toLowerCase();
        let attributes = node.attributes;
        let expressions = [];
        let expression;
        let behaviorInstructions = [];
        let providers = [];
        let bindingLanguage = resources.getBindingLanguage(this.bindingLanguage);
        let liftingInstruction;
        let viewFactory;
        let type;
        let elementInstruction;
        let elementProperty;
        let i;
        let ii;
        let attr;
        let attrName;
        let attrValue;
        let originalAttrName;
        let instruction;
        let info;
        let property;
        let knownAttribute;
        let auTargetID;
        let injectorId;
  
        if (tagName === 'slot') {
          if (targetLightDOM) {
            node = makeShadowSlot(this, resources, node, instructions, parentInjectorId);
          }
          return node.nextSibling;
        } else if (tagName === 'template') {
          if (!('content' in node)) {
            throw new Error('You cannot place a template element within ' + node.namespaceURI + ' namespace');
          }
          viewFactory = this.compile(node, resources);
          viewFactory.part = node.getAttribute('part');
        } else {
          type = resources.getElement(node.getAttribute('as-element') || tagName);
  
          if (tagName === 'let' && !type && bindingLanguage.createLetExpressions !== defaultLetHandler) {
            expressions = bindingLanguage.createLetExpressions(resources, node);
            auTargetID = makeIntoInstructionTarget(node);
            instructions[auTargetID] = TargetInstruction.letElement(expressions);
            return node.nextSibling;
          }
          if (type) {
            elementInstruction = BehaviorInstruction.element(node, type);
            type.processAttributes(this, resources, node, attributes, elementInstruction);
            behaviorInstructions.push(elementInstruction);
          }
        }
  
        for (i = 0, ii = attributes.length; i < ii; ++i) {
          attr = attributes[i];
          originalAttrName = attrName = attr.name;
          attrValue = attr.value;
          info = bindingLanguage.inspectAttribute(resources, tagName, attrName, attrValue);
  
          if (targetLightDOM && info.attrName === 'slot') {
            info.attrName = attrName = 'au-slot';
          }
  
          type = resources.getAttribute(info.attrName);
          elementProperty = null;
  
          if (type) {
            knownAttribute = resources.mapAttribute(info.attrName);
            if (knownAttribute) {
              property = type.attributes[knownAttribute];
  
              if (property) {
                info.defaultBindingMode = property.defaultBindingMode;
  
                if (!info.command && !info.expression) {
                  info.command = property.hasOptions ? 'options' : null;
                }
  
                if (info.command && info.command !== 'options' && type.primaryProperty) {
                  const primaryProperty = type.primaryProperty;
                  attrName = info.attrName = primaryProperty.attribute;
  
                  info.defaultBindingMode = primaryProperty.defaultBindingMode;
                }
              }
            }
          } else if (elementInstruction) {
            elementProperty = elementInstruction.type.attributes[info.attrName];
            if (elementProperty) {
              info.defaultBindingMode = elementProperty.defaultBindingMode;
            }
          }
  
          if (elementProperty) {
            instruction = bindingLanguage.createAttributeInstruction(resources, node, info, elementInstruction);
          } else {
            instruction = bindingLanguage.createAttributeInstruction(resources, node, info, undefined, type);
          }
  
          if (instruction) {
            if (instruction.alteredAttr) {
              type = resources.getAttribute(instruction.attrName);
            }
  
            if (instruction.discrete) {
              expressions.push(instruction);
            } else {
              if (type) {
                instruction.type = type;
                this._configureProperties(instruction, resources);
  
                if (type.liftsContent) {
                  instruction.originalAttrName = originalAttrName;
                  liftingInstruction = instruction;
                  break;
                } else {
                  behaviorInstructions.push(instruction);
                }
              } else if (elementProperty) {
                elementInstruction.attributes[info.attrName].targetProperty = elementProperty.name;
              } else {
                expressions.push(instruction.attributes[instruction.attrName]);
              }
            }
          } else {
            if (type) {
              instruction = BehaviorInstruction.attribute(attrName, type);
              instruction.attributes[resources.mapAttribute(attrName)] = attrValue;
  
              if (type.liftsContent) {
                instruction.originalAttrName = originalAttrName;
                liftingInstruction = instruction;
                break;
              } else {
                behaviorInstructions.push(instruction);
              }
            } else if (elementProperty) {
              elementInstruction.attributes[attrName] = attrValue;
            }
          }
        }
  
        if (liftingInstruction) {
          liftingInstruction.viewFactory = viewFactory;
          node = liftingInstruction.type.compile(this, resources, node, liftingInstruction, parentNode);
          auTargetID = makeIntoInstructionTarget(node);
          instructions[auTargetID] = TargetInstruction.lifting(parentInjectorId, liftingInstruction);
        } else {
          let skipContentProcessing = false;
  
          if (expressions.length || behaviorInstructions.length) {
            injectorId = behaviorInstructions.length ? getNextInjectorId() : false;
  
            for (i = 0, ii = behaviorInstructions.length; i < ii; ++i) {
              instruction = behaviorInstructions[i];
              instruction.type.compile(this, resources, node, instruction, parentNode);
              providers.push(instruction.type.target);
              skipContentProcessing = skipContentProcessing || instruction.skipContentProcessing;
            }
  
            for (i = 0, ii = expressions.length; i < ii; ++i) {
              expression = expressions[i];
              if (expression.attrToRemove !== undefined) {
                node.removeAttribute(expression.attrToRemove);
              }
            }
  
            auTargetID = makeIntoInstructionTarget(node);
            instructions[auTargetID] = TargetInstruction.normal(injectorId, parentInjectorId, providers, behaviorInstructions, expressions, elementInstruction);
          }
  
          if (skipContentProcessing) {
            return node.nextSibling;
          }
  
          let currentChild = node.firstChild;
          while (currentChild) {
            currentChild = this._compileNode(currentChild, resources, instructions, node, injectorId || parentInjectorId, targetLightDOM);
          }
        }
  
        return node.nextSibling;
      }
  
      _configureProperties(instruction, resources) {
        let type = instruction.type;
        let attrName = instruction.attrName;
        let attributes = instruction.attributes;
        let property;
        let key;
        let value;
  
        let knownAttribute = resources.mapAttribute(attrName);
        if (knownAttribute && attrName in attributes && knownAttribute !== attrName) {
          attributes[knownAttribute] = attributes[attrName];
          delete attributes[attrName];
        }
  
        for (key in attributes) {
          value = attributes[key];
  
          if (value !== null && typeof value === 'object') {
            property = type.attributes[key];
  
            if (property !== undefined) {
              value.targetProperty = property.name;
            } else {
              value.targetProperty = key;
            }
          }
        }
      }
    }) || _class13$1);
  
    let ResourceModule = class ResourceModule {
      constructor(moduleId) {
        this.id = moduleId;
        this.moduleInstance = null;
        this.mainResource = null;
        this.resources = null;
        this.viewStrategy = null;
        this.isInitialized = false;
        this.onLoaded = null;
        this.loadContext = null;
      }
  
      initialize(container) {
        let current = this.mainResource;
        let resources = this.resources;
        let vs = this.viewStrategy;
  
        if (this.isInitialized) {
          return;
        }
  
        this.isInitialized = true;
  
        if (current !== undefined) {
          current.metadata.viewStrategy = vs;
          current.initialize(container);
        }
  
        for (let i = 0, ii = resources.length; i < ii; ++i) {
          current = resources[i];
          current.metadata.viewStrategy = vs;
          current.initialize(container);
        }
      }
  
      register(registry, name) {
        let main = this.mainResource;
        let resources = this.resources;
  
        if (main !== undefined) {
          main.register(registry, name);
          name = null;
        }
  
        for (let i = 0, ii = resources.length; i < ii; ++i) {
          resources[i].register(registry, name);
          name = null;
        }
      }
  
      load(container, loadContext) {
        if (this.onLoaded !== null) {
          return this.loadContext === loadContext ? Promise.resolve() : this.onLoaded;
        }
  
        let main = this.mainResource;
        let resources = this.resources;
        let loads;
  
        if (main !== undefined) {
          loads = new Array(resources.length + 1);
          loads[0] = main.load(container, loadContext);
          for (let i = 0, ii = resources.length; i < ii; ++i) {
            loads[i + 1] = resources[i].load(container, loadContext);
          }
        } else {
          loads = new Array(resources.length);
          for (let i = 0, ii = resources.length; i < ii; ++i) {
            loads[i] = resources[i].load(container, loadContext);
          }
        }
  
        this.loadContext = loadContext;
        this.onLoaded = Promise.all(loads);
        return this.onLoaded;
      }
    };
  
    let ResourceDescription = class ResourceDescription {
      constructor(key, exportedValue, resourceTypeMeta) {
        if (!resourceTypeMeta) {
          resourceTypeMeta = metadata.get(metadata.resource, exportedValue);
  
          if (!resourceTypeMeta) {
            resourceTypeMeta = new HtmlBehaviorResource();
            resourceTypeMeta.elementName = _hyphenate(key);
            metadata.define(metadata.resource, resourceTypeMeta, exportedValue);
          }
        }
  
        if (resourceTypeMeta instanceof HtmlBehaviorResource) {
          if (resourceTypeMeta.elementName === undefined) {
            resourceTypeMeta.elementName = _hyphenate(key);
          } else if (resourceTypeMeta.attributeName === undefined) {
            resourceTypeMeta.attributeName = _hyphenate(key);
          } else if (resourceTypeMeta.attributeName === null && resourceTypeMeta.elementName === null) {
            HtmlBehaviorResource.convention(key, resourceTypeMeta);
          }
        } else if (!resourceTypeMeta.name) {
          resourceTypeMeta.name = _hyphenate(key);
        }
  
        this.metadata = resourceTypeMeta;
        this.value = exportedValue;
      }
  
      initialize(container) {
        this.metadata.initialize(container, this.value);
      }
  
      register(registry, name) {
        this.metadata.register(registry, name);
      }
  
      load(container, loadContext) {
        return this.metadata.load(container, this.value, loadContext);
      }
    };
  
    let ModuleAnalyzer = class ModuleAnalyzer {
      constructor() {
        this.cache = Object.create(null);
      }
  
      getAnalysis(moduleId) {
        return this.cache[moduleId];
      }
  
      analyze(moduleId, moduleInstance, mainResourceKey) {
        let mainResource;
        let fallbackValue;
        let fallbackKey;
        let resourceTypeMeta;
        let key;
        let exportedValue;
        let resources = [];
        let conventional;
        let vs;
        let resourceModule;
  
        resourceModule = this.cache[moduleId];
        if (resourceModule) {
          return resourceModule;
        }
  
        resourceModule = new ResourceModule(moduleId);
        this.cache[moduleId] = resourceModule;
  
        if (typeof moduleInstance === 'function') {
          moduleInstance = { 'default': moduleInstance };
        }
  
        if (mainResourceKey) {
          mainResource = new ResourceDescription(mainResourceKey, moduleInstance[mainResourceKey]);
        }
  
        for (key in moduleInstance) {
          exportedValue = moduleInstance[key];
  
          if (key === mainResourceKey || typeof exportedValue !== 'function') {
            continue;
          }
  
          resourceTypeMeta = metadata.get(metadata.resource, exportedValue);
  
          if (resourceTypeMeta) {
            if (resourceTypeMeta instanceof HtmlBehaviorResource) {
              ViewResources.convention(exportedValue, resourceTypeMeta);
  
              if (resourceTypeMeta.attributeName === null && resourceTypeMeta.elementName === null) {
                HtmlBehaviorResource.convention(key, resourceTypeMeta);
              }
  
              if (resourceTypeMeta.attributeName === null && resourceTypeMeta.elementName === null) {
                resourceTypeMeta.elementName = _hyphenate(key);
              }
            }
  
            if (!mainResource && resourceTypeMeta instanceof HtmlBehaviorResource && resourceTypeMeta.elementName !== null) {
              mainResource = new ResourceDescription(key, exportedValue, resourceTypeMeta);
            } else {
              resources.push(new ResourceDescription(key, exportedValue, resourceTypeMeta));
            }
          } else if (viewStrategy.decorates(exportedValue)) {
            vs = exportedValue;
          } else if (exportedValue instanceof TemplateRegistryEntry) {
            vs = new TemplateRegistryViewStrategy(moduleId, exportedValue);
          } else {
            if (conventional = ViewResources.convention(exportedValue)) {
              if (conventional.elementName !== null && !mainResource) {
                mainResource = new ResourceDescription(key, exportedValue, conventional);
              } else {
                resources.push(new ResourceDescription(key, exportedValue, conventional));
              }
              metadata.define(metadata.resource, conventional, exportedValue);
            } else if (conventional = HtmlBehaviorResource.convention(key)) {
              if (conventional.elementName !== null && !mainResource) {
                mainResource = new ResourceDescription(key, exportedValue, conventional);
              } else {
                resources.push(new ResourceDescription(key, exportedValue, conventional));
              }
  
              metadata.define(metadata.resource, conventional, exportedValue);
            } else if (conventional = ValueConverterResource.convention(key) || BindingBehaviorResource.convention(key) || ViewEngineHooksResource.convention(key)) {
              resources.push(new ResourceDescription(key, exportedValue, conventional));
              metadata.define(metadata.resource, conventional, exportedValue);
            } else if (!fallbackValue) {
              fallbackValue = exportedValue;
              fallbackKey = key;
            }
          }
        }
  
        if (!mainResource && fallbackValue) {
          mainResource = new ResourceDescription(fallbackKey, fallbackValue);
        }
  
        resourceModule.moduleInstance = moduleInstance;
        resourceModule.mainResource = mainResource;
        resourceModule.resources = resources;
        resourceModule.viewStrategy = vs;
  
        return resourceModule;
      }
    };
  
    let logger$1 = getLogger('templating');
  
    function ensureRegistryEntry(loader, urlOrRegistryEntry) {
      if (urlOrRegistryEntry instanceof TemplateRegistryEntry) {
        return Promise.resolve(urlOrRegistryEntry);
      }
  
      return loader.loadTemplate(urlOrRegistryEntry);
    }
  
    let ProxyViewFactory = class ProxyViewFactory {
      constructor(promise) {
        promise.then(x => this.viewFactory = x);
      }
  
      create(container, bindingContext, createInstruction, element) {
        return this.viewFactory.create(container, bindingContext, createInstruction, element);
      }
  
      get isCaching() {
        return this.viewFactory.isCaching;
      }
  
      setCacheSize(size, doNotOverrideIfAlreadySet) {
        this.viewFactory.setCacheSize(size, doNotOverrideIfAlreadySet);
      }
  
      getCachedView() {
        return this.viewFactory.getCachedView();
      }
  
      returnViewToCache(view) {
        this.viewFactory.returnViewToCache(view);
      }
    };
  
  
    let auSlotBehavior = null;
  
    let ViewEngine = (_dec8$1 = inject(Loader, Container, ViewCompiler, ModuleAnalyzer, ViewResources), _dec8$1(_class14 = (_temp4 = _class15 = class ViewEngine {
      constructor(loader, container, viewCompiler, moduleAnalyzer, appResources) {
        this.loader = loader;
        this.container = container;
        this.viewCompiler = viewCompiler;
        this.moduleAnalyzer = moduleAnalyzer;
        this.appResources = appResources;
        this._pluginMap = {};
  
        if (auSlotBehavior === null) {
          auSlotBehavior = new HtmlBehaviorResource();
          auSlotBehavior.attributeName = 'au-slot';
          metadata.define(metadata.resource, auSlotBehavior, SlotCustomAttribute);
        }
  
        auSlotBehavior.initialize(container, SlotCustomAttribute);
        auSlotBehavior.register(appResources);
      }
  
      addResourcePlugin(extension, implementation) {
        let name = extension.replace('.', '') + '-resource-plugin';
        this._pluginMap[extension] = name;
        this.loader.addPlugin(name, implementation);
      }
  
      loadViewFactory(urlOrRegistryEntry, compileInstruction, loadContext, target) {
        loadContext = loadContext || new ResourceLoadContext();
  
        return ensureRegistryEntry(this.loader, urlOrRegistryEntry).then(registryEntry => {
          const url = registryEntry.address;
  
          if (registryEntry.onReady) {
            if (!loadContext.hasDependency(url)) {
              loadContext.addDependency(url);
              return registryEntry.onReady;
            }
  
            if (registryEntry.template === null) {
              return registryEntry.onReady;
            }
  
            return Promise.resolve(new ProxyViewFactory(registryEntry.onReady));
          }
  
          loadContext.addDependency(url);
  
          registryEntry.onReady = this.loadTemplateResources(registryEntry, compileInstruction, loadContext, target).then(resources => {
            registryEntry.resources = resources;
  
            if (registryEntry.template === null) {
              return registryEntry.factory = null;
            }
  
            let viewFactory = this.viewCompiler.compile(registryEntry.template, resources, compileInstruction);
            return registryEntry.factory = viewFactory;
          });
  
          return registryEntry.onReady;
        });
      }
  
      loadTemplateResources(registryEntry, compileInstruction, loadContext, target) {
        let resources = new ViewResources(this.appResources, registryEntry.address);
        let dependencies = registryEntry.dependencies;
        let importIds;
        let names;
  
        compileInstruction = compileInstruction || ViewCompileInstruction.normal;
  
        if (dependencies.length === 0 && !compileInstruction.associatedModuleId) {
          return Promise.resolve(resources);
        }
  
        importIds = dependencies.map(x => x.src);
        names = dependencies.map(x => x.name);
        logger$1.debug(`importing resources for ${registryEntry.address}`, importIds);
  
        if (target) {
          let viewModelRequires = metadata.get(ViewEngine.viewModelRequireMetadataKey, target);
          if (viewModelRequires) {
            let templateImportCount = importIds.length;
            for (let i = 0, ii = viewModelRequires.length; i < ii; ++i) {
              let req = viewModelRequires[i];
              let importId = typeof req === 'function' ? Origin.get(req).moduleId : relativeToFile(req.src || req, registryEntry.address);
  
              if (importIds.indexOf(importId) === -1) {
                importIds.push(importId);
                names.push(req.as);
              }
            }
            logger$1.debug(`importing ViewModel resources for ${compileInstruction.associatedModuleId}`, importIds.slice(templateImportCount));
          }
        }
  
        return this.importViewResources(importIds, names, resources, compileInstruction, loadContext);
      }
  
      importViewModelResource(moduleImport, moduleMember) {
        return this.loader.loadModule(moduleImport).then(viewModelModule => {
          let normalizedId = Origin.get(viewModelModule).moduleId;
          let resourceModule = this.moduleAnalyzer.analyze(normalizedId, viewModelModule, moduleMember);
  
          if (!resourceModule.mainResource) {
            throw new Error(`No view model found in module "${moduleImport}".`);
          }
  
          resourceModule.initialize(this.container);
  
          return resourceModule.mainResource;
        });
      }
  
      importViewResources(moduleIds, names, resources, compileInstruction, loadContext) {
        loadContext = loadContext || new ResourceLoadContext();
        compileInstruction = compileInstruction || ViewCompileInstruction.normal;
  
        moduleIds = moduleIds.map(x => this._applyLoaderPlugin(x));
  
        return this.loader.loadAllModules(moduleIds).then(imports => {
          let i;
          let ii;
          let analysis;
          let normalizedId;
          let current;
          let associatedModule;
          let container = this.container;
          let moduleAnalyzer = this.moduleAnalyzer;
          let allAnalysis = new Array(imports.length);
  
          for (i = 0, ii = imports.length; i < ii; ++i) {
            current = imports[i];
            normalizedId = Origin.get(current).moduleId;
  
            analysis = moduleAnalyzer.analyze(normalizedId, current);
            analysis.initialize(container);
            analysis.register(resources, names[i]);
  
            allAnalysis[i] = analysis;
          }
  
          if (compileInstruction.associatedModuleId) {
            associatedModule = moduleAnalyzer.getAnalysis(compileInstruction.associatedModuleId);
  
            if (associatedModule) {
              associatedModule.register(resources);
            }
          }
  
          for (i = 0, ii = allAnalysis.length; i < ii; ++i) {
            allAnalysis[i] = allAnalysis[i].load(container, loadContext);
          }
  
          return Promise.all(allAnalysis).then(() => resources);
        });
      }
  
      _applyLoaderPlugin(id) {
        let index = id.lastIndexOf('.');
        if (index !== -1) {
          let ext = id.substring(index);
          let pluginName = this._pluginMap[ext];
  
          if (pluginName === undefined) {
            return id;
          }
  
          return this.loader.applyPluginToUrl(id, pluginName);
        }
  
        return id;
      }
    }, _class15.viewModelRequireMetadataKey = 'aurelia:view-model-require', _temp4)) || _class14);
  
    let Controller = class Controller {
      constructor(behavior, instruction, viewModel, container) {
        this.behavior = behavior;
        this.instruction = instruction;
        this.viewModel = viewModel;
        this.isAttached = false;
        this.view = null;
        this.isBound = false;
        this.scope = null;
        this.container = container;
        this.elementEvents = container.elementEvents || null;
  
        let observerLookup = behavior.observerLocator.getOrCreateObserversLookup(viewModel);
        let handlesBind = behavior.handlesBind;
        let attributes = instruction.attributes;
        let boundProperties = this.boundProperties = [];
        let properties = behavior.properties;
        let i;
        let ii;
  
        behavior._ensurePropertiesDefined(viewModel, observerLookup);
  
        for (i = 0, ii = properties.length; i < ii; ++i) {
          properties[i]._initialize(viewModel, observerLookup, attributes, handlesBind, boundProperties);
        }
      }
  
      created(owningView) {
        if (this.behavior.handlesCreated) {
          this.viewModel.created(owningView, this.view);
        }
      }
  
      automate(overrideContext, owningView) {
        this.view.bindingContext = this.viewModel;
        this.view.overrideContext = overrideContext || createOverrideContext(this.viewModel);
        this.view._isUserControlled = true;
  
        if (this.behavior.handlesCreated) {
          this.viewModel.created(owningView || null, this.view);
        }
  
        this.bind(this.view);
      }
  
      bind(scope) {
        let skipSelfSubscriber = this.behavior.handlesBind;
        let boundProperties = this.boundProperties;
        let i;
        let ii;
        let x;
        let observer;
        let selfSubscriber;
  
        if (this.isBound) {
          if (this.scope === scope) {
            return;
          }
  
          this.unbind();
        }
  
        this.isBound = true;
        this.scope = scope;
  
        for (i = 0, ii = boundProperties.length; i < ii; ++i) {
          x = boundProperties[i];
          observer = x.observer;
          selfSubscriber = observer.selfSubscriber;
          observer.publishing = false;
  
          if (skipSelfSubscriber) {
            observer.selfSubscriber = null;
          }
  
          x.binding.bind(scope);
          observer.call();
  
          observer.publishing = true;
          observer.selfSubscriber = selfSubscriber;
        }
  
        let overrideContext;
        if (this.view !== null) {
          if (skipSelfSubscriber) {
            this.view.viewModelScope = scope;
          }
  
          if (this.viewModel === scope.overrideContext.bindingContext) {
            overrideContext = scope.overrideContext;
          } else if (this.instruction.inheritBindingContext) {
            overrideContext = createOverrideContext(this.viewModel, scope.overrideContext);
          } else {
            overrideContext = createOverrideContext(this.viewModel);
            overrideContext.__parentOverrideContext = scope.overrideContext;
          }
  
          this.view.bind(this.viewModel, overrideContext);
        } else if (skipSelfSubscriber) {
          overrideContext = scope.overrideContext;
  
          if (scope.overrideContext.__parentOverrideContext !== undefined && this.viewModel.viewFactory && this.viewModel.viewFactory.factoryCreateInstruction.partReplacements) {
            overrideContext = Object.assign({}, scope.overrideContext);
            overrideContext.parentOverrideContext = scope.overrideContext.__parentOverrideContext;
          }
          this.viewModel.bind(scope.bindingContext, overrideContext);
        }
      }
  
      unbind() {
        if (this.isBound) {
          let boundProperties = this.boundProperties;
          let i;
          let ii;
  
          this.isBound = false;
          this.scope = null;
  
          if (this.view !== null) {
            this.view.unbind();
          }
  
          if (this.behavior.handlesUnbind) {
            this.viewModel.unbind();
          }
  
          if (this.elementEvents !== null) {
            this.elementEvents.disposeAll();
          }
  
          for (i = 0, ii = boundProperties.length; i < ii; ++i) {
            boundProperties[i].binding.unbind();
          }
        }
      }
  
      attached() {
        if (this.isAttached) {
          return;
        }
  
        this.isAttached = true;
  
        if (this.behavior.handlesAttached) {
          this.viewModel.attached();
        }
  
        if (this.view !== null) {
          this.view.attached();
        }
      }
  
      detached() {
        if (this.isAttached) {
          this.isAttached = false;
  
          if (this.view !== null) {
            this.view.detached();
          }
  
          if (this.behavior.handlesDetached) {
            this.viewModel.detached();
          }
        }
      }
    };
  
    let BehaviorPropertyObserver = (_dec9$1 = subscriberCollection(), _dec9$1(_class16 = class BehaviorPropertyObserver {
      constructor(taskQueue, obj, propertyName, selfSubscriber, initialValue) {
        this.taskQueue = taskQueue;
        this.obj = obj;
        this.propertyName = propertyName;
        this.notqueued = true;
        this.publishing = false;
        this.selfSubscriber = selfSubscriber;
        this.currentValue = this.oldValue = initialValue;
      }
  
      getValue() {
        return this.currentValue;
      }
  
      setValue(newValue) {
        let oldValue = this.currentValue;
  
        if (!Object.is(newValue, oldValue)) {
          this.oldValue = oldValue;
          this.currentValue = newValue;
  
          if (this.publishing && this.notqueued) {
            if (this.taskQueue.flushing) {
              this.call();
            } else {
              this.notqueued = false;
              this.taskQueue.queueMicroTask(this);
            }
          }
        }
      }
  
      call() {
        let oldValue = this.oldValue;
        let newValue = this.currentValue;
  
        this.notqueued = true;
  
        if (Object.is(newValue, oldValue)) {
          return;
        }
  
        if (this.selfSubscriber) {
          this.selfSubscriber(newValue, oldValue);
        }
  
        this.callSubscribers(newValue, oldValue);
        this.oldValue = newValue;
      }
  
      subscribe(context, callable) {
        this.addSubscriber(context, callable);
      }
  
      unsubscribe(context, callable) {
        this.removeSubscriber(context, callable);
      }
    }) || _class16);
  
    function getObserver(instance, name) {
      let lookup = instance.__observers__;
  
      if (lookup === undefined) {
        let ctor = Object.getPrototypeOf(instance).constructor;
        let behavior = metadata.get(metadata.resource, ctor);
        if (!behavior.isInitialized) {
          behavior.initialize(Container.instance || new Container(), instance.constructor);
        }
  
        lookup = behavior.observerLocator.getOrCreateObserversLookup(instance);
        behavior._ensurePropertiesDefined(instance, lookup);
      }
  
      return lookup[name];
    }
  
    let BindableProperty = class BindableProperty {
      constructor(nameOrConfig) {
        if (typeof nameOrConfig === 'string') {
          this.name = nameOrConfig;
        } else {
          Object.assign(this, nameOrConfig);
        }
  
        this.attribute = this.attribute || _hyphenate(this.name);
        let defaultBindingMode = this.defaultBindingMode;
        if (defaultBindingMode === null || defaultBindingMode === undefined) {
          this.defaultBindingMode = bindingMode.oneWay;
        } else if (typeof defaultBindingMode === 'string') {
          this.defaultBindingMode = bindingMode[defaultBindingMode] || bindingMode.oneWay;
        }
        this.changeHandler = this.changeHandler || null;
        this.owner = null;
        this.descriptor = null;
      }
  
      registerWith(target, behavior, descriptor) {
        behavior.properties.push(this);
        behavior.attributes[this.attribute] = this;
        this.owner = behavior;
  
        if (descriptor) {
          this.descriptor = descriptor;
          return this._configureDescriptor(descriptor);
        }
  
        return undefined;
      }
  
      _configureDescriptor(descriptor) {
        let name = this.name;
  
        descriptor.configurable = true;
        descriptor.enumerable = true;
  
        if ('initializer' in descriptor) {
          this.defaultValue = descriptor.initializer;
          delete descriptor.initializer;
          delete descriptor.writable;
        }
  
        if ('value' in descriptor) {
          this.defaultValue = descriptor.value;
          delete descriptor.value;
          delete descriptor.writable;
        }
  
        descriptor.get = function () {
          return getObserver(this, name).getValue();
        };
  
        descriptor.set = function (value) {
          getObserver(this, name).setValue(value);
        };
  
        descriptor.get.getObserver = function (obj) {
          return getObserver(obj, name);
        };
  
        return descriptor;
      }
  
      defineOn(target, behavior) {
        let name = this.name;
        let handlerName;
  
        if (this.changeHandler === null) {
          handlerName = name + 'Changed';
          if (handlerName in target.prototype) {
            this.changeHandler = handlerName;
          }
        }
  
        if (this.descriptor === null) {
          Object.defineProperty(target.prototype, name, this._configureDescriptor(behavior, {}));
        }
      }
  
      createObserver(viewModel) {
        let selfSubscriber = null;
        let defaultValue = this.defaultValue;
        let changeHandlerName = this.changeHandler;
        let name = this.name;
        let initialValue;
  
        if (this.hasOptions) {
          return undefined;
        }
  
        if (changeHandlerName in viewModel) {
          if ('propertyChanged' in viewModel) {
            selfSubscriber = (newValue, oldValue) => {
              viewModel[changeHandlerName](newValue, oldValue);
              viewModel.propertyChanged(name, newValue, oldValue);
            };
          } else {
            selfSubscriber = (newValue, oldValue) => viewModel[changeHandlerName](newValue, oldValue);
          }
        } else if ('propertyChanged' in viewModel) {
          selfSubscriber = (newValue, oldValue) => viewModel.propertyChanged(name, newValue, oldValue);
        } else if (changeHandlerName !== null) {
          throw new Error(`Change handler ${changeHandlerName} was specified but not declared on the class.`);
        }
  
        if (defaultValue !== undefined) {
          initialValue = typeof defaultValue === 'function' ? defaultValue.call(viewModel) : defaultValue;
        }
  
        return new BehaviorPropertyObserver(this.owner.taskQueue, viewModel, this.name, selfSubscriber, initialValue);
      }
  
      _initialize(viewModel, observerLookup, attributes, behaviorHandlesBind, boundProperties) {
        let selfSubscriber;
        let observer;
        let attribute;
        let defaultValue = this.defaultValue;
  
        if (this.isDynamic) {
          for (let key in attributes) {
            this._createDynamicProperty(viewModel, observerLookup, behaviorHandlesBind, key, attributes[key], boundProperties);
          }
        } else if (!this.hasOptions) {
          observer = observerLookup[this.name];
  
          if (attributes !== null) {
            selfSubscriber = observer.selfSubscriber;
            attribute = attributes[this.attribute];
  
            if (behaviorHandlesBind) {
              observer.selfSubscriber = null;
            }
  
            if (typeof attribute === 'string') {
              viewModel[this.name] = attribute;
              observer.call();
            } else if (attribute) {
              boundProperties.push({ observer: observer, binding: attribute.createBinding(viewModel) });
            } else if (defaultValue !== undefined) {
              observer.call();
            }
  
            observer.selfSubscriber = selfSubscriber;
          }
  
          observer.publishing = true;
        }
      }
  
      _createDynamicProperty(viewModel, observerLookup, behaviorHandlesBind, name, attribute, boundProperties) {
        let changeHandlerName = name + 'Changed';
        let selfSubscriber = null;
        let observer;
        let info;
  
        if (changeHandlerName in viewModel) {
          if ('propertyChanged' in viewModel) {
            selfSubscriber = (newValue, oldValue) => {
              viewModel[changeHandlerName](newValue, oldValue);
              viewModel.propertyChanged(name, newValue, oldValue);
            };
          } else {
            selfSubscriber = (newValue, oldValue) => viewModel[changeHandlerName](newValue, oldValue);
          }
        } else if ('propertyChanged' in viewModel) {
          selfSubscriber = (newValue, oldValue) => viewModel.propertyChanged(name, newValue, oldValue);
        }
  
        observer = observerLookup[name] = new BehaviorPropertyObserver(this.owner.taskQueue, viewModel, name, selfSubscriber);
  
        Object.defineProperty(viewModel, name, {
          configurable: true,
          enumerable: true,
          get: observer.getValue.bind(observer),
          set: observer.setValue.bind(observer)
        });
  
        if (behaviorHandlesBind) {
          observer.selfSubscriber = null;
        }
  
        if (typeof attribute === 'string') {
          viewModel[name] = attribute;
          observer.call();
        } else if (attribute) {
          info = { observer: observer, binding: attribute.createBinding(viewModel) };
          boundProperties.push(info);
        }
  
        observer.publishing = true;
        observer.selfSubscriber = selfSubscriber;
      }
    };
  
    let lastProviderId = 0;
  
    function nextProviderId() {
      return ++lastProviderId;
    }
  
    function doProcessContent() {
      return true;
    }
    function doProcessAttributes() {}
  
    let HtmlBehaviorResource = class HtmlBehaviorResource {
      constructor() {
        this.elementName = null;
        this.attributeName = null;
        this.attributeDefaultBindingMode = undefined;
        this.liftsContent = false;
        this.targetShadowDOM = false;
        this.shadowDOMOptions = null;
        this.processAttributes = doProcessAttributes;
        this.processContent = doProcessContent;
        this.usesShadowDOM = false;
        this.childBindings = null;
        this.hasDynamicOptions = false;
        this.containerless = false;
        this.properties = [];
        this.attributes = {};
        this.isInitialized = false;
        this.primaryProperty = null;
      }
  
      static convention(name, existing) {
        let behavior;
  
        if (name.endsWith('CustomAttribute')) {
          behavior = existing || new HtmlBehaviorResource();
          behavior.attributeName = _hyphenate(name.substring(0, name.length - 15));
        }
  
        if (name.endsWith('CustomElement')) {
          behavior = existing || new HtmlBehaviorResource();
          behavior.elementName = _hyphenate(name.substring(0, name.length - 13));
        }
  
        return behavior;
      }
  
      addChildBinding(behavior) {
        if (this.childBindings === null) {
          this.childBindings = [];
        }
  
        this.childBindings.push(behavior);
      }
  
      initialize(container, target) {
        let proto = target.prototype;
        let properties = this.properties;
        let attributeName = this.attributeName;
        let attributeDefaultBindingMode = this.attributeDefaultBindingMode;
        let i;
        let ii;
        let current;
  
        if (this.isInitialized) {
          return;
        }
  
        this.isInitialized = true;
        target.__providerId__ = nextProviderId();
  
        this.observerLocator = container.get(ObserverLocator);
        this.taskQueue = container.get(TaskQueue);
  
        this.target = target;
        this.usesShadowDOM = this.targetShadowDOM && FEATURE.shadowDOM;
        this.handlesCreated = 'created' in proto;
        this.handlesBind = 'bind' in proto;
        this.handlesUnbind = 'unbind' in proto;
        this.handlesAttached = 'attached' in proto;
        this.handlesDetached = 'detached' in proto;
        this.htmlName = this.elementName || this.attributeName;
  
        if (attributeName !== null) {
          if (properties.length === 0) {
            new BindableProperty({
              name: 'value',
              changeHandler: 'valueChanged' in proto ? 'valueChanged' : null,
              attribute: attributeName,
              defaultBindingMode: attributeDefaultBindingMode
            }).registerWith(target, this);
          }
  
          current = properties[0];
  
          if (properties.length === 1 && current.name === 'value') {
            current.isDynamic = current.hasOptions = this.hasDynamicOptions;
            current.defineOn(target, this);
          } else {
            for (i = 0, ii = properties.length; i < ii; ++i) {
              properties[i].defineOn(target, this);
              if (properties[i].primaryProperty) {
                if (this.primaryProperty) {
                  throw new Error('Only one bindable property on a custom element can be defined as the default');
                }
                this.primaryProperty = properties[i];
              }
            }
  
            current = new BindableProperty({
              name: 'value',
              changeHandler: 'valueChanged' in proto ? 'valueChanged' : null,
              attribute: attributeName,
              defaultBindingMode: attributeDefaultBindingMode
            });
  
            current.hasOptions = true;
            current.registerWith(target, this);
          }
        } else {
          for (i = 0, ii = properties.length; i < ii; ++i) {
            properties[i].defineOn(target, this);
          }
  
          this._copyInheritedProperties(container, target);
        }
      }
  
      register(registry, name) {
        if (this.attributeName !== null) {
          registry.registerAttribute(name || this.attributeName, this, this.attributeName);
  
          if (Array.isArray(this.aliases)) {
            this.aliases.forEach(alias => {
              registry.registerAttribute(alias, this, this.attributeName);
            });
          }
        }
  
        if (this.elementName !== null) {
          registry.registerElement(name || this.elementName, this);
        }
      }
  
      load(container, target, loadContext, viewStrategy, transientView) {
        let options;
  
        if (this.elementName !== null) {
          viewStrategy = container.get(ViewLocator).getViewStrategy(viewStrategy || this.viewStrategy || target);
          options = new ViewCompileInstruction(this.targetShadowDOM, true);
  
          if (!viewStrategy.moduleId) {
            viewStrategy.moduleId = Origin.get(target).moduleId;
          }
  
          return viewStrategy.loadViewFactory(container.get(ViewEngine), options, loadContext, target).then(viewFactory => {
            if (!transientView || !this.viewFactory) {
              this.viewFactory = viewFactory;
            }
  
            return viewFactory;
          });
        }
  
        return Promise.resolve(this);
      }
  
      compile(compiler, resources, node, instruction, parentNode) {
        if (this.liftsContent) {
          if (!instruction.viewFactory) {
            let template = DOM.createElement('template');
            let fragment = DOM.createDocumentFragment();
            let cacheSize = node.getAttribute('view-cache');
            let part = node.getAttribute('part');
  
            node.removeAttribute(instruction.originalAttrName);
            DOM.replaceNode(template, node, parentNode);
            fragment.appendChild(node);
            instruction.viewFactory = compiler.compile(fragment, resources);
  
            if (part) {
              instruction.viewFactory.part = part;
              node.removeAttribute('part');
            }
  
            if (cacheSize) {
              instruction.viewFactory.setCacheSize(cacheSize);
              node.removeAttribute('view-cache');
            }
  
            node = template;
          }
        } else if (this.elementName !== null) {
          let partReplacements = {};
  
          if (this.processContent(compiler, resources, node, instruction) && node.hasChildNodes()) {
            let currentChild = node.firstChild;
            let contentElement = this.usesShadowDOM ? null : DOM.createElement('au-content');
            let nextSibling;
            let toReplace;
  
            while (currentChild) {
              nextSibling = currentChild.nextSibling;
  
              if (currentChild.tagName === 'TEMPLATE' && (toReplace = currentChild.getAttribute('replace-part'))) {
                partReplacements[toReplace] = compiler.compile(currentChild, resources);
                DOM.removeNode(currentChild, parentNode);
                instruction.partReplacements = partReplacements;
              } else if (contentElement !== null) {
                if (currentChild.nodeType === 3 && _isAllWhitespace(currentChild)) {
                  DOM.removeNode(currentChild, parentNode);
                } else {
                  contentElement.appendChild(currentChild);
                }
              }
  
              currentChild = nextSibling;
            }
  
            if (contentElement !== null && contentElement.hasChildNodes()) {
              node.appendChild(contentElement);
            }
  
            instruction.skipContentProcessing = false;
          } else {
            instruction.skipContentProcessing = true;
          }
        } else if (!this.processContent(compiler, resources, node, instruction)) {
          instruction.skipContentProcessing = true;
        }
  
        return node;
      }
  
      create(container, instruction, element, bindings) {
        let viewHost;
        let au = null;
  
        instruction = instruction || BehaviorInstruction.normal;
        element = element || null;
        bindings = bindings || null;
  
        if (this.elementName !== null && element) {
          if (this.usesShadowDOM) {
            viewHost = element.attachShadow(this.shadowDOMOptions);
            container.registerInstance(DOM.boundary, viewHost);
          } else {
            viewHost = element;
            if (this.targetShadowDOM) {
              container.registerInstance(DOM.boundary, viewHost);
            }
          }
        }
  
        if (element !== null) {
          element.au = au = element.au || {};
        }
  
        let viewModel = instruction.viewModel || container.get(this.target);
        let controller = new Controller(this, instruction, viewModel, container);
        let childBindings = this.childBindings;
        let viewFactory;
  
        if (this.liftsContent) {
          au.controller = controller;
        } else if (this.elementName !== null) {
          viewFactory = instruction.viewFactory || this.viewFactory;
          container.viewModel = viewModel;
  
          if (viewFactory) {
            controller.view = viewFactory.create(container, instruction, element);
          }
  
          if (element !== null) {
            au.controller = controller;
  
            if (controller.view) {
              if (!this.usesShadowDOM && (element.childNodes.length === 1 || element.contentElement)) {
                let contentElement = element.childNodes[0] || element.contentElement;
                controller.view.contentView = { fragment: contentElement };
                contentElement.parentNode && DOM.removeNode(contentElement);
              }
  
              if (instruction.anchorIsContainer) {
                if (childBindings !== null) {
                  for (let i = 0, ii = childBindings.length; i < ii; ++i) {
                    controller.view.addBinding(childBindings[i].create(element, viewModel, controller));
                  }
                }
  
                controller.view.appendNodesTo(viewHost);
              } else {
                controller.view.insertNodesBefore(viewHost);
              }
            } else if (childBindings !== null) {
              for (let i = 0, ii = childBindings.length; i < ii; ++i) {
                bindings.push(childBindings[i].create(element, viewModel, controller));
              }
            }
          } else if (controller.view) {
            controller.view.controller = controller;
  
            if (childBindings !== null) {
              for (let i = 0, ii = childBindings.length; i < ii; ++i) {
                controller.view.addBinding(childBindings[i].create(instruction.host, viewModel, controller));
              }
            }
          } else if (childBindings !== null) {
            for (let i = 0, ii = childBindings.length; i < ii; ++i) {
              bindings.push(childBindings[i].create(instruction.host, viewModel, controller));
            }
          }
        } else if (childBindings !== null) {
          for (let i = 0, ii = childBindings.length; i < ii; ++i) {
            bindings.push(childBindings[i].create(element, viewModel, controller));
          }
        }
  
        if (au !== null) {
          au[this.htmlName] = controller;
        }
  
        if (instruction.initiatedByBehavior && viewFactory) {
          controller.view.created();
        }
  
        return controller;
      }
  
      _ensurePropertiesDefined(instance, lookup) {
        let properties;
        let i;
        let ii;
        let observer;
  
        if ('__propertiesDefined__' in lookup) {
          return;
        }
  
        lookup.__propertiesDefined__ = true;
        properties = this.properties;
  
        for (i = 0, ii = properties.length; i < ii; ++i) {
          observer = properties[i].createObserver(instance);
  
          if (observer !== undefined) {
            lookup[observer.propertyName] = observer;
          }
        }
      }
  
      _copyInheritedProperties(container, target) {
        let behavior;
        let derived = target;
  
        while (true) {
          let proto = Object.getPrototypeOf(target.prototype);
          target = proto && proto.constructor;
          if (!target) {
            return;
          }
          behavior = metadata.getOwn(metadata.resource, target);
          if (behavior) {
            break;
          }
        }
        behavior.initialize(container, target);
        for (let i = 0, ii = behavior.properties.length; i < ii; ++i) {
          let prop = behavior.properties[i];
  
          if (this.properties.some(p => p.name === prop.name)) {
            continue;
          }
  
          new BindableProperty(prop).registerWith(derived, this);
        }
      }
    };
  
    function createChildObserverDecorator(selectorOrConfig, all) {
      return function (target, key, descriptor) {
        let actualTarget = typeof key === 'string' ? target.constructor : target;
        let r = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, actualTarget);
  
        if (typeof selectorOrConfig === 'string') {
          selectorOrConfig = {
            selector: selectorOrConfig,
            name: key
          };
        }
  
        if (descriptor) {
          descriptor.writable = true;
          descriptor.configurable = true;
        }
  
        selectorOrConfig.all = all;
        r.addChildBinding(new ChildObserver(selectorOrConfig));
      };
    }
  
    function children(selectorOrConfig) {
      return createChildObserverDecorator(selectorOrConfig, true);
    }
  
    function child(selectorOrConfig) {
      return createChildObserverDecorator(selectorOrConfig, false);
    }
  
    let ChildObserver = class ChildObserver {
      constructor(config) {
        this.name = config.name;
        this.changeHandler = config.changeHandler || this.name + 'Changed';
        this.selector = config.selector;
        this.all = config.all;
      }
  
      create(viewHost, viewModel, controller) {
        return new ChildObserverBinder(this.selector, viewHost, this.name, viewModel, controller, this.changeHandler, this.all);
      }
    };
  
  
    const noMutations = [];
  
    function trackMutation(groupedMutations, binder, record) {
      let mutations = groupedMutations.get(binder);
  
      if (!mutations) {
        mutations = [];
        groupedMutations.set(binder, mutations);
      }
  
      mutations.push(record);
    }
  
    function onChildChange(mutations, observer) {
      let binders = observer.binders;
      let bindersLength = binders.length;
      let groupedMutations = new Map();
  
      for (let i = 0, ii = mutations.length; i < ii; ++i) {
        let record = mutations[i];
        let added = record.addedNodes;
        let removed = record.removedNodes;
  
        for (let j = 0, jj = removed.length; j < jj; ++j) {
          let node = removed[j];
          if (node.nodeType === 1) {
            for (let k = 0; k < bindersLength; ++k) {
              let binder = binders[k];
              if (binder.onRemove(node)) {
                trackMutation(groupedMutations, binder, record);
              }
            }
          }
        }
  
        for (let j = 0, jj = added.length; j < jj; ++j) {
          let node = added[j];
          if (node.nodeType === 1) {
            for (let k = 0; k < bindersLength; ++k) {
              let binder = binders[k];
              if (binder.onAdd(node)) {
                trackMutation(groupedMutations, binder, record);
              }
            }
          }
        }
      }
  
      groupedMutations.forEach((value, key) => {
        if (key.changeHandler !== null) {
          key.viewModel[key.changeHandler](value);
        }
      });
    }
  
    let ChildObserverBinder = class ChildObserverBinder {
      constructor(selector, viewHost, property, viewModel, controller, changeHandler, all) {
        this.selector = selector;
        this.viewHost = viewHost;
        this.property = property;
        this.viewModel = viewModel;
        this.controller = controller;
        this.changeHandler = changeHandler in viewModel ? changeHandler : null;
        this.usesShadowDOM = controller.behavior.usesShadowDOM;
        this.all = all;
  
        if (!this.usesShadowDOM && controller.view && controller.view.contentView) {
          this.contentView = controller.view.contentView;
        } else {
          this.contentView = null;
        }
      }
  
      matches(element) {
        if (element.matches(this.selector)) {
          if (this.contentView === null) {
            return true;
          }
  
          let contentView = this.contentView;
          let assignedSlot = element.auAssignedSlot;
  
          if (assignedSlot && assignedSlot.projectFromAnchors) {
            let anchors = assignedSlot.projectFromAnchors;
  
            for (let i = 0, ii = anchors.length; i < ii; ++i) {
              if (anchors[i].auOwnerView === contentView) {
                return true;
              }
            }
  
            return false;
          }
  
          return element.auOwnerView === contentView;
        }
  
        return false;
      }
  
      bind(source) {
        let viewHost = this.viewHost;
        let viewModel = this.viewModel;
        let observer = viewHost.__childObserver__;
  
        if (!observer) {
          observer = viewHost.__childObserver__ = DOM.createMutationObserver(onChildChange);
  
          let options = {
            childList: true,
            subtree: !this.usesShadowDOM
          };
  
          observer.observe(viewHost, options);
          observer.binders = [];
        }
  
        observer.binders.push(this);
  
        if (this.usesShadowDOM) {
          let current = viewHost.firstElementChild;
  
          if (this.all) {
            let items = viewModel[this.property];
            if (!items) {
              items = viewModel[this.property] = [];
            } else {
              items.splice(0);
            }
  
            while (current) {
              if (this.matches(current)) {
                items.push(current.au && current.au.controller ? current.au.controller.viewModel : current);
              }
  
              current = current.nextElementSibling;
            }
  
            if (this.changeHandler !== null) {
              this.viewModel[this.changeHandler](noMutations);
            }
          } else {
            while (current) {
              if (this.matches(current)) {
                let value = current.au && current.au.controller ? current.au.controller.viewModel : current;
                this.viewModel[this.property] = value;
  
                if (this.changeHandler !== null) {
                  this.viewModel[this.changeHandler](value);
                }
  
                break;
              }
  
              current = current.nextElementSibling;
            }
          }
        }
      }
  
      onRemove(element) {
        if (this.matches(element)) {
          let value = element.au && element.au.controller ? element.au.controller.viewModel : element;
  
          if (this.all) {
            let items = this.viewModel[this.property] || (this.viewModel[this.property] = []);
            let index = items.indexOf(value);
  
            if (index !== -1) {
              items.splice(index, 1);
            }
  
            return true;
          }
  
          return false;
        }
  
        return false;
      }
  
      onAdd(element) {
        if (this.matches(element)) {
          let value = element.au && element.au.controller ? element.au.controller.viewModel : element;
  
          if (this.all) {
            let items = this.viewModel[this.property] || (this.viewModel[this.property] = []);
  
            if (this.selector === '*') {
              items.push(value);
              return true;
            }
  
            let index = 0;
            let prev = element.previousElementSibling;
  
            while (prev) {
              if (this.matches(prev)) {
                index++;
              }
  
              prev = prev.previousElementSibling;
            }
  
            items.splice(index, 0, value);
            return true;
          }
  
          this.viewModel[this.property] = value;
  
          if (this.changeHandler !== null) {
            this.viewModel[this.changeHandler](value);
          }
        }
  
        return false;
      }
  
      unbind() {
        if (this.viewHost.__childObserver__) {
          this.viewHost.__childObserver__.disconnect();
          this.viewHost.__childObserver__ = null;
          this.viewModel[this.property] = null;
        }
      }
    };
  
  
    function remove(viewSlot, previous) {
      return Array.isArray(previous) ? viewSlot.removeMany(previous, true) : viewSlot.remove(previous, true);
    }
  
    const SwapStrategies = {
      before(viewSlot, previous, callback) {
        return previous === undefined ? callback() : callback().then(() => remove(viewSlot, previous));
      },
  
      with(viewSlot, previous, callback) {
        return previous === undefined ? callback() : Promise.all([remove(viewSlot, previous), callback()]);
      },
  
      after(viewSlot, previous, callback) {
        return Promise.resolve(viewSlot.removeAll(true)).then(callback);
      }
    };
  
    function tryActivateViewModel(context) {
      if (context.skipActivation || typeof context.viewModel.activate !== 'function') {
        return Promise.resolve();
      }
  
      return context.viewModel.activate(context.model) || Promise.resolve();
    }
  
    let CompositionEngine = (_dec10$1 = inject(ViewEngine, ViewLocator), _dec10$1(_class17 = class CompositionEngine {
      constructor(viewEngine, viewLocator) {
        this.viewEngine = viewEngine;
        this.viewLocator = viewLocator;
      }
  
      _swap(context, view) {
        let swapStrategy = SwapStrategies[context.swapOrder] || SwapStrategies.after;
        let previousViews = context.viewSlot.children.slice();
  
        return swapStrategy(context.viewSlot, previousViews, () => {
          return Promise.resolve(context.viewSlot.add(view)).then(() => {
            if (context.currentController) {
              context.currentController.unbind();
            }
          });
        }).then(() => {
          if (context.compositionTransactionNotifier) {
            context.compositionTransactionNotifier.done();
          }
        });
      }
  
      _createControllerAndSwap(context) {
        return this.createController(context).then(controller => {
          if (context.compositionTransactionOwnershipToken) {
            return context.compositionTransactionOwnershipToken.waitForCompositionComplete().then(() => {
              controller.automate(context.overrideContext, context.owningView);
  
              return this._swap(context, controller.view);
            }).then(() => controller);
          }
  
          controller.automate(context.overrideContext, context.owningView);
  
          return this._swap(context, controller.view).then(() => controller);
        });
      }
  
      createController(context) {
        let childContainer;
        let viewModel;
        let viewModelResource;
  
        let m;
  
        return this.ensureViewModel(context).then(tryActivateViewModel).then(() => {
          childContainer = context.childContainer;
          viewModel = context.viewModel;
          viewModelResource = context.viewModelResource;
          m = viewModelResource.metadata;
  
          let viewStrategy = this.viewLocator.getViewStrategy(context.view || viewModel);
  
          if (context.viewResources) {
            viewStrategy.makeRelativeTo(context.viewResources.viewUrl);
          }
  
          return m.load(childContainer, viewModelResource.value, null, viewStrategy, true);
        }).then(viewFactory => m.create(childContainer, BehaviorInstruction.dynamic(context.host, viewModel, viewFactory)));
      }
  
      ensureViewModel(context) {
        let childContainer = context.childContainer = context.childContainer || context.container.createChild();
  
        if (typeof context.viewModel === 'string') {
          context.viewModel = context.viewResources ? context.viewResources.relativeToView(context.viewModel) : context.viewModel;
  
          return this.viewEngine.importViewModelResource(context.viewModel).then(viewModelResource => {
            childContainer.autoRegister(viewModelResource.value);
  
            if (context.host) {
              childContainer.registerInstance(DOM.Element, context.host);
            }
  
            context.viewModel = childContainer.viewModel = childContainer.get(viewModelResource.value);
            context.viewModelResource = viewModelResource;
            return context;
          });
        }
  
        let ctor = context.viewModel.constructor;
        let isClass = typeof context.viewModel === 'function';
        if (isClass) {
          ctor = context.viewModel;
          childContainer.autoRegister(ctor);
        }
        let m = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, ctor);
  
        m.elementName = m.elementName || 'dynamic-element';
  
        m.initialize(isClass ? childContainer : context.container || childContainer, ctor);
  
        context.viewModelResource = { metadata: m, value: ctor };
  
        if (context.host) {
          childContainer.registerInstance(DOM.Element, context.host);
        }
        childContainer.viewModel = context.viewModel = isClass ? childContainer.get(ctor) : context.viewModel;
        return Promise.resolve(context);
      }
  
      compose(context) {
        context.childContainer = context.childContainer || context.container.createChild();
        context.view = this.viewLocator.getViewStrategy(context.view);
  
        let transaction = context.childContainer.get(CompositionTransaction);
        let compositionTransactionOwnershipToken = transaction.tryCapture();
  
        if (compositionTransactionOwnershipToken) {
          context.compositionTransactionOwnershipToken = compositionTransactionOwnershipToken;
        } else {
          context.compositionTransactionNotifier = transaction.enlist();
        }
  
        if (context.viewModel) {
          return this._createControllerAndSwap(context);
        } else if (context.view) {
          if (context.viewResources) {
            context.view.makeRelativeTo(context.viewResources.viewUrl);
          }
  
          return context.view.loadViewFactory(this.viewEngine, new ViewCompileInstruction()).then(viewFactory => {
            let result = viewFactory.create(context.childContainer);
            result.bind(context.bindingContext, context.overrideContext);
  
            if (context.compositionTransactionOwnershipToken) {
              return context.compositionTransactionOwnershipToken.waitForCompositionComplete().then(() => this._swap(context, result)).then(() => result);
            }
  
            return this._swap(context, result).then(() => result);
          });
        } else if (context.viewSlot) {
          context.viewSlot.removeAll();
  
          if (context.compositionTransactionNotifier) {
            context.compositionTransactionNotifier.done();
          }
  
          return Promise.resolve(null);
        }
  
        return Promise.resolve(null);
      }
    }) || _class17);
  
    let ElementConfigResource = class ElementConfigResource {
      initialize(container, target) {}
  
      register(registry, name) {}
  
      load(container, target) {
        let config = new target();
        let eventManager = container.get(EventManager);
        eventManager.registerElementConfig(config);
      }
    };
  
    function resource(instanceOrConfig) {
      return function (target) {
        let isConfig = typeof instanceOrConfig === 'string' || Object.getPrototypeOf(instanceOrConfig) === Object.prototype;
        if (isConfig) {
          target.$resource = instanceOrConfig;
        } else {
          metadata.define(metadata.resource, instanceOrConfig, target);
        }
      };
    }
  
    function behavior(override) {
      return function (target) {
        if (override instanceof HtmlBehaviorResource) {
          metadata.define(metadata.resource, override, target);
        } else {
          let r = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, target);
          Object.assign(r, override);
        }
      };
    }
  
    function customElement(name) {
      return function (target) {
        let r = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, target);
        r.elementName = validateBehaviorName(name, 'custom element');
      };
    }
  
    function customAttribute(name, defaultBindingMode, aliases) {
      return function (target) {
        let r = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, target);
        r.attributeName = validateBehaviorName(name, 'custom attribute');
        r.attributeDefaultBindingMode = defaultBindingMode;
        r.aliases = aliases;
      };
    }
  
    function templateController(target) {
      let deco = function (t) {
        let r = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, t);
        r.liftsContent = true;
      };
  
      return target ? deco(target) : deco;
    }
  
    function bindable(nameOrConfigOrTarget, key, descriptor) {
      let deco = function (target, key2, descriptor2) {
        let actualTarget = key2 ? target.constructor : target;
        let r = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, actualTarget);
        let prop;
  
        if (key2) {
          nameOrConfigOrTarget = nameOrConfigOrTarget || {};
          nameOrConfigOrTarget.name = key2;
        }
  
        prop = new BindableProperty(nameOrConfigOrTarget);
        return prop.registerWith(actualTarget, r, descriptor2);
      };
  
      if (!nameOrConfigOrTarget) {
        return deco;
      }
  
      if (key) {
        let target = nameOrConfigOrTarget;
        nameOrConfigOrTarget = null;
        return deco(target, key, descriptor);
      }
  
      return deco;
    }
  
    function dynamicOptions(target) {
      let deco = function (t) {
        let r = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, t);
        r.hasDynamicOptions = true;
      };
  
      return target ? deco(target) : deco;
    }
  
    const defaultShadowDOMOptions = { mode: 'open' };
  
    function useShadowDOM(targetOrOptions) {
      let options = typeof targetOrOptions === 'function' || !targetOrOptions ? defaultShadowDOMOptions : targetOrOptions;
  
      let deco = function (t) {
        let r = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, t);
        r.targetShadowDOM = true;
        r.shadowDOMOptions = options;
      };
  
      return typeof targetOrOptions === 'function' ? deco(targetOrOptions) : deco;
    }
  
    function processAttributes(processor) {
      return function (t) {
        let r = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, t);
        r.processAttributes = function (compiler, resources, node, attributes, elementInstruction) {
          try {
            processor(compiler, resources, node, attributes, elementInstruction);
          } catch (error) {
            getLogger('templating').error(error);
          }
        };
      };
    }
  
    function doNotProcessContent() {
      return false;
    }
  
    function processContent(processor) {
      return function (t) {
        let r = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, t);
        r.processContent = processor ? function (compiler, resources, node, instruction) {
          try {
            return processor(compiler, resources, node, instruction);
          } catch (error) {
            getLogger('templating').error(error);
            return false;
          }
        } : doNotProcessContent;
      };
    }
  
    function containerless(target) {
      let deco = function (t) {
        let r = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, t);
        r.containerless = true;
      };
  
      return target ? deco(target) : deco;
    }
  
    function useViewStrategy(strategy) {
      return function (target) {
        metadata.define(ViewLocator.viewStrategyMetadataKey, strategy, target);
      };
    }
  
    function useView(path) {
      return useViewStrategy(new RelativeViewStrategy(path));
    }
  
    function inlineView(markup, dependencies, dependencyBaseUrl) {
      return useViewStrategy(new InlineViewStrategy(markup, dependencies, dependencyBaseUrl));
    }
  
    function noView(targetOrDependencies, dependencyBaseUrl) {
      let target;
      let dependencies;
      if (typeof targetOrDependencies === 'function') {
        target = targetOrDependencies;
      } else {
        dependencies = targetOrDependencies;
        target = undefined;
      }
  
      let deco = function (t) {
        metadata.define(ViewLocator.viewStrategyMetadataKey, new NoViewStrategy(dependencies, dependencyBaseUrl), t);
      };
  
      return target ? deco(target) : deco;
    }
  
    function view(templateOrConfig) {
      return function (target) {
        target.$view = templateOrConfig;
      };
    }
  
    function elementConfig(target) {
      let deco = function (t) {
        metadata.define(metadata.resource, new ElementConfigResource(), t);
      };
  
      return target ? deco(target) : deco;
    }
  
    function viewResources(...resources) {
      return function (target) {
        metadata.define(ViewEngine.viewModelRequireMetadataKey, resources, target);
      };
    }
  
    let TemplatingEngine = (_dec11 = inject(Container, ModuleAnalyzer, ViewCompiler, CompositionEngine), _dec11(_class18 = class TemplatingEngine {
      constructor(container, moduleAnalyzer, viewCompiler, compositionEngine) {
        this._container = container;
        this._moduleAnalyzer = moduleAnalyzer;
        this._viewCompiler = viewCompiler;
        this._compositionEngine = compositionEngine;
        container.registerInstance(Animator, Animator.instance = new Animator());
      }
  
      configureAnimator(animator) {
        this._container.unregister(Animator);
        this._container.registerInstance(Animator, Animator.instance = animator);
      }
  
      compose(context) {
        return this._compositionEngine.compose(context);
      }
  
      enhance(instruction) {
        if (instruction instanceof DOM.Element) {
          instruction = { element: instruction };
        }
  
        let compilerInstructions = { letExpressions: [] };
        let resources = instruction.resources || this._container.get(ViewResources);
  
        this._viewCompiler._compileNode(instruction.element, resources, compilerInstructions, instruction.element.parentNode, 'root', true);
  
        let factory = new ViewFactory(instruction.element, compilerInstructions, resources);
        let container = instruction.container || this._container.createChild();
        let view = factory.create(container, BehaviorInstruction.enhance());
  
        view.bind(instruction.bindingContext || {}, instruction.overrideContext);
  
        view.firstChild = view.lastChild = view.fragment;
        view.fragment = DOM.createDocumentFragment();
        view.attached();
  
        return view;
      }
    }) || _class18);
  
    function preventActionlessFormSubmit() {
      DOM.addEventListener('submit', evt => {
        const target = evt.target;
        const action = target.action;
  
        if (target.tagName.toLowerCase() === 'form' && !action) {
          evt.preventDefault();
        }
      });
    }
  
    let Aurelia = class Aurelia {
      constructor(loader, container, resources) {
        this.loader = loader || new PLATFORM.Loader();
        this.container = container || new Container().makeGlobal();
        this.resources = resources || new ViewResources();
        this.use = new FrameworkConfiguration(this);
        this.logger = getLogger('aurelia');
        this.hostConfigured = false;
        this.host = null;
  
        this.use.instance(Aurelia, this);
        this.use.instance(Loader, this.loader);
        this.use.instance(ViewResources, this.resources);
      }
  
      start() {
        if (this._started) {
          return this._started;
        }
  
        this.logger.info('Aurelia Starting');
        return this._started = this.use.apply().then(() => {
          preventActionlessFormSubmit();
  
          if (!this.container.hasResolver(BindingLanguage)) {
            let message = 'You must configure Aurelia with a BindingLanguage implementation.';
            this.logger.error(message);
            throw new Error(message);
          }
  
          this.logger.info('Aurelia Started');
          let evt = DOM.createCustomEvent('aurelia-started', { bubbles: true, cancelable: true });
          DOM.dispatchEvent(evt);
          return this;
        });
      }
  
      enhance(bindingContext = {}, applicationHost = null) {
        this._configureHost(applicationHost || DOM.querySelectorAll('body')[0]);
  
        return new Promise(resolve => {
          let engine = this.container.get(TemplatingEngine);
          this.root = engine.enhance({ container: this.container, element: this.host, resources: this.resources, bindingContext: bindingContext });
          this.root.attached();
          this._onAureliaComposed();
          resolve(this);
        });
      }
  
      setRoot(root = null, applicationHost = null) {
        let instruction = {};
  
        if (this.root && this.root.viewModel && this.root.viewModel.router) {
          this.root.viewModel.router.deactivate();
          this.root.viewModel.router.reset();
        }
  
        this._configureHost(applicationHost);
  
        let engine = this.container.get(TemplatingEngine);
        let transaction = this.container.get(CompositionTransaction);
        delete transaction.initialComposition;
  
        if (!root) {
          if (this.configModuleId) {
            root = relativeToFile('./app', this.configModuleId);
          } else {
            root = 'app';
          }
        }
  
        instruction.viewModel = root;
        instruction.container = instruction.childContainer = this.container;
        instruction.viewSlot = this.hostSlot;
        instruction.host = this.host;
  
        return engine.compose(instruction).then(r => {
          this.root = r;
          instruction.viewSlot.attached();
          this._onAureliaComposed();
          return this;
        });
      }
  
      _configureHost(applicationHost) {
        if (this.hostConfigured) {
          return;
        }
        applicationHost = applicationHost || this.host;
  
        if (!applicationHost || typeof applicationHost === 'string') {
          this.host = DOM.getElementById(applicationHost || 'applicationHost');
        } else {
          this.host = applicationHost;
        }
  
        if (!this.host) {
          throw new Error('No applicationHost was specified.');
        }
  
        this.hostConfigured = true;
        this.host.aurelia = this;
        this.hostSlot = new ViewSlot(this.host, true);
        this.hostSlot.transformChildNodesIntoView();
        this.container.registerInstance(DOM.boundary, this.host);
      }
  
      _onAureliaComposed() {
        let evt = DOM.createCustomEvent('aurelia-composed', { bubbles: true, cancelable: true });
        setTimeout(() => DOM.dispatchEvent(evt), 1);
      }
    };
  
    const logger$2 = getLogger('aurelia');
    const extPattern = /\.[^/.]+$/;
  
    function runTasks(config, tasks) {
      let current;
      let next = () => {
        current = tasks.shift();
        if (current) {
          return Promise.resolve(current(config)).then(next);
        }
  
        return Promise.resolve();
      };
  
      return next();
    }
  
    function loadPlugin(fwConfig, loader, info) {
      logger$2.debug(`Loading plugin ${info.moduleId}.`);
      if (typeof info.moduleId === 'string') {
        fwConfig.resourcesRelativeTo = info.resourcesRelativeTo;
  
        let id = info.moduleId;
  
        if (info.resourcesRelativeTo.length > 1) {
          return loader.normalize(info.moduleId, info.resourcesRelativeTo[1]).then(normalizedId => _loadPlugin(normalizedId));
        }
  
        return _loadPlugin(id);
      } else if (typeof info.configure === 'function') {
        if (fwConfig.configuredPlugins.indexOf(info.configure) !== -1) {
          return Promise.resolve();
        }
        fwConfig.configuredPlugins.push(info.configure);
  
        return Promise.resolve(info.configure.call(null, fwConfig, info.config || {}));
      }
      throw new Error(invalidConfigMsg(info.moduleId || info.configure, 'plugin'));
  
      function _loadPlugin(moduleId) {
        return loader.loadModule(moduleId).then(m => {
          if ('configure' in m) {
            if (fwConfig.configuredPlugins.indexOf(m.configure) !== -1) {
              return Promise.resolve();
            }
            return Promise.resolve(m.configure(fwConfig, info.config || {})).then(() => {
              fwConfig.configuredPlugins.push(m.configure);
              fwConfig.resourcesRelativeTo = null;
              logger$2.debug(`Configured plugin ${info.moduleId}.`);
            });
          }
  
          fwConfig.resourcesRelativeTo = null;
          logger$2.debug(`Loaded plugin ${info.moduleId}.`);
        });
      }
    }
  
    function loadResources(aurelia, resourcesToLoad, appResources) {
      if (Object.keys(resourcesToLoad).length === 0) {
        return Promise.resolve();
      }
      let viewEngine = aurelia.container.get(ViewEngine);
  
      return Promise.all(Object.keys(resourcesToLoad).map(n => _normalize(resourcesToLoad[n]))).then(loads => {
        let names = [];
        let importIds = [];
  
        loads.forEach(l => {
          names.push(undefined);
          importIds.push(l.importId);
        });
  
        return viewEngine.importViewResources(importIds, names, appResources);
      });
  
      function _normalize(load) {
        let moduleId = load.moduleId;
        let ext = getExt(moduleId);
  
        if (isOtherResource(moduleId)) {
          moduleId = removeExt(moduleId);
        }
  
        return aurelia.loader.normalize(moduleId, load.relativeTo).then(normalized => {
          return {
            name: load.moduleId,
            importId: isOtherResource(load.moduleId) ? addOriginalExt(normalized, ext) : normalized
          };
        });
      }
  
      function isOtherResource(name) {
        let ext = getExt(name);
        if (!ext) return false;
        if (ext === '') return false;
        if (ext === '.js' || ext === '.ts') return false;
        return true;
      }
  
      function removeExt(name) {
        return name.replace(extPattern, '');
      }
  
      function addOriginalExt(normalized, ext) {
        return removeExt(normalized) + '.' + ext;
      }
    }
  
    function getExt(name) {
      let match = name.match(extPattern);
      if (match && match.length > 0) {
        return match[0].split('.')[1];
      }
    }
  
    function loadBehaviors(config) {
      return Promise.all(config.behaviorsToLoad.map(m => m.load(config.container, m.target))).then(() => {
        config.behaviorsToLoad = null;
      });
    }
  
    function assertProcessed(plugins) {
      if (plugins.processed) {
        throw new Error('This config instance has already been applied. To load more plugins or global resources, create a new FrameworkConfiguration instance.');
      }
    }
  
    function invalidConfigMsg(cfg, type) {
      return `Invalid ${type} [${cfg}], ${type} must be specified as functions or relative module IDs.`;
    }
  
    let FrameworkConfiguration = class FrameworkConfiguration {
      constructor(aurelia) {
        this.aurelia = aurelia;
        this.container = aurelia.container;
  
        this.info = [];
        this.processed = false;
        this.preTasks = [];
        this.postTasks = [];
  
        this.behaviorsToLoad = [];
  
        this.configuredPlugins = [];
        this.resourcesToLoad = {};
        this.preTask(() => aurelia.loader.normalize('aurelia-bootstrapper').then(name => this.bootstrapperName = name));
        this.postTask(() => loadResources(aurelia, this.resourcesToLoad, aurelia.resources));
      }
  
      instance(type, instance) {
        this.container.registerInstance(type, instance);
        return this;
      }
  
      singleton(type, implementation) {
        this.container.registerSingleton(type, implementation);
        return this;
      }
  
      transient(type, implementation) {
        this.container.registerTransient(type, implementation);
        return this;
      }
  
      preTask(task) {
        assertProcessed(this);
        this.preTasks.push(task);
        return this;
      }
  
      postTask(task) {
        assertProcessed(this);
        this.postTasks.push(task);
        return this;
      }
  
      feature(plugin, config = {}) {
        switch (typeof plugin) {
          case 'string':
            let hasIndex = /\/index$/i.test(plugin);
            let moduleId = hasIndex || getExt(plugin) ? plugin : plugin + '/index';
            let root = hasIndex ? plugin.substr(0, plugin.length - 6) : plugin;
            this.info.push({ moduleId, resourcesRelativeTo: [root, ''], config });
            break;
  
          case 'function':
            this.info.push({ configure: plugin, config: config || {} });
            break;
          default:
            throw new Error(invalidConfigMsg(plugin, 'feature'));
        }
        return this;
      }
  
      globalResources(resources) {
        assertProcessed(this);
  
        let toAdd = Array.isArray(resources) ? resources : arguments;
        let resource;
        let resourcesRelativeTo = this.resourcesRelativeTo || ['', ''];
  
        for (let i = 0, ii = toAdd.length; i < ii; ++i) {
          resource = toAdd[i];
          switch (typeof resource) {
            case 'string':
              let parent = resourcesRelativeTo[0];
              let grandParent = resourcesRelativeTo[1];
              let name = resource;
  
              if ((resource.startsWith('./') || resource.startsWith('../')) && parent !== '') {
                name = join(parent, resource);
              }
  
              this.resourcesToLoad[name] = { moduleId: name, relativeTo: grandParent };
              break;
            case 'function':
              let meta = this.aurelia.resources.autoRegister(this.container, resource);
              if (meta instanceof HtmlBehaviorResource && meta.elementName !== null) {
                if (this.behaviorsToLoad.push(meta) === 1) {
                  this.postTask(() => loadBehaviors(this));
                }
              }
              break;
            default:
              throw new Error(invalidConfigMsg(resource, 'resource'));
          }
        }
  
        return this;
      }
  
      globalName(resourcePath, newName) {
        assertProcessed(this);
        this.resourcesToLoad[resourcePath] = { moduleId: newName, relativeTo: '' };
        return this;
      }
  
      plugin(plugin, pluginConfig) {
        assertProcessed(this);
  
        let info;
        switch (typeof plugin) {
          case 'string':
            info = { moduleId: plugin, resourcesRelativeTo: [plugin, ''], config: pluginConfig || {} };
            break;
          case 'function':
            info = { configure: plugin, config: pluginConfig || {} };
            break;
          default:
            throw new Error(invalidConfigMsg(plugin, 'plugin'));
        }
        this.info.push(info);
        return this;
      }
  
      _addNormalizedPlugin(name, config) {
        let plugin = { moduleId: name, resourcesRelativeTo: [name, ''], config: config || {} };
        this.info.push(plugin);
  
        this.preTask(() => {
          let relativeTo = [name, this.bootstrapperName];
          plugin.moduleId = name;
          plugin.resourcesRelativeTo = relativeTo;
          return Promise.resolve();
        });
  
        return this;
      }
  
      defaultBindingLanguage() {
        return this._addNormalizedPlugin('aurelia-templating-binding');
      }
  
      router() {
        return this._addNormalizedPlugin('aurelia-templating-router');
      }
  
      history() {
        return this._addNormalizedPlugin('aurelia-history-browser');
      }
  
      defaultResources() {
        return this._addNormalizedPlugin('aurelia-templating-resources');
      }
  
      eventAggregator() {
        return this._addNormalizedPlugin('aurelia-event-aggregator');
      }
  
      basicConfiguration() {
        return this.defaultBindingLanguage().defaultResources().eventAggregator();
      }
  
      standardConfiguration() {
        return this.basicConfiguration().history().router();
      }
  
      developmentLogging(level) {
        let logLevel$1 = level ? logLevel[level] : undefined;
  
        if (logLevel$1 === undefined) {
          logLevel$1 = logLevel.debug;
        }
  
        this.preTask(() => {
          return this.aurelia.loader.normalize('aurelia-logging-console', this.bootstrapperName).then(name => {
            return this.aurelia.loader.loadModule(name).then(m => {
              addAppender(new m.ConsoleAppender());
              setLevel(logLevel$1);
            });
          });
        });
  
        return this;
      }
  
      apply() {
        if (this.processed) {
          return Promise.resolve();
        }
  
        return runTasks(this, this.preTasks).then(() => {
          let loader = this.aurelia.loader;
          let info = this.info;
          let current;
  
          let next = () => {
            current = info.shift();
            if (current) {
              return loadPlugin(this, loader, current).then(next);
            }
  
            this.processed = true;
            this.configuredPlugins = null;
            return Promise.resolve();
          };
  
          return next().then(() => runTasks(this, this.postTasks));
        });
      }
    };
  
    const LogManager = TheLogManager;
  
    var _class$3, _temp$2, _dec$3, _class2$3, _dec2$3, _class3$3, _class4$2, _temp2$2, _class5$3, _temp3$1;
  
    let AttributeMap = (_temp$2 = _class$3 = class AttributeMap {
  
      constructor(svg) {
        this.elements = Object.create(null);
        this.allElements = Object.create(null);
  
        this.svg = svg;
  
        this.registerUniversal('accesskey', 'accessKey');
        this.registerUniversal('contenteditable', 'contentEditable');
        this.registerUniversal('tabindex', 'tabIndex');
        this.registerUniversal('textcontent', 'textContent');
        this.registerUniversal('innerhtml', 'innerHTML');
        this.registerUniversal('scrolltop', 'scrollTop');
        this.registerUniversal('scrollleft', 'scrollLeft');
        this.registerUniversal('readonly', 'readOnly');
  
        this.register('label', 'for', 'htmlFor');
  
        this.register('img', 'usemap', 'useMap');
  
        this.register('input', 'maxlength', 'maxLength');
        this.register('input', 'minlength', 'minLength');
        this.register('input', 'formaction', 'formAction');
        this.register('input', 'formenctype', 'formEncType');
        this.register('input', 'formmethod', 'formMethod');
        this.register('input', 'formnovalidate', 'formNoValidate');
        this.register('input', 'formtarget', 'formTarget');
  
        this.register('textarea', 'maxlength', 'maxLength');
  
        this.register('td', 'rowspan', 'rowSpan');
        this.register('td', 'colspan', 'colSpan');
        this.register('th', 'rowspan', 'rowSpan');
        this.register('th', 'colspan', 'colSpan');
      }
  
      register(elementName, attributeName, propertyName) {
        elementName = elementName.toLowerCase();
        attributeName = attributeName.toLowerCase();
        const element = this.elements[elementName] = this.elements[elementName] || Object.create(null);
        element[attributeName] = propertyName;
      }
  
      registerUniversal(attributeName, propertyName) {
        attributeName = attributeName.toLowerCase();
        this.allElements[attributeName] = propertyName;
      }
  
      map(elementName, attributeName) {
        if (this.svg.isStandardSvgAttribute(elementName, attributeName)) {
          return attributeName;
        }
        elementName = elementName.toLowerCase();
        attributeName = attributeName.toLowerCase();
        const element = this.elements[elementName];
        if (element !== undefined && attributeName in element) {
          return element[attributeName];
        }
        if (attributeName in this.allElements) {
          return this.allElements[attributeName];
        }
  
        if (/(?:^data-)|(?:^aria-)|:/.test(attributeName)) {
          return attributeName;
        }
        return camelCase(attributeName);
      }
    }, _class$3.inject = [SVGAnalyzer], _temp$2);
  
    let InterpolationBindingExpression = class InterpolationBindingExpression {
      constructor(observerLocator, targetProperty, parts, mode, lookupFunctions, attribute) {
        this.observerLocator = observerLocator;
        this.targetProperty = targetProperty;
        this.parts = parts;
        this.mode = mode;
        this.lookupFunctions = lookupFunctions;
        this.attribute = this.attrToRemove = attribute;
        this.discrete = false;
      }
  
      createBinding(target) {
        if (this.parts.length === 3) {
          return new ChildInterpolationBinding(target, this.observerLocator, this.parts[1], this.mode, this.lookupFunctions, this.targetProperty, this.parts[0], this.parts[2]);
        }
        return new InterpolationBinding(this.observerLocator, this.parts, target, this.targetProperty, this.mode, this.lookupFunctions);
      }
    };
  
    function validateTarget(target, propertyName) {
      if (propertyName === 'style') {
        getLogger('templating-binding').info('Internet Explorer does not support interpolation in "style" attributes.  Use the style attribute\'s alias, "css" instead.');
      } else if (target.parentElement && target.parentElement.nodeName === 'TEXTAREA' && propertyName === 'textContent') {
        throw new Error('Interpolation binding cannot be used in the content of a textarea element.  Use <textarea value.bind="expression"></textarea> instead.');
      }
    }
  
    let InterpolationBinding = class InterpolationBinding {
      constructor(observerLocator, parts, target, targetProperty, mode, lookupFunctions) {
        validateTarget(target, targetProperty);
        this.observerLocator = observerLocator;
        this.parts = parts;
        this.target = target;
        this.targetProperty = targetProperty;
        this.targetAccessor = observerLocator.getAccessor(target, targetProperty);
        this.mode = mode;
        this.lookupFunctions = lookupFunctions;
      }
  
      interpolate() {
        if (this.isBound) {
          let value = '';
          let parts = this.parts;
          for (let i = 0, ii = parts.length; i < ii; i++) {
            value += i % 2 === 0 ? parts[i] : this[`childBinding${i}`].value;
          }
          this.targetAccessor.setValue(value, this.target, this.targetProperty);
        }
      }
  
      updateOneTimeBindings() {
        for (let i = 1, ii = this.parts.length; i < ii; i += 2) {
          let child = this[`childBinding${i}`];
          if (child.mode === bindingMode.oneTime) {
            child.call();
          }
        }
      }
  
      bind(source) {
        if (this.isBound) {
          if (this.source === source) {
            return;
          }
          this.unbind();
        }
        this.source = source;
  
        let parts = this.parts;
        for (let i = 1, ii = parts.length; i < ii; i += 2) {
          let binding = new ChildInterpolationBinding(this, this.observerLocator, parts[i], this.mode, this.lookupFunctions);
          binding.bind(source);
          this[`childBinding${i}`] = binding;
        }
  
        this.isBound = true;
        this.interpolate();
      }
  
      unbind() {
        if (!this.isBound) {
          return;
        }
        this.isBound = false;
        this.source = null;
        let parts = this.parts;
        for (let i = 1, ii = parts.length; i < ii; i += 2) {
          let name = `childBinding${i}`;
          this[name].unbind();
        }
      }
    };
  
    let ChildInterpolationBinding = (_dec$3 = connectable(), _dec$3(_class2$3 = class ChildInterpolationBinding {
      constructor(target, observerLocator, sourceExpression, mode, lookupFunctions, targetProperty, left, right) {
        if (target instanceof InterpolationBinding) {
          this.parent = target;
        } else {
          validateTarget(target, targetProperty);
          this.target = target;
          this.targetProperty = targetProperty;
          this.targetAccessor = observerLocator.getAccessor(target, targetProperty);
        }
        this.observerLocator = observerLocator;
        this.sourceExpression = sourceExpression;
        this.mode = mode;
        this.lookupFunctions = lookupFunctions;
        this.left = left;
        this.right = right;
      }
  
      updateTarget(value) {
        value = value === null || value === undefined ? '' : value.toString();
        if (value !== this.value) {
          this.value = value;
          if (this.parent) {
            this.parent.interpolate();
          } else {
            this.targetAccessor.setValue(this.left + value + this.right, this.target, this.targetProperty);
          }
        }
      }
  
      call() {
        if (!this.isBound) {
          return;
        }
  
        this.rawValue = this.sourceExpression.evaluate(this.source, this.lookupFunctions);
        this.updateTarget(this.rawValue);
  
        if (this.mode !== bindingMode.oneTime) {
          this._version++;
          this.sourceExpression.connect(this, this.source);
          if (this.rawValue instanceof Array) {
            this.observeArray(this.rawValue);
          }
          this.unobserve(false);
        }
      }
  
      bind(source) {
        if (this.isBound) {
          if (this.source === source) {
            return;
          }
          this.unbind();
        }
        this.isBound = true;
        this.source = source;
  
        let sourceExpression = this.sourceExpression;
        if (sourceExpression.bind) {
          sourceExpression.bind(this, source, this.lookupFunctions);
        }
  
        this.rawValue = sourceExpression.evaluate(source, this.lookupFunctions);
        this.updateTarget(this.rawValue);
  
        if (this.mode === bindingMode.oneWay) {
          enqueueBindingConnect(this);
        }
      }
  
      unbind() {
        if (!this.isBound) {
          return;
        }
        this.isBound = false;
        let sourceExpression = this.sourceExpression;
        if (sourceExpression.unbind) {
          sourceExpression.unbind(this, this.source);
        }
        this.source = null;
        this.value = null;
        this.rawValue = null;
        this.unobserve(true);
      }
  
      connect(evaluate) {
        if (!this.isBound) {
          return;
        }
        if (evaluate) {
          this.rawValue = this.sourceExpression.evaluate(this.source, this.lookupFunctions);
          this.updateTarget(this.rawValue);
        }
        this.sourceExpression.connect(this, this.source);
        if (this.rawValue instanceof Array) {
          this.observeArray(this.rawValue);
        }
      }
    }) || _class2$3);
  
    let LetExpression = class LetExpression {
      constructor(observerLocator, targetProperty, sourceExpression, lookupFunctions, toBindingContext) {
        this.observerLocator = observerLocator;
        this.sourceExpression = sourceExpression;
        this.targetProperty = targetProperty;
        this.lookupFunctions = lookupFunctions;
        this.toBindingContext = toBindingContext;
      }
  
      createBinding() {
        return new LetBinding(this.observerLocator, this.sourceExpression, this.targetProperty, this.lookupFunctions, this.toBindingContext);
      }
    };
  
    let LetBinding = (_dec2$3 = connectable(), _dec2$3(_class3$3 = class LetBinding {
      constructor(observerLocator, sourceExpression, targetProperty, lookupFunctions, toBindingContext) {
        this.observerLocator = observerLocator;
        this.sourceExpression = sourceExpression;
        this.targetProperty = targetProperty;
        this.lookupFunctions = lookupFunctions;
        this.source = null;
        this.target = null;
        this.toBindingContext = toBindingContext;
      }
  
      updateTarget() {
        const value = this.sourceExpression.evaluate(this.source, this.lookupFunctions);
        this.target[this.targetProperty] = value;
      }
  
      call(context) {
        if (!this.isBound) {
          return;
        }
        if (context === sourceContext) {
          this.updateTarget();
          return;
        }
        throw new Error(`Unexpected call context ${context}`);
      }
  
      bind(source) {
        if (this.isBound) {
          if (this.source === source) {
            return;
          }
          this.unbind();
        }
  
        this.isBound = true;
        this.source = source;
        this.target = this.toBindingContext ? source.bindingContext : source.overrideContext;
  
        if (this.sourceExpression.bind) {
          this.sourceExpression.bind(this, source, this.lookupFunctions);
        }
  
        enqueueBindingConnect(this);
      }
  
      unbind() {
        if (!this.isBound) {
          return;
        }
        this.isBound = false;
        if (this.sourceExpression.unbind) {
          this.sourceExpression.unbind(this, this.source);
        }
        this.source = null;
        this.target = null;
        this.unobserve(true);
      }
  
      connect() {
        if (!this.isBound) {
          return;
        }
        this.updateTarget();
        this.sourceExpression.connect(this, this.source);
      }
    }) || _class3$3);
  
    let LetInterpolationBindingExpression = class LetInterpolationBindingExpression {
      constructor(observerLocator, targetProperty, parts, lookupFunctions, toBindingContext) {
        this.observerLocator = observerLocator;
        this.targetProperty = targetProperty;
        this.parts = parts;
        this.lookupFunctions = lookupFunctions;
        this.toBindingContext = toBindingContext;
      }
  
      createBinding() {
        return new LetInterpolationBinding(this.observerLocator, this.targetProperty, this.parts, this.lookupFunctions, this.toBindingContext);
      }
    };
  
    let LetInterpolationBinding = class LetInterpolationBinding {
      constructor(observerLocator, targetProperty, parts, lookupFunctions, toBindingContext) {
        this.observerLocator = observerLocator;
        this.parts = parts;
        this.targetProperty = targetProperty;
        this.lookupFunctions = lookupFunctions;
        this.toBindingContext = toBindingContext;
        this.target = null;
      }
  
      bind(source) {
        if (this.isBound) {
          if (this.source === source) {
            return;
          }
          this.unbind();
        }
  
        this.isBound = true;
        this.source = source;
        this.target = this.toBindingContext ? source.bindingContext : source.overrideContext;
  
        this.interpolationBinding = this.createInterpolationBinding();
        this.interpolationBinding.bind(source);
      }
  
      unbind() {
        if (!this.isBound) {
          return;
        }
        this.isBound = false;
        this.source = null;
        this.target = null;
        this.interpolationBinding.unbind();
        this.interpolationBinding = null;
      }
  
      createInterpolationBinding() {
        if (this.parts.length === 3) {
          return new ChildInterpolationBinding(this.target, this.observerLocator, this.parts[1], bindingMode.oneWay, this.lookupFunctions, this.targetProperty, this.parts[0], this.parts[2]);
        }
        return new InterpolationBinding(this.observerLocator, this.parts, this.target, this.targetProperty, bindingMode.oneWay, this.lookupFunctions);
      }
    };
  
    let SyntaxInterpreter = (_temp2$2 = _class4$2 = class SyntaxInterpreter {
  
      constructor(parser, observerLocator, eventManager, attributeMap) {
        this.parser = parser;
        this.observerLocator = observerLocator;
        this.eventManager = eventManager;
        this.attributeMap = attributeMap;
      }
  
      interpret(resources, element, info, existingInstruction, context) {
        if (info.command in this) {
          return this[info.command](resources, element, info, existingInstruction, context);
        }
  
        return this.handleUnknownCommand(resources, element, info, existingInstruction, context);
      }
  
      handleUnknownCommand(resources, element, info, existingInstruction, context) {
        getLogger('templating-binding').warn('Unknown binding command.', info);
        return existingInstruction;
      }
  
      determineDefaultBindingMode(element, attrName, context) {
        let tagName = element.tagName.toLowerCase();
  
        if (tagName === 'input' && (attrName === 'value' || attrName === 'files') && element.type !== 'checkbox' && element.type !== 'radio' || tagName === 'input' && attrName === 'checked' && (element.type === 'checkbox' || element.type === 'radio') || (tagName === 'textarea' || tagName === 'select') && attrName === 'value' || (attrName === 'textcontent' || attrName === 'innerhtml') && element.contentEditable === 'true' || attrName === 'scrolltop' || attrName === 'scrollleft') {
          return bindingMode.twoWay;
        }
  
        if (context && attrName in context.attributes && context.attributes[attrName] && context.attributes[attrName].defaultBindingMode >= bindingMode.oneTime) {
          return context.attributes[attrName].defaultBindingMode;
        }
  
        return bindingMode.oneWay;
      }
  
      bind(resources, element, info, existingInstruction, context) {
        let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName);
  
        instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, this.attributeMap.map(element.tagName, info.attrName), this.parser.parse(info.attrValue), info.defaultBindingMode === undefined || info.defaultBindingMode === null ? this.determineDefaultBindingMode(element, info.attrName, context) : info.defaultBindingMode, resources.lookupFunctions);
  
        return instruction;
      }
  
      trigger(resources, element, info) {
        return new ListenerExpression(this.eventManager, info.attrName, this.parser.parse(info.attrValue), delegationStrategy.none, true, resources.lookupFunctions);
      }
  
      capture(resources, element, info) {
        return new ListenerExpression(this.eventManager, info.attrName, this.parser.parse(info.attrValue), delegationStrategy.capturing, true, resources.lookupFunctions);
      }
  
      delegate(resources, element, info) {
        return new ListenerExpression(this.eventManager, info.attrName, this.parser.parse(info.attrValue), delegationStrategy.bubbling, true, resources.lookupFunctions);
      }
  
      call(resources, element, info, existingInstruction) {
        let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName);
  
        instruction.attributes[info.attrName] = new CallExpression(this.observerLocator, info.attrName, this.parser.parse(info.attrValue), resources.lookupFunctions);
  
        return instruction;
      }
  
      options(resources, element, info, existingInstruction, context) {
        let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName);
        let attrValue = info.attrValue;
        let language = this.language;
        let name = null;
        let target = '';
        let current;
        let i;
        let ii;
        let inString = false;
        let inEscape = false;
        let foundName = false;
  
        for (i = 0, ii = attrValue.length; i < ii; ++i) {
          current = attrValue[i];
  
          if (current === ';' && !inString) {
            if (!foundName) {
              name = this._getPrimaryPropertyName(resources, context);
            }
            info = language.inspectAttribute(resources, '?', name, target.trim());
            language.createAttributeInstruction(resources, element, info, instruction, context);
  
            if (!instruction.attributes[info.attrName]) {
              instruction.attributes[info.attrName] = info.attrValue;
            }
  
            target = '';
            name = null;
          } else if (current === ':' && name === null) {
            foundName = true;
            name = target.trim();
            target = '';
          } else if (current === '\\') {
            target += current;
            inEscape = true;
            continue;
          } else {
            target += current;
  
            if (name !== null && inEscape === false && current === '\'') {
              inString = !inString;
            }
          }
  
          inEscape = false;
        }
  
        if (!foundName) {
          name = this._getPrimaryPropertyName(resources, context);
        }
  
        if (name !== null) {
          info = language.inspectAttribute(resources, '?', name, target.trim());
          language.createAttributeInstruction(resources, element, info, instruction, context);
  
          if (!instruction.attributes[info.attrName]) {
            instruction.attributes[info.attrName] = info.attrValue;
          }
        }
  
        return instruction;
      }
  
      _getPrimaryPropertyName(resources, context) {
        let type = resources.getAttribute(context.attributeName);
        if (type && type.primaryProperty) {
          return type.primaryProperty.attribute;
        }
        return null;
      }
  
      'for'(resources, element, info, existingInstruction) {
        let parts;
        let keyValue;
        let instruction;
        let attrValue;
        let isDestructuring;
  
        attrValue = info.attrValue;
        isDestructuring = attrValue.match(/^ *[[].+[\]]/);
        parts = isDestructuring ? attrValue.split('of ') : attrValue.split(' of ');
  
        if (parts.length !== 2) {
          throw new Error('Incorrect syntax for "for". The form is: "$local of $items" or "[$key, $value] of $items".');
        }
  
        instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName);
  
        if (isDestructuring) {
          keyValue = parts[0].replace(/[[\]]/g, '').replace(/,/g, ' ').replace(/\s+/g, ' ').trim().split(' ');
          instruction.attributes.key = keyValue[0];
          instruction.attributes.value = keyValue[1];
        } else {
          instruction.attributes.local = parts[0];
        }
  
        instruction.attributes.items = new BindingExpression(this.observerLocator, 'items', this.parser.parse(parts[1]), bindingMode.oneWay, resources.lookupFunctions);
  
        return instruction;
      }
  
      'two-way'(resources, element, info, existingInstruction) {
        let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName);
  
        instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, this.attributeMap.map(element.tagName, info.attrName), this.parser.parse(info.attrValue), bindingMode.twoWay, resources.lookupFunctions);
  
        return instruction;
      }
  
      'to-view'(resources, element, info, existingInstruction) {
        let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName);
  
        instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, this.attributeMap.map(element.tagName, info.attrName), this.parser.parse(info.attrValue), bindingMode.toView, resources.lookupFunctions);
  
        return instruction;
      }
  
      'from-view'(resources, element, info, existingInstruction) {
        let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName);
  
        instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, this.attributeMap.map(element.tagName, info.attrName), this.parser.parse(info.attrValue), bindingMode.fromView, resources.lookupFunctions);
  
        return instruction;
      }
  
      'one-time'(resources, element, info, existingInstruction) {
        let instruction = existingInstruction || BehaviorInstruction.attribute(info.attrName);
  
        instruction.attributes[info.attrName] = new BindingExpression(this.observerLocator, this.attributeMap.map(element.tagName, info.attrName), this.parser.parse(info.attrValue), bindingMode.oneTime, resources.lookupFunctions);
  
        return instruction;
      }
    }, _class4$2.inject = [Parser, ObserverLocator, EventManager, AttributeMap], _temp2$2);
  
    SyntaxInterpreter.prototype['one-way'] = SyntaxInterpreter.prototype['to-view'];
  
    let info = {};
  
    let TemplatingBindingLanguage = (_temp3$1 = _class5$3 = class TemplatingBindingLanguage extends BindingLanguage {
  
      constructor(parser, observerLocator, syntaxInterpreter, attributeMap) {
        super();
        this.parser = parser;
        this.observerLocator = observerLocator;
        this.syntaxInterpreter = syntaxInterpreter;
        this.emptyStringExpression = this.parser.parse('\'\'');
        syntaxInterpreter.language = this;
        this.attributeMap = attributeMap;
        this.toBindingContextAttr = 'to-binding-context';
      }
  
      inspectAttribute(resources, elementName, attrName, attrValue) {
        let parts = attrName.split('.');
  
        info.defaultBindingMode = null;
  
        if (parts.length === 2) {
          info.attrName = parts[0].trim();
          info.attrValue = attrValue;
          info.command = parts[1].trim();
  
          if (info.command === 'ref') {
            info.expression = new NameExpression(this.parser.parse(attrValue), info.attrName, resources.lookupFunctions);
            info.command = null;
            info.attrName = 'ref';
          } else {
            info.expression = null;
          }
        } else if (attrName === 'ref') {
          info.attrName = attrName;
          info.attrValue = attrValue;
          info.command = null;
          info.expression = new NameExpression(this.parser.parse(attrValue), 'element', resources.lookupFunctions);
        } else {
          info.attrName = attrName;
          info.attrValue = attrValue;
          info.command = null;
          const interpolationParts = this.parseInterpolation(resources, attrValue);
          if (interpolationParts === null) {
            info.expression = null;
          } else {
            info.expression = new InterpolationBindingExpression(this.observerLocator, this.attributeMap.map(elementName, attrName), interpolationParts, bindingMode.oneWay, resources.lookupFunctions, attrName);
          }
        }
  
        return info;
      }
  
      createAttributeInstruction(resources, element, theInfo, existingInstruction, context) {
        let instruction;
  
        if (theInfo.expression) {
          if (theInfo.attrName === 'ref') {
            return theInfo.expression;
          }
  
          instruction = existingInstruction || BehaviorInstruction.attribute(theInfo.attrName);
          instruction.attributes[theInfo.attrName] = theInfo.expression;
        } else if (theInfo.command) {
          instruction = this.syntaxInterpreter.interpret(resources, element, theInfo, existingInstruction, context);
        }
  
        return instruction;
      }
  
      createLetExpressions(resources, letElement) {
        let expressions = [];
        let attributes = letElement.attributes;
  
        let attr;
  
        let parts;
        let attrName;
        let attrValue;
        let command;
        let toBindingContextAttr = this.toBindingContextAttr;
        let toBindingContext = letElement.hasAttribute(toBindingContextAttr);
        for (let i = 0, ii = attributes.length; ii > i; ++i) {
          attr = attributes[i];
          attrName = attr.name;
          attrValue = attr.nodeValue;
          parts = attrName.split('.');
  
          if (attrName === toBindingContextAttr) {
            continue;
          }
  
          if (parts.length === 2) {
            command = parts[1];
            if (command !== 'bind') {
              getLogger('templating-binding-language').warn(`Detected invalid let command. Expected "${parts[0]}.bind", given "${attrName}"`);
              continue;
            }
            expressions.push(new LetExpression(this.observerLocator, camelCase(parts[0]), this.parser.parse(attrValue), resources.lookupFunctions, toBindingContext));
          } else {
            attrName = camelCase(attrName);
            parts = this.parseInterpolation(resources, attrValue);
            if (parts === null) {
              getLogger('templating-binding-language').warn(`Detected string literal in let bindings. Did you mean "${attrName}.bind=${attrValue}" or "${attrName}=\${${attrValue}}" ?`);
            }
            if (parts) {
              expressions.push(new LetInterpolationBindingExpression(this.observerLocator, attrName, parts, resources.lookupFunctions, toBindingContext));
            } else {
              expressions.push(new LetExpression(this.observerLocator, attrName, new LiteralString(attrValue), resources.lookupFunctions, toBindingContext));
            }
          }
        }
        return expressions;
      }
  
      inspectTextContent(resources, value) {
        const parts = this.parseInterpolation(resources, value);
        if (parts === null) {
          return null;
        }
        return new InterpolationBindingExpression(this.observerLocator, 'textContent', parts, bindingMode.oneWay, resources.lookupFunctions, 'textContent');
      }
  
      parseInterpolation(resources, value) {
        let i = value.indexOf('${', 0);
        let ii = value.length;
        let char;
        let pos = 0;
        let open = 0;
        let quote = null;
        let interpolationStart;
        let parts;
        let partIndex = 0;
  
        while (i >= 0 && i < ii - 2) {
          open = 1;
          interpolationStart = i;
          i += 2;
  
          do {
            char = value[i];
            i++;
  
            if (char === "'" || char === '"') {
              if (quote === null) {
                quote = char;
              } else if (quote === char) {
                quote = null;
              }
              continue;
            }
  
            if (char === '\\') {
              i++;
              continue;
            }
  
            if (quote !== null) {
              continue;
            }
  
            if (char === '{') {
              open++;
            } else if (char === '}') {
              open--;
            }
          } while (open > 0 && i < ii);
  
          if (open === 0) {
            parts = parts || [];
            if (value[interpolationStart - 1] === '\\' && value[interpolationStart - 2] !== '\\') {
              parts[partIndex] = value.substring(pos, interpolationStart - 1) + value.substring(interpolationStart, i);
              partIndex++;
              parts[partIndex] = this.emptyStringExpression;
              partIndex++;
            } else {
              parts[partIndex] = value.substring(pos, interpolationStart);
              partIndex++;
              parts[partIndex] = this.parser.parse(value.substring(interpolationStart + 2, i - 1));
              partIndex++;
            }
            pos = i;
            i = value.indexOf('${', i);
          } else {
            break;
          }
        }
  
        if (partIndex === 0) {
          return null;
        }
  
        parts[partIndex] = value.substr(pos);
        return parts;
      }
    }, _class5$3.inject = [Parser, ObserverLocator, SyntaxInterpreter, AttributeMap], _temp3$1);
  
    function configure(config) {
      config.container.registerSingleton(BindingLanguage, TemplatingBindingLanguage);
      config.container.registerAlias(BindingLanguage, TemplatingBindingLanguage);
    }
  
    var _dec$4, _class$4, _class2$4, _descriptor, _descriptor2, _descriptor3, _descriptor4;
  
    function _initDefineProp(target, property, descriptor, context) {
      if (!descriptor) return;
      Object.defineProperty(target, property, {
        enumerable: descriptor.enumerable,
        configurable: descriptor.configurable,
        writable: descriptor.writable,
        value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
      });
    }
  
    function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
      var desc = {};
      Object['ke' + 'ys'](descriptor).forEach(function (key) {
        desc[key] = descriptor[key];
      });
      desc.enumerable = !!desc.enumerable;
      desc.configurable = !!desc.configurable;
  
      if ('value' in desc || desc.initializer) {
        desc.writable = true;
      }
  
      desc = decorators.slice().reverse().reduce(function (desc, decorator) {
        return decorator(target, property, desc) || desc;
      }, desc);
  
      if (context && desc.initializer !== void 0) {
        desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
        desc.initializer = undefined;
      }
  
      if (desc.initializer === void 0) {
        Object['define' + 'Property'](target, property, desc);
        desc = null;
      }
  
      return desc;
    }
  
    let Compose = (_dec$4 = customElement('compose'), _dec$4(_class$4 = noView(_class$4 = (_class2$4 = class Compose {
  
      static inject() {
        return [DOM.Element, Container, CompositionEngine, ViewSlot, ViewResources, TaskQueue];
      }
  
      constructor(element, container, compositionEngine, viewSlot, viewResources, taskQueue) {
        _initDefineProp(this, 'model', _descriptor, this);
  
        _initDefineProp(this, 'view', _descriptor2, this);
  
        _initDefineProp(this, 'viewModel', _descriptor3, this);
  
        _initDefineProp(this, 'swapOrder', _descriptor4, this);
  
        this.element = element;
        this.container = container;
        this.compositionEngine = compositionEngine;
        this.viewSlot = viewSlot;
        this.viewResources = viewResources;
        this.taskQueue = taskQueue;
        this.currentController = null;
        this.currentViewModel = null;
        this.changes = Object.create(null);
      }
  
      created(owningView) {
        this.owningView = owningView;
      }
  
      bind(bindingContext, overrideContext) {
        this.bindingContext = bindingContext;
        this.overrideContext = overrideContext;
        this.changes.view = this.view;
        this.changes.viewModel = this.viewModel;
        this.changes.model = this.model;
        if (!this.pendingTask) {
          processChanges(this);
        }
      }
  
      unbind() {
        this.changes = Object.create(null);
        this.bindingContext = null;
        this.overrideContext = null;
        let returnToCache = true;
        let skipAnimation = true;
        this.viewSlot.removeAll(returnToCache, skipAnimation);
      }
  
      modelChanged(newValue, oldValue) {
        this.changes.model = newValue;
        requestUpdate(this);
      }
  
      viewChanged(newValue, oldValue) {
        this.changes.view = newValue;
        requestUpdate(this);
      }
  
      viewModelChanged(newValue, oldValue) {
        this.changes.viewModel = newValue;
        requestUpdate(this);
      }
    }, (_descriptor = _applyDecoratedDescriptor(_class2$4.prototype, 'model', [bindable], {
      enumerable: true,
      initializer: null
    }), _descriptor2 = _applyDecoratedDescriptor(_class2$4.prototype, 'view', [bindable], {
      enumerable: true,
      initializer: null
    }), _descriptor3 = _applyDecoratedDescriptor(_class2$4.prototype, 'viewModel', [bindable], {
      enumerable: true,
      initializer: null
    }), _descriptor4 = _applyDecoratedDescriptor(_class2$4.prototype, 'swapOrder', [bindable], {
      enumerable: true,
      initializer: null
    })), _class2$4)) || _class$4) || _class$4);
  
    function isEmpty(obj) {
      for (const key in obj) {
        return false;
      }
      return true;
    }
  
    function tryActivateViewModel$1(vm, model) {
      if (vm && typeof vm.activate === 'function') {
        return Promise.resolve(vm.activate(model));
      }
    }
  
    function createInstruction(composer, instruction) {
      return Object.assign(instruction, {
        bindingContext: composer.bindingContext,
        overrideContext: composer.overrideContext,
        owningView: composer.owningView,
        container: composer.container,
        viewSlot: composer.viewSlot,
        viewResources: composer.viewResources,
        currentController: composer.currentController,
        host: composer.element,
        swapOrder: composer.swapOrder
      });
    }
  
    function processChanges(composer) {
      const changes = composer.changes;
      composer.changes = Object.create(null);
  
      if (!('view' in changes) && !('viewModel' in changes) && 'model' in changes) {
        composer.pendingTask = tryActivateViewModel$1(composer.currentViewModel, changes.model);
        if (!composer.pendingTask) {
          return;
        }
      } else {
        let instruction = {
          view: composer.view,
          viewModel: composer.currentViewModel || composer.viewModel,
          model: composer.model
        };
  
        instruction = Object.assign(instruction, changes);
  
        instruction = createInstruction(composer, instruction);
        composer.pendingTask = composer.compositionEngine.compose(instruction).then(controller => {
          composer.currentController = controller;
          composer.currentViewModel = controller ? controller.viewModel : null;
        });
      }
  
      composer.pendingTask = composer.pendingTask.then(() => {
        completeCompositionTask(composer);
      }, reason => {
        completeCompositionTask(composer);
        throw reason;
      });
    }
  
    function completeCompositionTask(composer) {
      composer.pendingTask = null;
      if (!isEmpty(composer.changes)) {
        processChanges(composer);
      }
    }
  
    function requestUpdate(composer) {
      if (composer.pendingTask || composer.updateRequested) {
        return;
      }
      composer.updateRequested = true;
      composer.taskQueue.queueMicroTask(() => {
        composer.updateRequested = false;
        processChanges(composer);
      });
    }
  
    let IfCore = class IfCore {
      constructor(viewFactory, viewSlot) {
        this.viewFactory = viewFactory;
        this.viewSlot = viewSlot;
        this.view = null;
        this.bindingContext = null;
        this.overrideContext = null;
  
        this.showing = false;
      }
  
      bind(bindingContext, overrideContext) {
        this.bindingContext = bindingContext;
        this.overrideContext = overrideContext;
      }
  
      unbind() {
        if (this.view === null) {
          return;
        }
  
        this.view.unbind();
  
        if (!this.viewFactory.isCaching) {
          return;
        }
  
        if (this.showing) {
          this.showing = false;
          this.viewSlot.remove(this.view, true, true);
        } else {
          this.view.returnToCache();
        }
  
        this.view = null;
      }
  
      _show() {
        if (this.showing) {
          if (!this.view.isBound) {
            this.view.bind(this.bindingContext, this.overrideContext);
          }
          return;
        }
  
        if (this.view === null) {
          this.view = this.viewFactory.create();
        }
  
        if (!this.view.isBound) {
          this.view.bind(this.bindingContext, this.overrideContext);
        }
  
        this.showing = true;
        return this.viewSlot.add(this.view);
      }
  
      _hide() {
        if (!this.showing) {
          return;
        }
  
        this.showing = false;
        let removed = this.viewSlot.remove(this.view);
  
        if (removed instanceof Promise) {
          return removed.then(() => this.view.unbind());
        }
  
        this.view.unbind();
      }
    };
  
    var _dec$5, _dec2$4, _dec3$3, _class$5, _class2$5, _descriptor$1, _descriptor2$1;
  
    function _initDefineProp$1(target, property, descriptor, context) {
      if (!descriptor) return;
      Object.defineProperty(target, property, {
        enumerable: descriptor.enumerable,
        configurable: descriptor.configurable,
        writable: descriptor.writable,
        value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
      });
    }
  
    function _applyDecoratedDescriptor$1(target, property, decorators, descriptor, context) {
      var desc = {};
      Object['ke' + 'ys'](descriptor).forEach(function (key) {
        desc[key] = descriptor[key];
      });
      desc.enumerable = !!desc.enumerable;
      desc.configurable = !!desc.configurable;
  
      if ('value' in desc || desc.initializer) {
        desc.writable = true;
      }
  
      desc = decorators.slice().reverse().reduce(function (desc, decorator) {
        return decorator(target, property, desc) || desc;
      }, desc);
  
      if (context && desc.initializer !== void 0) {
        desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
        desc.initializer = undefined;
      }
  
      if (desc.initializer === void 0) {
        Object['define' + 'Property'](target, property, desc);
        desc = null;
      }
  
      return desc;
    }
  
    let If = (_dec$5 = customAttribute('if'), _dec2$4 = inject(BoundViewFactory, ViewSlot), _dec3$3 = bindable({ primaryProperty: true }), _dec$5(_class$5 = templateController(_class$5 = _dec2$4(_class$5 = (_class2$5 = class If extends IfCore {
      constructor(...args) {
        var _temp;
  
        return _temp = super(...args), _initDefineProp$1(this, 'condition', _descriptor$1, this), _initDefineProp$1(this, 'swapOrder', _descriptor2$1, this), _temp;
      }
  
      bind(bindingContext, overrideContext) {
        super.bind(bindingContext, overrideContext);
        if (this.condition) {
          this._show();
        } else {
          this._hide();
        }
      }
  
      conditionChanged(newValue) {
        this._update(newValue);
      }
  
      _update(show) {
        if (this.animating) {
          return;
        }
  
        let promise;
        if (this.elseVm) {
          promise = show ? this._swap(this.elseVm, this) : this._swap(this, this.elseVm);
        } else {
          promise = show ? this._show() : this._hide();
        }
  
        if (promise) {
          this.animating = true;
          promise.then(() => {
            this.animating = false;
            if (this.condition !== this.showing) {
              this._update(this.condition);
            }
          });
        }
      }
  
      _swap(remove, add) {
        switch (this.swapOrder) {
          case 'before':
            return Promise.resolve(add._show()).then(() => remove._hide());
          case 'with':
            return Promise.all([remove._hide(), add._show()]);
          default:
            let promise = remove._hide();
            return promise ? promise.then(() => add._show()) : add._show();
        }
      }
    }, (_descriptor$1 = _applyDecoratedDescriptor$1(_class2$5.prototype, 'condition', [_dec3$3], {
      enumerable: true,
      initializer: null
    }), _descriptor2$1 = _applyDecoratedDescriptor$1(_class2$5.prototype, 'swapOrder', [bindable], {
      enumerable: true,
      initializer: null
    })), _class2$5)) || _class$5) || _class$5) || _class$5);
  
    var _dec$6, _dec2$5, _class$6;
  
    let Else = (_dec$6 = customAttribute('else'), _dec2$5 = inject(BoundViewFactory, ViewSlot), _dec$6(_class$6 = templateController(_class$6 = _dec2$5(_class$6 = class Else extends IfCore {
      constructor(viewFactory, viewSlot) {
        super(viewFactory, viewSlot);
        this._registerInIf();
      }
  
      bind(bindingContext, overrideContext) {
        super.bind(bindingContext, overrideContext);
  
        if (this.ifVm.condition) {
          this._hide();
        } else {
          this._show();
        }
      }
  
      _registerInIf() {
        let previous = this.viewSlot.anchor.previousSibling;
        while (previous && !previous.au) {
          previous = previous.previousSibling;
        }
        if (!previous || !previous.au.if) {
          throw new Error("Can't find matching If for Else custom attribute.");
        }
        this.ifVm = previous.au.if.viewModel;
        this.ifVm.elseVm = this;
      }
    }) || _class$6) || _class$6) || _class$6);
  
    var _dec$7, _dec2$6, _class$7;
  
    let With = (_dec$7 = customAttribute('with'), _dec2$6 = inject(BoundViewFactory, ViewSlot), _dec$7(_class$7 = templateController(_class$7 = _dec2$6(_class$7 = class With {
      constructor(viewFactory, viewSlot) {
        this.viewFactory = viewFactory;
        this.viewSlot = viewSlot;
        this.parentOverrideContext = null;
        this.view = null;
      }
  
      bind(bindingContext, overrideContext) {
        this.parentOverrideContext = overrideContext;
        this.valueChanged(this.value);
      }
  
      valueChanged(newValue) {
        let overrideContext = createOverrideContext(newValue, this.parentOverrideContext);
        if (!this.view) {
          this.view = this.viewFactory.create();
          this.view.bind(newValue, overrideContext);
          this.viewSlot.add(this.view);
        } else {
          this.view.bind(newValue, overrideContext);
        }
      }
  
      unbind() {
        this.parentOverrideContext = null;
  
        if (this.view) {
          this.view.unbind();
        }
      }
    }) || _class$7) || _class$7) || _class$7);
  
    let NullRepeatStrategy = class NullRepeatStrategy {
      instanceChanged(repeat, items) {
        repeat.removeAllViews(true);
      }
  
      getCollectionObserver(observerLocator, items) {}
    };
  
    const oneTime = bindingMode.oneTime;
  
    function updateOverrideContexts(views, startIndex) {
      let length = views.length;
  
      if (startIndex > 0) {
        startIndex = startIndex - 1;
      }
  
      for (; startIndex < length; ++startIndex) {
        updateOverrideContext(views[startIndex].overrideContext, startIndex, length);
      }
    }
  
    function createFullOverrideContext(repeat, data, index, length, key) {
      let bindingContext = {};
      let overrideContext = createOverrideContext(bindingContext, repeat.scope.overrideContext);
  
      if (typeof key !== 'undefined') {
        bindingContext[repeat.key] = key;
        bindingContext[repeat.value] = data;
      } else {
        bindingContext[repeat.local] = data;
      }
      updateOverrideContext(overrideContext, index, length);
      return overrideContext;
    }
  
    function updateOverrideContext(overrideContext, index, length) {
      let first = index === 0;
      let last = index === length - 1;
      let even = index % 2 === 0;
  
      overrideContext.$index = index;
      overrideContext.$first = first;
      overrideContext.$last = last;
      overrideContext.$middle = !(first || last);
      overrideContext.$odd = !even;
      overrideContext.$even = even;
    }
  
    function getItemsSourceExpression(instruction, attrName) {
      return instruction.behaviorInstructions.filter(bi => bi.originalAttrName === attrName)[0].attributes.items.sourceExpression;
    }
  
    function unwrapExpression(expression) {
      let unwrapped = false;
      while (expression instanceof BindingBehavior) {
        expression = expression.expression;
      }
      while (expression instanceof ValueConverter) {
        expression = expression.expression;
        unwrapped = true;
      }
      return unwrapped ? expression : null;
    }
  
    function isOneTime(expression) {
      while (expression instanceof BindingBehavior) {
        if (expression.name === 'oneTime') {
          return true;
        }
        expression = expression.expression;
      }
      return false;
    }
  
    function updateOneTimeBinding(binding) {
      if (binding.call && binding.mode === oneTime) {
        binding.call(sourceContext);
      } else if (binding.updateOneTimeBindings) {
        binding.updateOneTimeBindings();
      }
    }
  
    function indexOf(array, item, matcher, startIndex) {
      if (!matcher) {
        return array.indexOf(item);
      }
      const length = array.length;
      for (let index = startIndex || 0; index < length; index++) {
        if (matcher(array[index], item)) {
          return index;
        }
      }
      return -1;
    }
  
    let ArrayRepeatStrategy = class ArrayRepeatStrategy {
      getCollectionObserver(observerLocator, items) {
        return observerLocator.getArrayObserver(items);
      }
  
      instanceChanged(repeat, items) {
        const itemsLength = items.length;
  
        if (!items || itemsLength === 0) {
          repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);
          return;
        }
  
        const children = repeat.views();
        const viewsLength = children.length;
  
        if (viewsLength === 0) {
          this._standardProcessInstanceChanged(repeat, items);
          return;
        }
  
        if (repeat.viewsRequireLifecycle) {
          const childrenSnapshot = children.slice(0);
          const itemNameInBindingContext = repeat.local;
          const matcher = repeat.matcher();
  
          let itemsPreviouslyInViews = [];
          const viewsToRemove = [];
  
          for (let index = 0; index < viewsLength; index++) {
            const view = childrenSnapshot[index];
            const oldItem = view.bindingContext[itemNameInBindingContext];
  
            if (indexOf(items, oldItem, matcher) === -1) {
              viewsToRemove.push(view);
            } else {
              itemsPreviouslyInViews.push(oldItem);
            }
          }
  
          let updateViews;
          let removePromise;
  
          if (itemsPreviouslyInViews.length > 0) {
            removePromise = repeat.removeViews(viewsToRemove, true, !repeat.viewsRequireLifecycle);
            updateViews = () => {
              for (let index = 0; index < itemsLength; index++) {
                const item = items[index];
                const indexOfView = indexOf(itemsPreviouslyInViews, item, matcher, index);
                let view;
  
                if (indexOfView === -1) {
                  const overrideContext = createFullOverrideContext(repeat, items[index], index, itemsLength);
                  repeat.insertView(index, overrideContext.bindingContext, overrideContext);
  
                  itemsPreviouslyInViews.splice(index, 0, undefined);
                } else if (indexOfView === index) {
                  view = children[indexOfView];
                  itemsPreviouslyInViews[indexOfView] = undefined;
                } else {
                  view = children[indexOfView];
                  repeat.moveView(indexOfView, index);
                  itemsPreviouslyInViews.splice(indexOfView, 1);
                  itemsPreviouslyInViews.splice(index, 0, undefined);
                }
  
                if (view) {
                  updateOverrideContext(view.overrideContext, index, itemsLength);
                }
              }
  
              this._inPlaceProcessItems(repeat, items);
            };
          } else {
            removePromise = repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);
            updateViews = () => this._standardProcessInstanceChanged(repeat, items);
          }
  
          if (removePromise instanceof Promise) {
            removePromise.then(updateViews);
          } else {
            updateViews();
          }
        } else {
          this._inPlaceProcessItems(repeat, items);
        }
      }
  
      _standardProcessInstanceChanged(repeat, items) {
        for (let i = 0, ii = items.length; i < ii; i++) {
          let overrideContext = createFullOverrideContext(repeat, items[i], i, ii);
          repeat.addView(overrideContext.bindingContext, overrideContext);
        }
      }
  
      _inPlaceProcessItems(repeat, items) {
        let itemsLength = items.length;
        let viewsLength = repeat.viewCount();
  
        while (viewsLength > itemsLength) {
          viewsLength--;
          repeat.removeView(viewsLength, true, !repeat.viewsRequireLifecycle);
        }
  
        let local = repeat.local;
  
        for (let i = 0; i < viewsLength; i++) {
          let view = repeat.view(i);
          let last = i === itemsLength - 1;
          let middle = i !== 0 && !last;
  
          if (view.bindingContext[local] === items[i] && view.overrideContext.$middle === middle && view.overrideContext.$last === last) {
            continue;
          }
  
          view.bindingContext[local] = items[i];
          view.overrideContext.$middle = middle;
          view.overrideContext.$last = last;
          repeat.updateBindings(view);
        }
  
        for (let i = viewsLength; i < itemsLength; i++) {
          let overrideContext = createFullOverrideContext(repeat, items[i], i, itemsLength);
          repeat.addView(overrideContext.bindingContext, overrideContext);
        }
      }
  
      instanceMutated(repeat, array, splices) {
        if (repeat.__queuedSplices) {
          for (let i = 0, ii = splices.length; i < ii; ++i) {
            let { index, removed, addedCount } = splices[i];
            mergeSplice(repeat.__queuedSplices, index, removed, addedCount);
          }
  
          repeat.__array = array.slice(0);
          return;
        }
  
        let maybePromise = this._runSplices(repeat, array.slice(0), splices);
        if (maybePromise instanceof Promise) {
          let queuedSplices = repeat.__queuedSplices = [];
  
          let runQueuedSplices = () => {
            if (!queuedSplices.length) {
              repeat.__queuedSplices = undefined;
              repeat.__array = undefined;
              return;
            }
  
            let nextPromise = this._runSplices(repeat, repeat.__array, queuedSplices) || Promise.resolve();
            queuedSplices = repeat.__queuedSplices = [];
            nextPromise.then(runQueuedSplices);
          };
  
          maybePromise.then(runQueuedSplices);
        }
      }
  
      _runSplices(repeat, array, splices) {
        let removeDelta = 0;
        let rmPromises = [];
  
        for (let i = 0, ii = splices.length; i < ii; ++i) {
          let splice = splices[i];
          let removed = splice.removed;
  
          for (let j = 0, jj = removed.length; j < jj; ++j) {
            let viewOrPromise = repeat.removeView(splice.index + removeDelta + rmPromises.length, true);
            if (viewOrPromise instanceof Promise) {
              rmPromises.push(viewOrPromise);
            }
          }
          removeDelta -= splice.addedCount;
        }
  
        if (rmPromises.length > 0) {
          return Promise.all(rmPromises).then(() => {
            let spliceIndexLow = this._handleAddedSplices(repeat, array, splices);
            updateOverrideContexts(repeat.views(), spliceIndexLow);
          });
        }
  
        let spliceIndexLow = this._handleAddedSplices(repeat, array, splices);
        updateOverrideContexts(repeat.views(), spliceIndexLow);
  
        return undefined;
      }
  
      _handleAddedSplices(repeat, array, splices) {
        let spliceIndex;
        let spliceIndexLow;
        let arrayLength = array.length;
        for (let i = 0, ii = splices.length; i < ii; ++i) {
          let splice = splices[i];
          let addIndex = spliceIndex = splice.index;
          let end = splice.index + splice.addedCount;
  
          if (typeof spliceIndexLow === 'undefined' || spliceIndexLow === null || spliceIndexLow > splice.index) {
            spliceIndexLow = spliceIndex;
          }
  
          for (; addIndex < end; ++addIndex) {
            let overrideContext = createFullOverrideContext(repeat, array[addIndex], addIndex, arrayLength);
            repeat.insertView(addIndex, overrideContext.bindingContext, overrideContext);
          }
        }
  
        return spliceIndexLow;
      }
    };
  
    let MapRepeatStrategy = class MapRepeatStrategy {
      getCollectionObserver(observerLocator, items) {
        return observerLocator.getMapObserver(items);
      }
  
      instanceChanged(repeat, items) {
        let removePromise = repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);
        if (removePromise instanceof Promise) {
          removePromise.then(() => this._standardProcessItems(repeat, items));
          return;
        }
        this._standardProcessItems(repeat, items);
      }
  
      _standardProcessItems(repeat, items) {
        let index = 0;
        let overrideContext;
  
        items.forEach((value, key) => {
          overrideContext = createFullOverrideContext(repeat, value, index, items.size, key);
          repeat.addView(overrideContext.bindingContext, overrideContext);
          ++index;
        });
      }
  
      instanceMutated(repeat, map, records) {
        let key;
        let i;
        let ii;
        let overrideContext;
        let removeIndex;
        let addIndex;
        let record;
        let rmPromises = [];
        let viewOrPromise;
  
        for (i = 0, ii = records.length; i < ii; ++i) {
          record = records[i];
          key = record.key;
          switch (record.type) {
            case 'update':
              removeIndex = this._getViewIndexByKey(repeat, key);
              viewOrPromise = repeat.removeView(removeIndex, true, !repeat.viewsRequireLifecycle);
              if (viewOrPromise instanceof Promise) {
                rmPromises.push(viewOrPromise);
              }
              overrideContext = createFullOverrideContext(repeat, map.get(key), removeIndex, map.size, key);
              repeat.insertView(removeIndex, overrideContext.bindingContext, overrideContext);
              break;
            case 'add':
              addIndex = repeat.viewCount() <= map.size - 1 ? repeat.viewCount() : map.size - 1;
              overrideContext = createFullOverrideContext(repeat, map.get(key), addIndex, map.size, key);
              repeat.insertView(map.size - 1, overrideContext.bindingContext, overrideContext);
              break;
            case 'delete':
              if (record.oldValue === undefined) {
                return;
              }
              removeIndex = this._getViewIndexByKey(repeat, key);
              viewOrPromise = repeat.removeView(removeIndex, true, !repeat.viewsRequireLifecycle);
              if (viewOrPromise instanceof Promise) {
                rmPromises.push(viewOrPromise);
              }
              break;
            case 'clear':
              repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);
              break;
            default:
              continue;
          }
        }
  
        if (rmPromises.length > 0) {
          Promise.all(rmPromises).then(() => {
            updateOverrideContexts(repeat.views(), 0);
          });
        } else {
          updateOverrideContexts(repeat.views(), 0);
        }
      }
  
      _getViewIndexByKey(repeat, key) {
        let i;
        let ii;
        let child;
  
        for (i = 0, ii = repeat.viewCount(); i < ii; ++i) {
          child = repeat.view(i);
          if (child.bindingContext[repeat.key] === key) {
            return i;
          }
        }
  
        return undefined;
      }
    };
  
    let SetRepeatStrategy = class SetRepeatStrategy {
      getCollectionObserver(observerLocator, items) {
        return observerLocator.getSetObserver(items);
      }
  
      instanceChanged(repeat, items) {
        let removePromise = repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);
        if (removePromise instanceof Promise) {
          removePromise.then(() => this._standardProcessItems(repeat, items));
          return;
        }
        this._standardProcessItems(repeat, items);
      }
  
      _standardProcessItems(repeat, items) {
        let index = 0;
        let overrideContext;
  
        items.forEach(value => {
          overrideContext = createFullOverrideContext(repeat, value, index, items.size);
          repeat.addView(overrideContext.bindingContext, overrideContext);
          ++index;
        });
      }
  
      instanceMutated(repeat, set, records) {
        let value;
        let i;
        let ii;
        let overrideContext;
        let removeIndex;
        let record;
        let rmPromises = [];
        let viewOrPromise;
  
        for (i = 0, ii = records.length; i < ii; ++i) {
          record = records[i];
          value = record.value;
          switch (record.type) {
            case 'add':
              let size = Math.max(set.size - 1, 0);
              overrideContext = createFullOverrideContext(repeat, value, size, set.size);
              repeat.insertView(size, overrideContext.bindingContext, overrideContext);
              break;
            case 'delete':
              removeIndex = this._getViewIndexByValue(repeat, value);
              viewOrPromise = repeat.removeView(removeIndex, true, !repeat.viewsRequireLifecycle);
              if (viewOrPromise instanceof Promise) {
                rmPromises.push(viewOrPromise);
              }
              break;
            case 'clear':
              repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);
              break;
            default:
              continue;
          }
        }
  
        if (rmPromises.length > 0) {
          Promise.all(rmPromises).then(() => {
            updateOverrideContexts(repeat.views(), 0);
          });
        } else {
          updateOverrideContexts(repeat.views(), 0);
        }
      }
  
      _getViewIndexByValue(repeat, value) {
        let i;
        let ii;
        let child;
  
        for (i = 0, ii = repeat.viewCount(); i < ii; ++i) {
          child = repeat.view(i);
          if (child.bindingContext[repeat.local] === value) {
            return i;
          }
        }
  
        return undefined;
      }
    };
  
    let NumberRepeatStrategy = class NumberRepeatStrategy {
      getCollectionObserver() {
        return null;
      }
  
      instanceChanged(repeat, value) {
        let removePromise = repeat.removeAllViews(true, !repeat.viewsRequireLifecycle);
        if (removePromise instanceof Promise) {
          removePromise.then(() => this._standardProcessItems(repeat, value));
          return;
        }
        this._standardProcessItems(repeat, value);
      }
  
      _standardProcessItems(repeat, value) {
        let childrenLength = repeat.viewCount();
        let i;
        let ii;
        let overrideContext;
        let viewsToRemove;
  
        value = Math.floor(value);
        viewsToRemove = childrenLength - value;
  
        if (viewsToRemove > 0) {
          if (viewsToRemove > childrenLength) {
            viewsToRemove = childrenLength;
          }
  
          for (i = 0, ii = viewsToRemove; i < ii; ++i) {
            repeat.removeView(childrenLength - (i + 1), true, !repeat.viewsRequireLifecycle);
          }
  
          return;
        }
  
        for (i = childrenLength, ii = value; i < ii; ++i) {
          overrideContext = createFullOverrideContext(repeat, i, i, ii);
          repeat.addView(overrideContext.bindingContext, overrideContext);
        }
  
        updateOverrideContexts(repeat.views(), 0);
      }
    };
  
    let RepeatStrategyLocator = class RepeatStrategyLocator {
      constructor() {
        this.matchers = [];
        this.strategies = [];
  
        this.addStrategy(items => items === null || items === undefined, new NullRepeatStrategy());
        this.addStrategy(items => items instanceof Array, new ArrayRepeatStrategy());
        this.addStrategy(items => items instanceof Map, new MapRepeatStrategy());
        this.addStrategy(items => items instanceof Set, new SetRepeatStrategy());
        this.addStrategy(items => typeof items === 'number', new NumberRepeatStrategy());
      }
  
      addStrategy(matcher, strategy) {
        this.matchers.push(matcher);
        this.strategies.push(strategy);
      }
  
      getStrategy(items) {
        let matchers = this.matchers;
  
        for (let i = 0, ii = matchers.length; i < ii; ++i) {
          if (matchers[i](items)) {
            return this.strategies[i];
          }
        }
  
        return null;
      }
    };
  
    const lifecycleOptionalBehaviors = ['focus', 'if', 'else', 'repeat', 'show', 'hide', 'with'];
  
    function behaviorRequiresLifecycle(instruction) {
      let t = instruction.type;
      let name = t.elementName !== null ? t.elementName : t.attributeName;
      return lifecycleOptionalBehaviors.indexOf(name) === -1 && (t.handlesAttached || t.handlesBind || t.handlesCreated || t.handlesDetached || t.handlesUnbind) || t.viewFactory && viewsRequireLifecycle(t.viewFactory) || instruction.viewFactory && viewsRequireLifecycle(instruction.viewFactory);
    }
  
    function targetRequiresLifecycle(instruction) {
      let behaviors = instruction.behaviorInstructions;
      if (behaviors) {
        let i = behaviors.length;
        while (i--) {
          if (behaviorRequiresLifecycle(behaviors[i])) {
            return true;
          }
        }
      }
  
      return instruction.viewFactory && viewsRequireLifecycle(instruction.viewFactory);
    }
  
    function viewsRequireLifecycle(viewFactory) {
      if ('_viewsRequireLifecycle' in viewFactory) {
        return viewFactory._viewsRequireLifecycle;
      }
  
      viewFactory._viewsRequireLifecycle = false;
  
      if (viewFactory.viewFactory) {
        viewFactory._viewsRequireLifecycle = viewsRequireLifecycle(viewFactory.viewFactory);
        return viewFactory._viewsRequireLifecycle;
      }
  
      if (viewFactory.template.querySelector('.au-animate')) {
        viewFactory._viewsRequireLifecycle = true;
        return true;
      }
  
      for (let id in viewFactory.instructions) {
        if (targetRequiresLifecycle(viewFactory.instructions[id])) {
          viewFactory._viewsRequireLifecycle = true;
          return true;
        }
      }
  
      viewFactory._viewsRequireLifecycle = false;
      return false;
    }
  
    let AbstractRepeater = class AbstractRepeater {
      constructor(options) {
        Object.assign(this, {
          local: 'items',
          viewsRequireLifecycle: true
        }, options);
      }
  
      viewCount() {
        throw new Error('subclass must implement `viewCount`');
      }
  
      views() {
        throw new Error('subclass must implement `views`');
      }
  
      view(index) {
        throw new Error('subclass must implement `view`');
      }
  
      matcher() {
        throw new Error('subclass must implement `matcher`');
      }
  
      addView(bindingContext, overrideContext) {
        throw new Error('subclass must implement `addView`');
      }
  
      insertView(index, bindingContext, overrideContext) {
        throw new Error('subclass must implement `insertView`');
      }
  
      moveView(sourceIndex, targetIndex) {
        throw new Error('subclass must implement `moveView`');
      }
  
      removeAllViews(returnToCache, skipAnimation) {
        throw new Error('subclass must implement `removeAllViews`');
      }
  
      removeViews(viewsToRemove, returnToCache, skipAnimation) {
        throw new Error('subclass must implement `removeView`');
      }
  
      removeView(index, returnToCache, skipAnimation) {
        throw new Error('subclass must implement `removeView`');
      }
  
      updateBindings(view) {
        throw new Error('subclass must implement `updateBindings`');
      }
    };
  
    var _dec$8, _dec2$7, _class$8, _class2$6, _descriptor$2, _descriptor2$2, _descriptor3$1, _descriptor4$1;
  
    function _initDefineProp$2(target, property, descriptor, context) {
      if (!descriptor) return;
      Object.defineProperty(target, property, {
        enumerable: descriptor.enumerable,
        configurable: descriptor.configurable,
        writable: descriptor.writable,
        value: descriptor.initializer ? descriptor.initializer.call(context) : void 0
      });
    }
  
    function _applyDecoratedDescriptor$2(target, property, decorators, descriptor, context) {
      var desc = {};
      Object['ke' + 'ys'](descriptor).forEach(function (key) {
        desc[key] = descriptor[key];
      });
      desc.enumerable = !!desc.enumerable;
      desc.configurable = !!desc.configurable;
  
      if ('value' in desc || desc.initializer) {
        desc.writable = true;
      }
  
      desc = decorators.slice().reverse().reduce(function (desc, decorator) {
        return decorator(target, property, desc) || desc;
      }, desc);
  
      if (context && desc.initializer !== void 0) {
        desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
        desc.initializer = undefined;
      }
  
      if (desc.initializer === void 0) {
        Object['define' + 'Property'](target, property, desc);
        desc = null;
      }
  
      return desc;
    }
  
    let Repeat = (_dec$8 = customAttribute('repeat'), _dec2$7 = inject(BoundViewFactory, TargetInstruction, ViewSlot, ViewResources, ObserverLocator, RepeatStrategyLocator), _dec$8(_class$8 = templateController(_class$8 = _dec2$7(_class$8 = (_class2$6 = class Repeat extends AbstractRepeater {
      constructor(viewFactory, instruction, viewSlot, viewResources, observerLocator, strategyLocator) {
        super({
          local: 'item',
          viewsRequireLifecycle: viewsRequireLifecycle(viewFactory)
        });
  
        _initDefineProp$2(this, 'items', _descriptor$2, this);
  
        _initDefineProp$2(this, 'local', _descriptor2$2, this);
  
        _initDefineProp$2(this, 'key', _descriptor3$1, this);
  
        _initDefineProp$2(this, 'value', _descriptor4$1, this);
  
        this.viewFactory = viewFactory;
        this.instruction = instruction;
        this.viewSlot = viewSlot;
        this.lookupFunctions = viewResources.lookupFunctions;
        this.observerLocator = observerLocator;
        this.key = 'key';
        this.value = 'value';
        this.strategyLocator = strategyLocator;
        this.ignoreMutation = false;
        this.sourceExpression = getItemsSourceExpression(this.instruction, 'repeat.for');
        this.isOneTime = isOneTime(this.sourceExpression);
        this.viewsRequireLifecycle = viewsRequireLifecycle(viewFactory);
      }
  
      call(context, changes) {
        this[context](this.items, changes);
      }
  
      bind(bindingContext, overrideContext) {
        this.scope = { bindingContext, overrideContext };
        this.matcherBinding = this._captureAndRemoveMatcherBinding();
        this.itemsChanged();
      }
  
      unbind() {
        this.scope = null;
        this.items = null;
        this.matcherBinding = null;
        this.viewSlot.removeAll(true, true);
        this._unsubscribeCollection();
      }
  
      _unsubscribeCollection() {
        if (this.collectionObserver) {
          this.collectionObserver.unsubscribe(this.callContext, this);
          this.collectionObserver = null;
          this.callContext = null;
        }
      }
  
      itemsChanged() {
        this._unsubscribeCollection();
  
        if (!this.scope) {
          return;
        }
  
        let items = this.items;
        this.strategy = this.strategyLocator.getStrategy(items);
        if (!this.strategy) {
          throw new Error(`Value for '${this.sourceExpression}' is non-repeatable`);
        }
  
        if (!this.isOneTime && !this._observeInnerCollection()) {
          this._observeCollection();
        }
        this.ignoreMutation = true;
        this.strategy.instanceChanged(this, items);
        this.observerLocator.taskQueue.queueMicroTask(() => {
          this.ignoreMutation = false;
        });
      }
  
      _getInnerCollection() {
        let expression = unwrapExpression(this.sourceExpression);
        if (!expression) {
          return null;
        }
        return expression.evaluate(this.scope, null);
      }
  
      handleCollectionMutated(collection, changes) {
        if (!this.collectionObserver) {
          return;
        }
        if (this.ignoreMutation) {
          return;
        }
        this.strategy.instanceMutated(this, collection, changes);
      }
  
      handleInnerCollectionMutated(collection, changes) {
        if (!this.collectionObserver) {
          return;
        }
  
        if (this.ignoreMutation) {
          return;
        }
        this.ignoreMutation = true;
        let newItems = this.sourceExpression.evaluate(this.scope, this.lookupFunctions);
        this.observerLocator.taskQueue.queueMicroTask(() => this.ignoreMutation = false);
  
        if (newItems === this.items) {
          this.itemsChanged();
        } else {
          this.items = newItems;
        }
      }
  
      _observeInnerCollection() {
        let items = this._getInnerCollection();
        let strategy = this.strategyLocator.getStrategy(items);
        if (!strategy) {
          return false;
        }
        this.collectionObserver = strategy.getCollectionObserver(this.observerLocator, items);
        if (!this.collectionObserver) {
          return false;
        }
        this.callContext = 'handleInnerCollectionMutated';
        this.collectionObserver.subscribe(this.callContext, this);
        return true;
      }
  
      _observeCollection() {
        let items = this.items;
        this.collectionObserver = this.strategy.getCollectionObserver(this.observerLocator, items);
        if (this.collectionObserver) {
          this.callContext = 'handleCollectionMutated';
          this.collectionObserver.subscribe(this.callContext, this);
        }
      }
  
      _captureAndRemoveMatcherBinding() {
        if (this.viewFactory.viewFactory) {
          const instructions = this.viewFactory.viewFactory.instructions;
          const instructionIds = Object.keys(instructions);
          for (let i = 0; i < instructionIds.length; i++) {
            const expressions = instructions[instructionIds[i]].expressions;
            if (expressions) {
              for (let ii = 0; i < expressions.length; i++) {
                if (expressions[ii].targetProperty === 'matcher') {
                  const matcherBinding = expressions[ii];
                  expressions.splice(ii, 1);
                  return matcherBinding;
                }
              }
            }
          }
        }
  
        return undefined;
      }
  
      viewCount() {
        return this.viewSlot.children.length;
      }
      views() {
        return this.viewSlot.children;
      }
      view(index) {
        return this.viewSlot.children[index];
      }
      matcher() {
        return this.matcherBinding ? this.matcherBinding.sourceExpression.evaluate(this.scope, this.matcherBinding.lookupFunctions) : null;
      }
  
      addView(bindingContext, overrideContext) {
        let view = this.viewFactory.create();
        view.bind(bindingContext, overrideContext);
        this.viewSlot.add(view);
      }
  
      insertView(index, bindingContext, overrideContext) {
        let view = this.viewFactory.create();
        view.bind(bindingContext, overrideContext);
        this.viewSlot.insert(index, view);
      }
  
      moveView(sourceIndex, targetIndex) {
        this.viewSlot.move(sourceIndex, targetIndex);
      }
  
      removeAllViews(returnToCache, skipAnimation) {
        return this.viewSlot.removeAll(returnToCache, skipAnimation);
      }
  
      removeViews(viewsToRemove, returnToCache, skipAnimation) {
        return this.viewSlot.removeMany(viewsToRemove, returnToCache, skipAnimation);
      }
  
      removeView(index, returnToCache, skipAnimation) {
        return this.viewSlot.removeAt(index, returnToCache, skipAnimation);
      }
  
      updateBindings(view) {
        let j = view.bindings.length;
        while (j--) {
          updateOneTimeBinding(view.bindings[j]);
        }
        j = view.controllers.length;
        while (j--) {
          let k = view.controllers[j].boundProperties.length;
          while (k--) {
            let binding = view.controllers[j].boundProperties[k].binding;
            updateOneTimeBinding(binding);
          }
        }
      }
    }, (_descriptor$2 = _applyDecoratedDescriptor$2(_class2$6.prototype, 'items', [bindable], {
      enumerable: true,
      initializer: null
    }), _descriptor2$2 = _applyDecoratedDescriptor$2(_class2$6.prototype, 'local', [bindable], {
      enumerable: true,
      initializer: null
    }), _descriptor3$1 = _applyDecoratedDescriptor$2(_class2$6.prototype, 'key', [bindable], {
      enumerable: true,
      initializer: null
    }), _descriptor4$1 = _applyDecoratedDescriptor$2(_class2$6.prototype, 'value', [bindable], {
      enumerable: true,
      initializer: null
    })), _class2$6)) || _class$8) || _class$8) || _class$8);
  
    const aureliaHideClassName = 'aurelia-hide';
  
    const aureliaHideClass = `.${aureliaHideClassName} { display:none !important; }`;
  
    function injectAureliaHideStyleAtHead() {
      DOM.injectStyles(aureliaHideClass);
    }
  
    function injectAureliaHideStyleAtBoundary(domBoundary) {
      if (FEATURE.shadowDOM && domBoundary && !domBoundary.hasAureliaHideStyle) {
        domBoundary.hasAureliaHideStyle = true;
        DOM.injectStyles(aureliaHideClass, domBoundary);
      }
    }
  
    var _dec$9, _class$9;
  
    let Show = (_dec$9 = customAttribute('show'), _dec$9(_class$9 = class Show {
  
      static inject() {
        return [DOM.Element, Animator, Optional.of(DOM.boundary, true)];
      }
  
      constructor(element, animator, domBoundary) {
        this.element = element;
        this.animator = animator;
        this.domBoundary = domBoundary;
      }
  
      created() {
        injectAureliaHideStyleAtBoundary(this.domBoundary);
      }
  
      valueChanged(newValue) {
        if (newValue) {
          this.animator.removeClass(this.element, aureliaHideClassName);
        } else {
          this.animator.addClass(this.element, aureliaHideClassName);
        }
      }
  
      bind(bindingContext) {
        this.valueChanged(this.value);
      }
    }) || _class$9);
  
    var _dec$a, _class$a;
  
    let Hide = (_dec$a = customAttribute('hide'), _dec$a(_class$a = class Hide {
  
      static inject() {
        return [DOM.Element, Animator, Optional.of(DOM.boundary, true)];
      }
  
      constructor(element, animator, domBoundary) {
        this.element = element;
        this.animator = animator;
        this.domBoundary = domBoundary;
      }
  
      created() {
        injectAureliaHideStyleAtBoundary(this.domBoundary);
      }
  
      valueChanged(newValue) {
        if (newValue) {
          this.animator.addClass(this.element, aureliaHideClassName);
        } else {
          this.animator.removeClass(this.element, aureliaHideClassName);
        }
      }
  
      bind(bindingContext) {
        this.valueChanged(this.value);
      }
    }) || _class$a);
  
    const SCRIPT_REGEX = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
  
    let HTMLSanitizer = class HTMLSanitizer {
      sanitize(input) {
        return input.replace(SCRIPT_REGEX, '');
      }
    };
  
    var _dec$b, _dec2$8, _class$b;
  
    let SanitizeHTMLValueConverter = (_dec$b = valueConverter('sanitizeHTML'), _dec2$8 = inject(HTMLSanitizer), _dec$b(_class$b = _dec2$8(_class$b = class SanitizeHTMLValueConverter {
      constructor(sanitizer) {
        this.sanitizer = sanitizer;
      }
  
      toView(untrustedMarkup) {
        if (untrustedMarkup === null || untrustedMarkup === undefined) {
          return null;
        }
  
        return this.sanitizer.sanitize(untrustedMarkup);
      }
    }) || _class$b) || _class$b);
  
    var _dec$c, _dec2$9, _class$c;
  
    let Replaceable = (_dec$c = customAttribute('replaceable'), _dec2$9 = inject(BoundViewFactory, ViewSlot), _dec$c(_class$c = templateController(_class$c = _dec2$9(_class$c = class Replaceable {
      constructor(viewFactory, viewSlot) {
        this.viewFactory = viewFactory;
        this.viewSlot = viewSlot;
        this.view = null;
      }
  
      bind(bindingContext, overrideContext) {
        if (this.view === null) {
          this.view = this.viewFactory.create();
          this.viewSlot.add(this.view);
        }
  
        this.view.bind(bindingContext, overrideContext);
      }
  
      unbind() {
        this.view.unbind();
      }
    }) || _class$c) || _class$c) || _class$c);
  
    var _dec$d, _class$d;
  
    let Focus = (_dec$d = customAttribute('focus', bindingMode.twoWay), _dec$d(_class$d = class Focus {
  
      static inject() {
        return [DOM.Element, TaskQueue];
      }
  
      constructor(element, taskQueue) {
        this.element = element;
        this.taskQueue = taskQueue;
        this.isAttached = false;
        this.needsApply = false;
      }
  
      valueChanged(newValue) {
        if (this.isAttached) {
          this._apply();
        } else {
          this.needsApply = true;
        }
      }
  
      _apply() {
        if (this.value) {
          this.taskQueue.queueMicroTask(() => {
            if (this.value) {
              this.element.focus();
            }
          });
        } else {
          this.element.blur();
        }
      }
  
      attached() {
        this.isAttached = true;
        if (this.needsApply) {
          this.needsApply = false;
          this._apply();
        }
        this.element.addEventListener('focus', this);
        this.element.addEventListener('blur', this);
      }
  
      detached() {
        this.isAttached = false;
        this.element.removeEventListener('focus', this);
        this.element.removeEventListener('blur', this);
      }
  
      handleEvent(e) {
        if (e.type === 'focus') {
          this.value = true;
        } else if (DOM.activeElement !== this.element) {
          this.value = false;
        }
      }
    }) || _class$d);
  
    let cssUrlMatcher = /url\((?!['"]data)([^)]+)\)/gi;
  
    function fixupCSSUrls(address, css) {
      if (typeof css !== 'string') {
        throw new Error(`Failed loading required CSS file: ${address}`);
      }
      return css.replace(cssUrlMatcher, (match, p1) => {
        let quote = p1.charAt(0);
        if (quote === '\'' || quote === '"') {
          p1 = p1.substr(1, p1.length - 2);
        }
        return 'url(\'' + relativeToFile(p1, address) + '\')';
      });
    }
  
    let CSSResource = class CSSResource {
      constructor(address) {
        this.address = address;
        this._scoped = null;
        this._global = false;
        this._alreadyGloballyInjected = false;
      }
  
      initialize(container, target) {
        this._scoped = new target(this);
      }
  
      register(registry, name) {
        if (name === 'scoped') {
          registry.registerViewEngineHooks(this._scoped);
        } else {
          this._global = true;
        }
      }
  
      load(container) {
        return container.get(Loader).loadText(this.address).catch(err => null).then(text => {
          text = fixupCSSUrls(this.address, text);
          this._scoped.css = text;
          if (this._global) {
            this._alreadyGloballyInjected = true;
            DOM.injectStyles(text);
          }
        });
      }
    };
    let CSSViewEngineHooks = class CSSViewEngineHooks {
      constructor(owner) {
        this.owner = owner;
        this.css = null;
      }
  
      beforeCompile(content, resources, instruction) {
        if (instruction.targetShadowDOM) {
          DOM.injectStyles(this.css, content, true);
        } else if (FEATURE.scopedCSS) {
          let styleNode = DOM.injectStyles(this.css, content, true);
          styleNode.setAttribute('scoped', 'scoped');
        } else if (this._global && !this.owner._alreadyGloballyInjected) {
          DOM.injectStyles(this.css);
          this.owner._alreadyGloballyInjected = true;
        }
      }
    };
  
  
    function _createCSSResource(address) {
      var _dec, _class;
  
      let ViewCSS = (_dec = resource(new CSSResource(address)), _dec(_class = class ViewCSS extends CSSViewEngineHooks {}) || _class);
  
      return ViewCSS;
    }
  
    var _dec$e, _class$e;
  
    let AttrBindingBehavior = (_dec$e = bindingBehavior('attr'), _dec$e(_class$e = class AttrBindingBehavior {
      bind(binding, source) {
        binding.targetObserver = new DataAttributeObserver(binding.target, binding.targetProperty);
      }
  
      unbind(binding, source) {}
    }) || _class$e);
  
    var _dec$f, _dec2$a, _class$f, _dec3$4, _dec4$3, _class2$7, _dec5$3, _dec6$3, _class3$4, _dec7$3, _dec8$2, _class4$3, _dec9$2, _dec10$2, _class5$4;
  
    let modeBindingBehavior = {
      bind(binding, source, lookupFunctions) {
        binding.originalMode = binding.mode;
        binding.mode = this.mode;
      },
  
      unbind(binding, source) {
        binding.mode = binding.originalMode;
        binding.originalMode = null;
      }
    };
  
    let OneTimeBindingBehavior = (_dec$f = mixin(modeBindingBehavior), _dec2$a = bindingBehavior('oneTime'), _dec$f(_class$f = _dec2$a(_class$f = class OneTimeBindingBehavior {
      constructor() {
        this.mode = bindingMode.oneTime;
      }
    }) || _class$f) || _class$f);
  
    let OneWayBindingBehavior = (_dec3$4 = mixin(modeBindingBehavior), _dec4$3 = bindingBehavior('oneWay'), _dec3$4(_class2$7 = _dec4$3(_class2$7 = class OneWayBindingBehavior {
      constructor() {
        this.mode = bindingMode.toView;
      }
    }) || _class2$7) || _class2$7);
  
    let ToViewBindingBehavior = (_dec5$3 = mixin(modeBindingBehavior), _dec6$3 = bindingBehavior('toView'), _dec5$3(_class3$4 = _dec6$3(_class3$4 = class ToViewBindingBehavior {
      constructor() {
        this.mode = bindingMode.toView;
      }
    }) || _class3$4) || _class3$4);
  
    let FromViewBindingBehavior = (_dec7$3 = mixin(modeBindingBehavior), _dec8$2 = bindingBehavior('fromView'), _dec7$3(_class4$3 = _dec8$2(_class4$3 = class FromViewBindingBehavior {
      constructor() {
        this.mode = bindingMode.fromView;
      }
    }) || _class4$3) || _class4$3);
  
    let TwoWayBindingBehavior = (_dec9$2 = mixin(modeBindingBehavior), _dec10$2 = bindingBehavior('twoWay'), _dec9$2(_class5$4 = _dec10$2(_class5$4 = class TwoWayBindingBehavior {
      constructor() {
        this.mode = bindingMode.twoWay;
      }
    }) || _class5$4) || _class5$4);
  
    var _dec$g, _class$g;
  
    function throttle(newValue) {
      let state = this.throttleState;
      let elapsed = +new Date() - state.last;
      if (elapsed >= state.delay) {
        clearTimeout(state.timeoutId);
        state.timeoutId = null;
        state.last = +new Date();
        this.throttledMethod(newValue);
        return;
      }
      state.newValue = newValue;
      if (state.timeoutId === null) {
        state.timeoutId = setTimeout(() => {
          state.timeoutId = null;
          state.last = +new Date();
          this.throttledMethod(state.newValue);
        }, state.delay - elapsed);
      }
    }
  
    let ThrottleBindingBehavior = (_dec$g = bindingBehavior('throttle'), _dec$g(_class$g = class ThrottleBindingBehavior {
      bind(binding, source, delay = 200) {
        let methodToThrottle = 'updateTarget';
        if (binding.callSource) {
          methodToThrottle = 'callSource';
        } else if (binding.updateSource && binding.mode === bindingMode.twoWay) {
          methodToThrottle = 'updateSource';
        }
  
        binding.throttledMethod = binding[methodToThrottle];
        binding.throttledMethod.originalName = methodToThrottle;
  
        binding[methodToThrottle] = throttle;
  
        binding.throttleState = {
          delay: delay,
          last: 0,
          timeoutId: null
        };
      }
  
      unbind(binding, source) {
        let methodToRestore = binding.throttledMethod.originalName;
        binding[methodToRestore] = binding.throttledMethod;
        binding.throttledMethod = null;
        clearTimeout(binding.throttleState.timeoutId);
        binding.throttleState = null;
      }
    }) || _class$g);
  
    var _dec$h, _class$h;
  
    const unset = {};
  
    function debounceCallSource(event) {
      const state = this.debounceState;
      clearTimeout(state.timeoutId);
      state.timeoutId = setTimeout(() => this.debouncedMethod(event), state.delay);
    }
  
    function debounceCall(context, newValue, oldValue) {
      const state = this.debounceState;
      clearTimeout(state.timeoutId);
      if (context !== state.callContextToDebounce) {
        state.oldValue = unset;
        this.debouncedMethod(context, newValue, oldValue);
        return;
      }
      if (state.oldValue === unset) {
        state.oldValue = oldValue;
      }
      state.timeoutId = setTimeout(() => {
        const _oldValue = state.oldValue;
        state.oldValue = unset;
        this.debouncedMethod(context, newValue, _oldValue);
      }, state.delay);
    }
  
    let DebounceBindingBehavior = (_dec$h = bindingBehavior('debounce'), _dec$h(_class$h = class DebounceBindingBehavior {
      bind(binding, source, delay = 200) {
        const isCallSource = binding.callSource !== undefined;
        const methodToDebounce = isCallSource ? 'callSource' : 'call';
        const debouncer = isCallSource ? debounceCallSource : debounceCall;
        const mode = binding.mode;
        const callContextToDebounce = mode === bindingMode.twoWay || mode === bindingMode.fromView ? targetContext : sourceContext;
  
        binding.debouncedMethod = binding[methodToDebounce];
        binding.debouncedMethod.originalName = methodToDebounce;
  
        binding[methodToDebounce] = debouncer;
  
        binding.debounceState = {
          callContextToDebounce,
          delay,
          timeoutId: 0,
          oldValue: unset
        };
      }
  
      unbind(binding, source) {
        const methodToRestore = binding.debouncedMethod.originalName;
        binding[methodToRestore] = binding.debouncedMethod;
        binding.debouncedMethod = null;
        clearTimeout(binding.debounceState.timeoutId);
        binding.debounceState = null;
      }
    }) || _class$h);
  
    var _dec$i, _class$i;
  
    function findOriginalEventTarget$1(event) {
      return event.path && event.path[0] || event.deepPath && event.deepPath[0] || event.target;
    }
  
    function handleSelfEvent(event) {
      let target = findOriginalEventTarget$1(event);
      if (this.target !== target) return;
      this.selfEventCallSource(event);
    }
  
    let SelfBindingBehavior = (_dec$i = bindingBehavior('self'), _dec$i(_class$i = class SelfBindingBehavior {
      bind(binding, source) {
        if (!binding.callSource || !binding.targetEvent) throw new Error('Self binding behavior only supports event.');
        binding.selfEventCallSource = binding.callSource;
        binding.callSource = handleSelfEvent;
      }
  
      unbind(binding, source) {
        binding.callSource = binding.selfEventCallSource;
        binding.selfEventCallSource = null;
      }
    }) || _class$i);
  
    let BindingSignaler = class BindingSignaler {
      constructor() {
        this.signals = {};
      }
  
      signal(name) {
        let bindings = this.signals[name];
        if (!bindings) {
          return;
        }
        let i = bindings.length;
        while (i--) {
          bindings[i].call(sourceContext);
        }
      }
    };
  
    var _dec$j, _class$j;
  
    let SignalBindingBehavior = (_dec$j = bindingBehavior('signal'), _dec$j(_class$j = class SignalBindingBehavior {
      static inject() {
        return [BindingSignaler];
      }
  
  
      constructor(bindingSignaler) {
        this.signals = bindingSignaler.signals;
      }
  
      bind(binding, source) {
        if (!binding.updateTarget) {
          throw new Error('Only property bindings and string interpolation bindings can be signaled.  Trigger, delegate and call bindings cannot be signaled.');
        }
        if (arguments.length === 3) {
          let name = arguments[2];
          let bindings = this.signals[name] || (this.signals[name] = []);
          bindings.push(binding);
          binding.signalName = name;
        } else if (arguments.length > 3) {
          let names = Array.prototype.slice.call(arguments, 2);
          let i = names.length;
          while (i--) {
            let name = names[i];
            let bindings = this.signals[name] || (this.signals[name] = []);
            bindings.push(binding);
          }
          binding.signalName = names;
        } else {
          throw new Error('Signal name is required.');
        }
      }
  
      unbind(binding, source) {
        let name = binding.signalName;
        binding.signalName = null;
        if (Array.isArray(name)) {
          let names = name;
          let i = names.length;
          while (i--) {
            let n = names[i];
            let bindings = this.signals[n];
            bindings.splice(bindings.indexOf(binding), 1);
          }
        } else {
          let bindings = this.signals[name];
          bindings.splice(bindings.indexOf(binding), 1);
        }
      }
    }) || _class$j);
  
    var _dec$k, _class$k;
  
    const eventNamesRequired = 'The updateTrigger binding behavior requires at least one event name argument: eg <input value.bind="firstName & updateTrigger:\'blur\'">';
    const notApplicableMessage = 'The updateTrigger binding behavior can only be applied to two-way/ from-view bindings on input/select elements.';
  
    let UpdateTriggerBindingBehavior = (_dec$k = bindingBehavior('updateTrigger'), _dec$k(_class$k = class UpdateTriggerBindingBehavior {
  
      bind(binding, source, ...events) {
        if (events.length === 0) {
          throw new Error(eventNamesRequired);
        }
        if (binding.mode !== bindingMode.twoWay && binding.mode !== bindingMode.fromView) {
          throw new Error(notApplicableMessage);
        }
  
        let targetObserver = binding.observerLocator.getObserver(binding.target, binding.targetProperty);
        if (!targetObserver.handler) {
          throw new Error(notApplicableMessage);
        }
        binding.targetObserver = targetObserver;
  
        targetObserver.originalHandler = binding.targetObserver.handler;
  
        let handler = new EventSubscriber(events);
        targetObserver.handler = handler;
      }
  
      unbind(binding, source) {
        binding.targetObserver.handler.dispose();
        binding.targetObserver.handler = binding.targetObserver.originalHandler;
        binding.targetObserver.originalHandler = null;
      }
    }) || _class$k);
  
    function _createDynamicElement(name, viewUrl, bindableNames) {
      var _dec, _dec2, _class;
  
      let DynamicElement = (_dec = customElement(name), _dec2 = useView(viewUrl), _dec(_class = _dec2(_class = class DynamicElement {
        bind(bindingContext) {
          this.$parent = bindingContext;
        }
      }) || _class) || _class);
  
      for (let i = 0, ii = bindableNames.length; i < ii; ++i) {
        bindable(bindableNames[i])(DynamicElement);
      }
      return DynamicElement;
    }
  
    function getElementName(address) {
      return (/([^\/^\?]+)\.html/i.exec(address)[1].toLowerCase()
      );
    }
  
    function configure$1(config) {
      let viewEngine = config.container.get(ViewEngine);
      let loader = config.aurelia.loader;
  
      viewEngine.addResourcePlugin('.html', {
        'fetch': function (address) {
          return loader.loadTemplate(address).then(registryEntry => {
            let bindable = registryEntry.template.getAttribute('bindable');
            let elementName = getElementName(address);
  
            if (bindable) {
              bindable = bindable.split(',').map(x => x.trim());
              registryEntry.template.removeAttribute('bindable');
            } else {
              bindable = [];
            }
  
            return { [elementName]: _createDynamicElement(elementName, address, bindable) };
          });
        }
      });
    }
  
    function configure$2(config) {
      injectAureliaHideStyleAtHead();
  
      config.globalResources(Compose, If, Else, With, Repeat, Show, Hide, Replaceable, Focus, SanitizeHTMLValueConverter, OneTimeBindingBehavior, OneWayBindingBehavior, ToViewBindingBehavior, FromViewBindingBehavior, TwoWayBindingBehavior, ThrottleBindingBehavior, DebounceBindingBehavior, SelfBindingBehavior, SignalBindingBehavior, UpdateTriggerBindingBehavior, AttrBindingBehavior);
  
      configure$1(config);
  
      let viewEngine = config.container.get(ViewEngine);
      let styleResourcePlugin = {
        fetch(address) {
          return { [address]: _createCSSResource(address) };
        }
      };
      ['.css', '.less', '.sass', '.scss', '.styl'].forEach(ext => viewEngine.addResourcePlugin(ext, styleResourcePlugin));
    }
  
    const logger$3 = getLogger('event-aggregator');
  
    let Handler = class Handler {
      constructor(messageType, callback) {
        this.messageType = messageType;
        this.callback = callback;
      }
  
      handle(message) {
        if (message instanceof this.messageType) {
          this.callback.call(null, message);
        }
      }
    };
  
  
    function invokeCallback(callback, data, event) {
      try {
        callback(data, event);
      } catch (e) {
        logger$3.error(e);
      }
    }
  
    function invokeHandler(handler, data) {
      try {
        handler.handle(data);
      } catch (e) {
        logger$3.error(e);
      }
    }
  
    let EventAggregator = class EventAggregator {
      constructor() {
        this.eventLookup = {};
        this.messageHandlers = [];
      }
  
      publish(event, data) {
        let subscribers;
        let i;
  
        if (!event) {
          throw new Error('Event was invalid.');
        }
  
        if (typeof event === 'string') {
          subscribers = this.eventLookup[event];
          if (subscribers) {
            subscribers = subscribers.slice();
            i = subscribers.length;
  
            while (i--) {
              invokeCallback(subscribers[i], data, event);
            }
          }
        } else {
          subscribers = this.messageHandlers.slice();
          i = subscribers.length;
  
          while (i--) {
            invokeHandler(subscribers[i], event);
          }
        }
      }
  
      subscribe(event, callback) {
        let handler;
        let subscribers;
  
        if (!event) {
          throw new Error('Event channel/type was invalid.');
        }
  
        if (typeof event === 'string') {
          handler = callback;
          subscribers = this.eventLookup[event] || (this.eventLookup[event] = []);
        } else {
          handler = new Handler(event, callback);
          subscribers = this.messageHandlers;
        }
  
        subscribers.push(handler);
  
        return {
          dispose() {
            let idx = subscribers.indexOf(handler);
            if (idx !== -1) {
              subscribers.splice(idx, 1);
            }
          }
        };
      }
  
      subscribeOnce(event, callback) {
        let sub = this.subscribe(event, (a, b) => {
          sub.dispose();
          return callback(a, b);
        });
  
        return sub;
      }
    };
  
    function includeEventsIn(obj) {
      let ea = new EventAggregator();
  
      obj.subscribeOnce = function (event, callback) {
        return ea.subscribeOnce(event, callback);
      };
  
      obj.subscribe = function (event, callback) {
        return ea.subscribe(event, callback);
      };
  
      obj.publish = function (event, data) {
        ea.publish(event, data);
      };
  
      return ea;
    }
  
    function configure$3(config) {
      config.instance(EventAggregator, includeEventsIn(config.aurelia));
    }
  
    function mi$1(name) {
      throw new Error('History must implement ' + name + '().');
    }
  
    var History = function () {
      function History() {
        
      }
  
      History.prototype.activate = function activate(options) {
        mi$1('activate');
      };
  
      History.prototype.deactivate = function deactivate() {
        mi$1('deactivate');
      };
  
      History.prototype.getAbsoluteRoot = function getAbsoluteRoot() {
        mi$1('getAbsoluteRoot');
      };
  
      History.prototype.navigate = function navigate(fragment, options) {
        mi$1('navigate');
      };
  
      History.prototype.navigateBack = function navigateBack() {
        mi$1('navigateBack');
      };
  
      History.prototype.setTitle = function setTitle(title) {
        mi$1('setTitle');
      };
  
      History.prototype.setState = function setState(key, value) {
        mi$1('setState');
      };
  
      History.prototype.getState = function getState(key) {
        mi$1('getState');
      };
  
      History.prototype.getHistoryIndex = function getHistoryIndex() {
        mi$1('getHistoryIndex');
      };
  
      History.prototype.go = function go(movement) {
        mi$1('go');
      };
  
      return History;
    }();
  
    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation. All rights reserved.
    Licensed under the Apache License, Version 2.0 (the "License"); you may not use
    this file except in compliance with the License. You may obtain a copy of the
    License at http://www.apache.org/licenses/LICENSE-2.0
  
    THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
    WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
    MERCHANTABLITY OR NON-INFRINGEMENT.
  
    See the Apache Version 2.0 License for specific language governing permissions
    and limitations under the License.
    ***************************************************************************** */
    /* global Reflect, Promise */
  
    var extendStatics = function(d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
  
    function __extends(d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }
  
    var LinkHandler = (function () {
        function LinkHandler() {
        }
        LinkHandler.prototype.activate = function (history) { };
        LinkHandler.prototype.deactivate = function () { };
        return LinkHandler;
    }());
    var DefaultLinkHandler = (function (_super) {
        __extends(DefaultLinkHandler, _super);
        function DefaultLinkHandler() {
            var _this = _super.call(this) || this;
            _this.handler = function (e) {
                var _a = DefaultLinkHandler.getEventInfo(e), shouldHandleEvent = _a.shouldHandleEvent, href = _a.href;
                if (shouldHandleEvent) {
                    e.preventDefault();
                    _this.history.navigate(href);
                }
            };
            return _this;
        }
        DefaultLinkHandler.prototype.activate = function (history) {
            if (history._hasPushState) {
                this.history = history;
                DOM.addEventListener('click', this.handler, true);
            }
        };
        DefaultLinkHandler.prototype.deactivate = function () {
            DOM.removeEventListener('click', this.handler, true);
        };
        DefaultLinkHandler.getEventInfo = function (event) {
            var $event = event;
            var info = {
                shouldHandleEvent: false,
                href: null,
                anchor: null
            };
            var target = DefaultLinkHandler.findClosestAnchor($event.target);
            if (!target || !DefaultLinkHandler.targetIsThisWindow(target)) {
                return info;
            }
            if (hasAttribute$1(target, 'download')
                || hasAttribute$1(target, 'router-ignore')
                || hasAttribute$1(target, 'data-router-ignore')) {
                return info;
            }
            if ($event.altKey || $event.ctrlKey || $event.metaKey || $event.shiftKey) {
                return info;
            }
            var href = target.getAttribute('href');
            info.anchor = target;
            info.href = href;
            var leftButtonClicked = $event.which === 1;
            var isRelative = href && !(href.charAt(0) === '#' || (/^[a-z]+:/i).test(href));
            info.shouldHandleEvent = leftButtonClicked && isRelative;
            return info;
        };
        DefaultLinkHandler.findClosestAnchor = function (el) {
            while (el) {
                if (el.tagName === 'A') {
                    return el;
                }
                el = el.parentNode;
            }
        };
        DefaultLinkHandler.targetIsThisWindow = function (target) {
            var targetWindow = target.getAttribute('target');
            var win = PLATFORM.global;
            return !targetWindow ||
                targetWindow === win.name ||
                targetWindow === '_self';
        };
        return DefaultLinkHandler;
    }(LinkHandler));
    var hasAttribute$1 = function (el, attr) { return el.hasAttribute(attr); };
  
    var BrowserHistory = (function (_super) {
        __extends(BrowserHistory, _super);
        function BrowserHistory(linkHandler) {
            var _this = _super.call(this) || this;
            _this._isActive = false;
            _this._checkUrlCallback = _this._checkUrl.bind(_this);
            _this.location = PLATFORM.location;
            _this.history = PLATFORM.history;
            _this.linkHandler = linkHandler;
            return _this;
        }
        BrowserHistory.prototype.activate = function (options) {
            if (this._isActive) {
                throw new Error('History has already been activated.');
            }
            var $history = this.history;
            var wantsPushState = !!options.pushState;
            this._isActive = true;
            var normalizedOptions = this.options = Object.assign({}, { root: '/' }, this.options, options);
            var rootUrl = this.root = ('/' + normalizedOptions.root + '/').replace(rootStripper, '/');
            var wantsHashChange = this._wantsHashChange = normalizedOptions.hashChange !== false;
            var hasPushState = this._hasPushState = !!(normalizedOptions.pushState && $history && $history.pushState);
            var eventName;
            if (hasPushState) {
                eventName = 'popstate';
            }
            else if (wantsHashChange) {
                eventName = 'hashchange';
            }
            PLATFORM.addEventListener(eventName, this._checkUrlCallback);
            if (wantsHashChange && wantsPushState) {
                var $location = this.location;
                var atRoot = $location.pathname.replace(/[^\/]$/, '$&/') === rootUrl;
                if (!hasPushState && !atRoot) {
                    var fragment = this.fragment = this._getFragment(null, true);
                    $location.replace(rootUrl + $location.search + '#' + fragment);
                    return true;
                }
                else if (hasPushState && atRoot && $location.hash) {
                    var fragment = this.fragment = this._getHash().replace(routeStripper, '');
                    $history.replaceState({}, DOM.title, rootUrl + fragment + $location.search);
                }
            }
            if (!this.fragment) {
                this.fragment = this._getFragment('');
            }
            this.linkHandler.activate(this);
            if (!normalizedOptions.silent) {
                return this._loadUrl('');
            }
        };
        BrowserHistory.prototype.deactivate = function () {
            var handler = this._checkUrlCallback;
            PLATFORM.removeEventListener('popstate', handler);
            PLATFORM.removeEventListener('hashchange', handler);
            this._isActive = false;
            this.linkHandler.deactivate();
        };
        BrowserHistory.prototype.getAbsoluteRoot = function () {
            var $location = this.location;
            var origin = createOrigin($location.protocol, $location.hostname, $location.port);
            return "" + origin + this.root;
        };
        BrowserHistory.prototype.navigate = function (fragment, _a) {
            var _b = _a === void 0 ? {} : _a, _c = _b.trigger, trigger = _c === void 0 ? true : _c, _d = _b.replace, replace = _d === void 0 ? false : _d;
            var location = this.location;
            if (fragment && absoluteUrl.test(fragment)) {
                location.href = fragment;
                return true;
            }
            if (!this._isActive) {
                return false;
            }
            fragment = this._getFragment(fragment || '');
            if (this.fragment === fragment && !replace) {
                return false;
            }
            this.fragment = fragment;
            var url = this.root + fragment;
            if (fragment === '' && url !== '/') {
                url = url.slice(0, -1);
            }
            if (this._hasPushState) {
                url = url.replace('//', '/');
                this.history[replace ? 'replaceState' : 'pushState']({}, DOM.title, url);
            }
            else if (this._wantsHashChange) {
                updateHash(location, fragment, replace);
            }
            else {
                location.assign(url);
            }
            if (trigger) {
                return this._loadUrl(fragment);
            }
            return true;
        };
        BrowserHistory.prototype.navigateBack = function () {
            this.history.back();
        };
        BrowserHistory.prototype.setTitle = function (title) {
            DOM.title = title;
        };
        BrowserHistory.prototype.setState = function (key, value) {
            var $history = this.history;
            var state = Object.assign({}, $history.state);
            var _a = this.location, pathname = _a.pathname, search = _a.search, hash = _a.hash;
            state[key] = value;
            $history.replaceState(state, null, "" + pathname + search + hash);
        };
        BrowserHistory.prototype.getState = function (key) {
            var state = Object.assign({}, this.history.state);
            return state[key];
        };
        BrowserHistory.prototype.getHistoryIndex = function () {
            var historyIndex = this.getState('HistoryIndex');
            if (historyIndex === undefined) {
                historyIndex = this.history.length - 1;
                this.setState('HistoryIndex', historyIndex);
            }
            return historyIndex;
        };
        BrowserHistory.prototype.go = function (movement) {
            this.history.go(movement);
        };
        BrowserHistory.prototype._getHash = function () {
            return this.location.hash.substr(1);
        };
        BrowserHistory.prototype._getFragment = function (fragment, forcePushState) {
            var rootUrl;
            if (!fragment) {
                if (this._hasPushState || !this._wantsHashChange || forcePushState) {
                    var location_1 = this.location;
                    fragment = location_1.pathname + location_1.search;
                    rootUrl = this.root.replace(trailingSlash, '');
                    if (!fragment.indexOf(rootUrl)) {
                        fragment = fragment.substr(rootUrl.length);
                    }
                }
                else {
                    fragment = this._getHash();
                }
            }
            return '/' + fragment.replace(routeStripper, '');
        };
        BrowserHistory.prototype._checkUrl = function () {
            var current = this._getFragment('');
            if (current !== this.fragment) {
                this._loadUrl('');
            }
        };
        BrowserHistory.prototype._loadUrl = function (fragmentOverride) {
            var fragment = this.fragment = this._getFragment(fragmentOverride);
            return this.options.routeHandler ?
                this.options.routeHandler(fragment) :
                false;
        };
        BrowserHistory.inject = [LinkHandler];
        return BrowserHistory;
    }(History));
    var routeStripper = /^#?\/*|\s+$/g;
    var rootStripper = /^\/+|\/+$/g;
    var trailingSlash = /\/$/;
    var absoluteUrl = /^([a-z][a-z0-9+\-.]*:)?\/\//i;
    function updateHash($location, fragment, replace) {
        if (replace) {
            var href = $location.href.replace(/(javascript:|#).*$/, '');
            $location.replace(href + '#' + fragment);
        }
        else {
            $location.hash = '#' + fragment;
        }
    }
    function createOrigin(protocol, hostname, port) {
        return protocol + "//" + hostname + (port ? ':' + port : '');
    }
  
    function configure$4(config) {
        var $config = config;
        $config.singleton(History, BrowserHistory);
        $config.transient(LinkHandler, DefaultLinkHandler);
    }
  
    let State = class State {
      constructor(charSpec) {
        this.charSpec = charSpec;
        this.nextStates = [];
      }
  
      get(charSpec) {
        for (let child of this.nextStates) {
          let isEqual = child.charSpec.validChars === charSpec.validChars && child.charSpec.invalidChars === charSpec.invalidChars;
  
          if (isEqual) {
            return child;
          }
        }
  
        return undefined;
      }
  
      put(charSpec) {
        let state = this.get(charSpec);
  
        if (state) {
          return state;
        }
  
        state = new State(charSpec);
  
        this.nextStates.push(state);
  
        if (charSpec.repeat) {
          state.nextStates.push(state);
        }
  
        return state;
      }
  
      match(ch) {
        let nextStates = this.nextStates;
        let results = [];
  
        for (let i = 0, l = nextStates.length; i < l; i++) {
          let child = nextStates[i];
          let charSpec = child.charSpec;
  
          if (charSpec.validChars !== undefined) {
            if (charSpec.validChars.indexOf(ch) !== -1) {
              results.push(child);
            }
          } else if (charSpec.invalidChars !== undefined) {
            if (charSpec.invalidChars.indexOf(ch) === -1) {
              results.push(child);
            }
          }
        }
  
        return results;
      }
    };
  
    const specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
  
    const escapeRegex = new RegExp('(\\' + specials.join('|\\') + ')', 'g');
  
    let StaticSegment = class StaticSegment {
      constructor(string, caseSensitive) {
        this.string = string;
        this.caseSensitive = caseSensitive;
      }
  
      eachChar(callback) {
        let s = this.string;
        for (let i = 0, ii = s.length; i < ii; ++i) {
          let ch = s[i];
          callback({ validChars: this.caseSensitive ? ch : ch.toUpperCase() + ch.toLowerCase() });
        }
      }
  
      regex() {
        return this.string.replace(escapeRegex, '\\$1');
      }
  
      generate() {
        return this.string;
      }
    };
  
    let DynamicSegment = class DynamicSegment {
      constructor(name, optional) {
        this.name = name;
        this.optional = optional;
      }
  
      eachChar(callback) {
        callback({ invalidChars: '/', repeat: true });
      }
  
      regex() {
        return '([^/]+)';
      }
  
      generate(params, consumed) {
        consumed[this.name] = true;
        return params[this.name];
      }
    };
  
    let StarSegment = class StarSegment {
      constructor(name) {
        this.name = name;
      }
  
      eachChar(callback) {
        callback({ invalidChars: '', repeat: true });
      }
  
      regex() {
        return '(.+)';
      }
  
      generate(params, consumed) {
        consumed[this.name] = true;
        return params[this.name];
      }
    };
  
    let EpsilonSegment = class EpsilonSegment {
      eachChar() {}
  
      regex() {
        return '';
      }
  
      generate() {
        return '';
      }
    };
  
    let RouteRecognizer = class RouteRecognizer {
      constructor() {
        this.rootState = new State();
        this.names = {};
        this.routes = new Map();
      }
  
      add(route) {
        if (Array.isArray(route)) {
          route.forEach(r => this.add(r));
          return undefined;
        }
  
        let currentState = this.rootState;
        let skippableStates = [];
        let regex = '^';
        let types = { statics: 0, dynamics: 0, stars: 0 };
        let names = [];
        let routeName = route.handler.name;
        let isEmpty = true;
        let segments = parse(route.path, names, types, route.caseSensitive);
  
        for (let i = 0, ii = segments.length; i < ii; i++) {
          let segment = segments[i];
          if (segment instanceof EpsilonSegment) {
            continue;
          }
  
          let [firstState, nextState] = addSegment(currentState, segment);
  
          for (let j = 0, jj = skippableStates.length; j < jj; j++) {
            skippableStates[j].nextStates.push(firstState);
          }
  
          if (segment.optional) {
            skippableStates.push(nextState);
            regex += `(?:/${segment.regex()})?`;
          } else {
            currentState = nextState;
            regex += `/${segment.regex()}`;
            skippableStates.length = 0;
            isEmpty = false;
          }
        }
  
        if (isEmpty) {
          currentState = currentState.put({ validChars: '/' });
          regex += '/?';
        }
  
        let handlers = [{ handler: route.handler, names: names }];
  
        this.routes.set(route.handler, { segments, handlers });
        if (routeName) {
          let routeNames = Array.isArray(routeName) ? routeName : [routeName];
          for (let i = 0; i < routeNames.length; i++) {
            if (!(routeNames[i] in this.names)) {
              this.names[routeNames[i]] = { segments, handlers };
            }
          }
        }
  
        for (let i = 0; i < skippableStates.length; i++) {
          let state = skippableStates[i];
          state.handlers = handlers;
          state.regex = new RegExp(regex + '$', route.caseSensitive ? '' : 'i');
          state.types = types;
        }
  
        currentState.handlers = handlers;
        currentState.regex = new RegExp(regex + '$', route.caseSensitive ? '' : 'i');
        currentState.types = types;
  
        return currentState;
      }
  
      getRoute(nameOrRoute) {
        return typeof nameOrRoute === 'string' ? this.names[nameOrRoute] : this.routes.get(nameOrRoute);
      }
  
      handlersFor(nameOrRoute) {
        let route = this.getRoute(nameOrRoute);
        if (!route) {
          throw new Error(`There is no route named ${nameOrRoute}`);
        }
  
        return [...route.handlers];
      }
  
      hasRoute(nameOrRoute) {
        return !!this.getRoute(nameOrRoute);
      }
  
      generate(nameOrRoute, params) {
        let route = this.getRoute(nameOrRoute);
        if (!route) {
          throw new Error(`There is no route named ${nameOrRoute}`);
        }
  
        let handler = route.handlers[0].handler;
        if (handler.generationUsesHref) {
          return handler.href;
        }
  
        let routeParams = Object.assign({}, params);
        let segments = route.segments;
        let consumed = {};
        let output = '';
  
        for (let i = 0, l = segments.length; i < l; i++) {
          let segment = segments[i];
  
          if (segment instanceof EpsilonSegment) {
            continue;
          }
  
          let segmentValue = segment.generate(routeParams, consumed);
          if (segmentValue === null || segmentValue === undefined) {
            if (!segment.optional) {
              throw new Error(`A value is required for route parameter '${segment.name}' in route '${nameOrRoute}'.`);
            }
          } else {
            output += '/';
            output += segmentValue;
          }
        }
  
        if (output.charAt(0) !== '/') {
          output = '/' + output;
        }
  
        for (let param in consumed) {
          delete routeParams[param];
        }
  
        let queryString = buildQueryString(routeParams);
        output += queryString ? `?${queryString}` : '';
  
        return output;
      }
  
      recognize(path) {
        let states = [this.rootState];
        let queryParams = {};
        let isSlashDropped = false;
        let normalizedPath = path;
  
        let queryStart = normalizedPath.indexOf('?');
        if (queryStart !== -1) {
          let queryString = normalizedPath.substr(queryStart + 1, normalizedPath.length);
          normalizedPath = normalizedPath.substr(0, queryStart);
          queryParams = parseQueryString(queryString);
        }
  
        normalizedPath = decodeURI(normalizedPath);
  
        if (normalizedPath.charAt(0) !== '/') {
          normalizedPath = '/' + normalizedPath;
        }
  
        let pathLen = normalizedPath.length;
        if (pathLen > 1 && normalizedPath.charAt(pathLen - 1) === '/') {
          normalizedPath = normalizedPath.substr(0, pathLen - 1);
          isSlashDropped = true;
        }
  
        for (let i = 0, l = normalizedPath.length; i < l; i++) {
          states = recognizeChar(states, normalizedPath.charAt(i));
          if (!states.length) {
            break;
          }
        }
  
        let solutions = [];
        for (let i = 0, l = states.length; i < l; i++) {
          if (states[i].handlers) {
            solutions.push(states[i]);
          }
        }
  
        states = sortSolutions(solutions);
  
        let state = solutions[0];
        if (state && state.handlers) {
          if (isSlashDropped && state.regex.source.slice(-5) === '(.+)$') {
            normalizedPath = normalizedPath + '/';
          }
  
          return findHandler(state, normalizedPath, queryParams);
        }
      }
    };
  
    let RecognizeResults = class RecognizeResults {
      constructor(queryParams) {
        this.splice = Array.prototype.splice;
        this.slice = Array.prototype.slice;
        this.push = Array.prototype.push;
        this.length = 0;
        this.queryParams = queryParams || {};
      }
    };
  
  
    function parse(route, names, types, caseSensitive) {
      let normalizedRoute = route;
      if (route.charAt(0) === '/') {
        normalizedRoute = route.substr(1);
      }
  
      let results = [];
  
      let splitRoute = normalizedRoute.split('/');
      for (let i = 0, ii = splitRoute.length; i < ii; ++i) {
        let segment = splitRoute[i];
  
        let match = segment.match(/^:([^?]+)(\?)?$/);
        if (match) {
          let [, name, optional] = match;
          if (name.indexOf('=') !== -1) {
            throw new Error(`Parameter ${name} in route ${route} has a default value, which is not supported.`);
          }
          results.push(new DynamicSegment(name, !!optional));
          names.push(name);
          types.dynamics++;
          continue;
        }
  
        match = segment.match(/^\*(.+)$/);
        if (match) {
          results.push(new StarSegment(match[1]));
          names.push(match[1]);
          types.stars++;
        } else if (segment === '') {
          results.push(new EpsilonSegment());
        } else {
          results.push(new StaticSegment(segment, caseSensitive));
          types.statics++;
        }
      }
  
      return results;
    }
  
    function sortSolutions(states) {
      return states.sort((a, b) => {
        if (a.types.stars !== b.types.stars) {
          return a.types.stars - b.types.stars;
        }
  
        if (a.types.stars) {
          if (a.types.statics !== b.types.statics) {
            return b.types.statics - a.types.statics;
          }
          if (a.types.dynamics !== b.types.dynamics) {
            return b.types.dynamics - a.types.dynamics;
          }
        }
  
        if (a.types.dynamics !== b.types.dynamics) {
          return a.types.dynamics - b.types.dynamics;
        }
  
        if (a.types.statics !== b.types.statics) {
          return b.types.statics - a.types.statics;
        }
  
        return 0;
      });
    }
  
    function recognizeChar(states, ch) {
      let nextStates = [];
  
      for (let i = 0, l = states.length; i < l; i++) {
        let state = states[i];
        nextStates.push(...state.match(ch));
      }
  
      return nextStates;
    }
  
    function findHandler(state, path, queryParams) {
      let handlers = state.handlers;
      let regex = state.regex;
      let captures = path.match(regex);
      let currentCapture = 1;
      let result = new RecognizeResults(queryParams);
  
      for (let i = 0, l = handlers.length; i < l; i++) {
        let handler = handlers[i];
        let names = handler.names;
        let params = {};
  
        for (let j = 0, m = names.length; j < m; j++) {
          params[names[j]] = captures[currentCapture++];
        }
  
        result.push({ handler: handler.handler, params: params, isDynamic: !!names.length });
      }
  
      return result;
    }
  
    function addSegment(currentState, segment) {
      let firstState = currentState.put({ validChars: '/' });
      let nextState = firstState;
      segment.eachChar(ch => {
        nextState = nextState.put(ch);
      });
  
      return [firstState, nextState];
    }
  
    /**
     * Class used to represent an instruction during a navigation.
     */
    class NavigationInstruction {
        constructor(init) {
            /**
             * Current built viewport plan of this nav instruction
             */
            this.plan = null;
            this.options = {};
            Object.assign(this, init);
            this.params = this.params || {};
            this.viewPortInstructions = {};
            let ancestorParams = [];
            let current = this;
            do {
                let currentParams = Object.assign({}, current.params);
                if (current.config && current.config.hasChildRouter) {
                    // remove the param for the injected child route segment
                    delete currentParams[current.getWildCardName()];
                }
                ancestorParams.unshift(currentParams);
                current = current.parentInstruction;
            } while (current);
            let allParams = Object.assign({}, this.queryParams, ...ancestorParams);
            this.lifecycleArgs = [allParams, this.config, this];
        }
        /**
         * Gets an array containing this instruction and all child instructions for the current navigation.
         */
        getAllInstructions() {
            let instructions = [this];
            let viewPortInstructions = this.viewPortInstructions;
            for (let key in viewPortInstructions) {
                let childInstruction = viewPortInstructions[key].childNavigationInstruction;
                if (childInstruction) {
                    instructions.push(...childInstruction.getAllInstructions());
                }
            }
            return instructions;
        }
        /**
         * Gets an array containing the instruction and all child instructions for the previous navigation.
         * Previous instructions are no longer available after navigation completes.
         */
        getAllPreviousInstructions() {
            return this.getAllInstructions().map(c => c.previousInstruction).filter(c => c);
        }
        addViewPortInstruction(nameOrInitOptions, strategy, moduleId, component) {
            let viewPortInstruction;
            let viewPortName = typeof nameOrInitOptions === 'string' ? nameOrInitOptions : nameOrInitOptions.name;
            const lifecycleArgs = this.lifecycleArgs;
            const config = Object.assign({}, lifecycleArgs[1], { currentViewPort: viewPortName });
            if (typeof nameOrInitOptions === 'string') {
                viewPortInstruction = {
                    name: nameOrInitOptions,
                    strategy: strategy,
                    moduleId: moduleId,
                    component: component,
                    childRouter: component.childRouter,
                    lifecycleArgs: [lifecycleArgs[0], config, lifecycleArgs[2]]
                };
            }
            else {
                viewPortInstruction = {
                    name: viewPortName,
                    strategy: nameOrInitOptions.strategy,
                    component: nameOrInitOptions.component,
                    moduleId: nameOrInitOptions.moduleId,
                    childRouter: nameOrInitOptions.component.childRouter,
                    lifecycleArgs: [lifecycleArgs[0], config, lifecycleArgs[2]]
                };
            }
            return this.viewPortInstructions[viewPortName] = viewPortInstruction;
        }
        /**
         * Gets the name of the route pattern's wildcard parameter, if applicable.
         */
        getWildCardName() {
            // todo: potential issue, or at least unsafe typings
            let configRoute = this.config.route;
            let wildcardIndex = configRoute.lastIndexOf('*');
            return configRoute.substr(wildcardIndex + 1);
        }
        /**
         * Gets the path and query string created by filling the route
         * pattern's wildcard parameter with the matching param.
         */
        getWildcardPath() {
            let wildcardName = this.getWildCardName();
            let path = this.params[wildcardName] || '';
            let queryString = this.queryString;
            if (queryString) {
                path += '?' + queryString;
            }
            return path;
        }
        /**
         * Gets the instruction's base URL, accounting for wildcard route parameters.
         */
        getBaseUrl() {
            let $encodeURI = encodeURI;
            let fragment = decodeURI(this.fragment);
            if (fragment === '') {
                let nonEmptyRoute = this.router.routes.find(route => {
                    return route.name === this.config.name &&
                        route.route !== '';
                });
                if (nonEmptyRoute) {
                    fragment = nonEmptyRoute.route;
                }
            }
            if (!this.params) {
                return $encodeURI(fragment);
            }
            let wildcardName = this.getWildCardName();
            let path = this.params[wildcardName] || '';
            if (!path) {
                return $encodeURI(fragment);
            }
            return $encodeURI(fragment.substr(0, fragment.lastIndexOf(path)));
        }
        /**
         * Finalize a viewport instruction
         * @internal
         */
        _commitChanges(waitToSwap) {
            let router = this.router;
            router.currentInstruction = this;
            const previousInstruction = this.previousInstruction;
            if (previousInstruction) {
                previousInstruction.config.navModel.isActive = false;
            }
            this.config.navModel.isActive = true;
            router.refreshNavigation();
            let loads = [];
            let delaySwaps = [];
            let viewPortInstructions = this.viewPortInstructions;
            for (let viewPortName in viewPortInstructions) {
                let viewPortInstruction = viewPortInstructions[viewPortName];
                let viewPort = router.viewPorts[viewPortName];
                if (!viewPort) {
                    throw new Error(`There was no router-view found in the view for ${viewPortInstruction.moduleId}.`);
                }
                let childNavInstruction = viewPortInstruction.childNavigationInstruction;
                if (viewPortInstruction.strategy === "replace" /* Replace */) {
                    if (childNavInstruction && childNavInstruction.parentCatchHandler) {
                        loads.push(childNavInstruction._commitChanges(waitToSwap));
                    }
                    else {
                        if (waitToSwap) {
                            delaySwaps.push({ viewPort, viewPortInstruction });
                        }
                        loads.push(viewPort
                            .process(viewPortInstruction, waitToSwap)
                            .then(() => childNavInstruction
                            ? childNavInstruction._commitChanges(waitToSwap)
                            : Promise.resolve()));
                    }
                }
                else {
                    if (childNavInstruction) {
                        loads.push(childNavInstruction._commitChanges(waitToSwap));
                    }
                }
            }
            return Promise
                .all(loads)
                .then(() => {
                delaySwaps.forEach(x => x.viewPort.swap(x.viewPortInstruction));
                return null;
            })
                .then(() => prune(this));
        }
        /**@internal */
        _updateTitle() {
            let router = this.router;
            let title = this._buildTitle(router.titleSeparator);
            if (title) {
                router.history.setTitle(title);
            }
        }
        /**@internal */
        _buildTitle(separator = ' | ') {
            let title = '';
            let childTitles = [];
            let navModelTitle = this.config.navModel.title;
            let instructionRouter = this.router;
            let viewPortInstructions = this.viewPortInstructions;
            if (navModelTitle) {
                title = instructionRouter.transformTitle(navModelTitle);
            }
            for (let viewPortName in viewPortInstructions) {
                let viewPortInstruction = viewPortInstructions[viewPortName];
                let child_nav_instruction = viewPortInstruction.childNavigationInstruction;
                if (child_nav_instruction) {
                    let childTitle = child_nav_instruction._buildTitle(separator);
                    if (childTitle) {
                        childTitles.push(childTitle);
                    }
                }
            }
            if (childTitles.length) {
                title = childTitles.join(separator) + (title ? separator : '') + title;
            }
            if (instructionRouter.title) {
                title += (title ? separator : '') + instructionRouter.transformTitle(instructionRouter.title);
            }
            return title;
        }
    }
    const prune = (instruction) => {
        instruction.previousInstruction = null;
        instruction.plan = null;
    };
  
    /**
    * Class for storing and interacting with a route's navigation settings.
    */
    class NavModel {
        constructor(router, relativeHref) {
            /**
            * True if this nav item is currently active.
            */
            this.isActive = false;
            /**
            * The title.
            */
            this.title = null;
            /**
            * This nav item's absolute href.
            */
            this.href = null;
            /**
            * This nav item's relative href.
            */
            this.relativeHref = null;
            /**
            * Data attached to the route at configuration time.
            */
            this.settings = {};
            /**
            * The route config.
            */
            this.config = null;
            this.router = router;
            this.relativeHref = relativeHref;
        }
        /**
        * Sets the route's title and updates document.title.
        *  If the a navigation is in progress, the change will be applied
        *  to document.title when the navigation completes.
        *
        * @param title The new title.
        */
        setTitle(title) {
            this.title = title;
            if (this.isActive) {
                this.router.updateTitle();
            }
        }
    }
  
    function _normalizeAbsolutePath(path, hasPushState, absolute = false) {
        if (!hasPushState && path[0] !== '#') {
            path = '#' + path;
        }
        if (hasPushState && absolute) {
            path = path.substring(1, path.length);
        }
        return path;
    }
    function _createRootedPath(fragment, baseUrl, hasPushState, absolute) {
        if (isAbsoluteUrl.test(fragment)) {
            return fragment;
        }
        let path = '';
        if (baseUrl.length && baseUrl[0] !== '/') {
            path += '/';
        }
        path += baseUrl;
        if ((!path.length || path[path.length - 1] !== '/') && fragment[0] !== '/') {
            path += '/';
        }
        if (path.length && path[path.length - 1] === '/' && fragment[0] === '/') {
            path = path.substring(0, path.length - 1);
        }
        return _normalizeAbsolutePath(path + fragment, hasPushState, absolute);
    }
    function _resolveUrl(fragment, baseUrl, hasPushState) {
        if (isRootedPath.test(fragment)) {
            return _normalizeAbsolutePath(fragment, hasPushState);
        }
        return _createRootedPath(fragment, baseUrl, hasPushState);
    }
    function _ensureArrayWithSingleRoutePerConfig(config) {
        let routeConfigs = [];
        if (Array.isArray(config.route)) {
            for (let i = 0, ii = config.route.length; i < ii; ++i) {
                let current = Object.assign({}, config);
                current.route = config.route[i];
                routeConfigs.push(current);
            }
        }
        else {
            routeConfigs.push(Object.assign({}, config));
        }
        return routeConfigs;
    }
    const isRootedPath = /^#?\//;
    const isAbsoluteUrl = /^([a-z][a-z0-9+\-.]*:)?\/\//i;
  
    /**
     * Class used to configure a [[Router]] instance.
     *
     * @constructor
     */
    class RouterConfiguration {
        constructor() {
            this.instructions = [];
            this.options = {};
            this.pipelineSteps = [];
        }
        /**
         * Adds a step to be run during the [[Router]]'s navigation pipeline.
         *
         * @param name The name of the pipeline slot to insert the step into.
         * @param step The pipeline step.
         * @chainable
         */
        addPipelineStep(name, step) {
            if (step === null || step === undefined) {
                throw new Error('Pipeline step cannot be null or undefined.');
            }
            this.pipelineSteps.push({ name, step });
            return this;
        }
        /**
         * Adds a step to be run during the [[Router]]'s authorize pipeline slot.
         *
         * @param step The pipeline step.
         * @chainable
         */
        addAuthorizeStep(step) {
            return this.addPipelineStep("authorize" /* Authorize */, step);
        }
        /**
         * Adds a step to be run during the [[Router]]'s preActivate pipeline slot.
         *
         * @param step The pipeline step.
         * @chainable
         */
        addPreActivateStep(step) {
            return this.addPipelineStep("preActivate" /* PreActivate */, step);
        }
        /**
         * Adds a step to be run during the [[Router]]'s preRender pipeline slot.
         *
         * @param step The pipeline step.
         * @chainable
         */
        addPreRenderStep(step) {
            return this.addPipelineStep("preRender" /* PreRender */, step);
        }
        /**
         * Adds a step to be run during the [[Router]]'s postRender pipeline slot.
         *
         * @param step The pipeline step.
         * @chainable
         */
        addPostRenderStep(step) {
            return this.addPipelineStep("postRender" /* PostRender */, step);
        }
        /**
         * Configures a route that will be used if there is no previous location available on navigation cancellation.
         *
         * @param fragment The URL fragment to use as the navigation destination.
         * @chainable
         */
        fallbackRoute(fragment) {
            this._fallbackRoute = fragment;
            return this;
        }
        /**
         * Maps one or more routes to be registered with the router.
         *
         * @param route The [[RouteConfig]] to map, or an array of [[RouteConfig]] to map.
         * @chainable
         */
        map(route) {
            if (Array.isArray(route)) {
                route.forEach(r => this.map(r));
                return this;
            }
            return this.mapRoute(route);
        }
        /**
         * Configures defaults to use for any view ports.
         *
         * @param viewPortConfig a view port configuration object to use as a
         *  default, of the form { viewPortName: { moduleId } }.
         * @chainable
         */
        useViewPortDefaults(viewPortConfig) {
            this.viewPortDefaults = viewPortConfig;
            return this;
        }
        /**
         * Maps a single route to be registered with the router.
         *
         * @param route The [[RouteConfig]] to map.
         * @chainable
         */
        mapRoute(config) {
            this.instructions.push(router => {
                let routeConfigs = _ensureArrayWithSingleRoutePerConfig(config);
                let navModel;
                for (let i = 0, ii = routeConfigs.length; i < ii; ++i) {
                    let routeConfig = routeConfigs[i];
                    routeConfig.settings = routeConfig.settings || {};
                    if (!navModel) {
                        navModel = router.createNavModel(routeConfig);
                    }
                    router.addRoute(routeConfig, navModel);
                }
            });
            return this;
        }
        /**
         * Registers an unknown route handler to be run when the URL fragment doesn't match any registered routes.
         *
         * @param config A string containing a moduleId to load, or a [[RouteConfig]], or a function that takes the
         *  [[NavigationInstruction]] and selects a moduleId to load.
         * @chainable
         */
        mapUnknownRoutes(config) {
            this.unknownRouteConfig = config;
            return this;
        }
        /**
         * Applies the current configuration to the specified [[Router]].
         *
         * @param router The [[Router]] to apply the configuration to.
         */
        exportToRouter(router) {
            let instructions = this.instructions;
            for (let i = 0, ii = instructions.length; i < ii; ++i) {
                instructions[i](router);
            }
            let { title, titleSeparator, unknownRouteConfig, _fallbackRoute, viewPortDefaults } = this;
            if (title) {
                router.title = title;
            }
            if (titleSeparator) {
                router.titleSeparator = titleSeparator;
            }
            if (unknownRouteConfig) {
                router.handleUnknownRoutes(unknownRouteConfig);
            }
            if (_fallbackRoute) {
                router.fallbackRoute = _fallbackRoute;
            }
            if (viewPortDefaults) {
                router.useViewPortDefaults(viewPortDefaults);
            }
            Object.assign(router.options, this.options);
            let pipelineSteps = this.pipelineSteps;
            let pipelineStepCount = pipelineSteps.length;
            if (pipelineStepCount) {
                if (!router.isRoot) {
                    throw new Error('Pipeline steps can only be added to the root router');
                }
                let pipelineProvider = router.pipelineProvider;
                for (let i = 0, ii = pipelineStepCount; i < ii; ++i) {
                    let { name, step } = pipelineSteps[i];
                    pipelineProvider.addStep(name, step);
                }
            }
        }
    }
  
    /**
     * The primary class responsible for handling routing and navigation.
     */
    class Router {
        /**
         * @param container The [[Container]] to use when child routers.
         * @param history The [[History]] implementation to delegate navigation requests to.
         */
        constructor(container, history) {
            /**
             * The parent router, or null if this instance is not a child router.
             */
            this.parent = null;
            this.options = {};
            /**
             * The defaults used when a viewport lacks specified content
             */
            this.viewPortDefaults = {};
            /**
             * Extension point to transform the document title before it is built and displayed.
             * By default, child routers delegate to the parent router, and the app router
             * returns the title unchanged.
             */
            this.transformTitle = (title) => {
                if (this.parent) {
                    return this.parent.transformTitle(title);
                }
                return title;
            };
            this.container = container;
            this.history = history;
            this.reset();
        }
        /**
         * Fully resets the router's internal state. Primarily used internally by the framework when multiple calls to setRoot are made.
         * Use with caution (actually, avoid using this). Do not use this to simply change your navigation model.
         */
        reset() {
            this.viewPorts = {};
            this.routes = [];
            this.baseUrl = '';
            this.isConfigured = false;
            this.isNavigating = false;
            this.isExplicitNavigation = false;
            this.isExplicitNavigationBack = false;
            this.isNavigatingFirst = false;
            this.isNavigatingNew = false;
            this.isNavigatingRefresh = false;
            this.isNavigatingForward = false;
            this.isNavigatingBack = false;
            this.couldDeactivate = false;
            this.navigation = [];
            this.currentInstruction = null;
            this.viewPortDefaults = {};
            this._fallbackOrder = 100;
            this._recognizer = new RouteRecognizer();
            this._childRecognizer = new RouteRecognizer();
            this._configuredPromise = new Promise(resolve => {
                this._resolveConfiguredPromise = resolve;
            });
        }
        /**
         * Gets a value indicating whether or not this [[Router]] is the root in the router tree. I.e., it has no parent.
         */
        get isRoot() {
            return !this.parent;
        }
        /**
         * Registers a viewPort to be used as a rendering target for activated routes.
         *
         * @param viewPort The viewPort.
         * @param name The name of the viewPort. 'default' if unspecified.
         */
        registerViewPort(viewPort, name) {
            name = name || 'default';
            this.viewPorts[name] = viewPort;
        }
        /**
         * Returns a Promise that resolves when the router is configured.
         */
        ensureConfigured() {
            return this._configuredPromise;
        }
        /**
         * Configures the router.
         *
         * @param callbackOrConfig The [[RouterConfiguration]] or a callback that takes a [[RouterConfiguration]].
         */
        configure(callbackOrConfig) {
            this.isConfigured = true;
            let result = callbackOrConfig;
            let config;
            if (typeof callbackOrConfig === 'function') {
                config = new RouterConfiguration();
                result = callbackOrConfig(config);
            }
            return Promise
                .resolve(result)
                .then((c) => {
                if (c && c.exportToRouter) {
                    config = c;
                }
                config.exportToRouter(this);
                this.isConfigured = true;
                this._resolveConfiguredPromise();
            });
        }
        /**
         * Navigates to a new location.
         *
         * @param fragment The URL fragment to use as the navigation destination.
         * @param options The navigation options.
         */
        navigate(fragment, options) {
            if (!this.isConfigured && this.parent) {
                return this.parent.navigate(fragment, options);
            }
            this.isExplicitNavigation = true;
            return this.history.navigate(_resolveUrl(fragment, this.baseUrl, this.history._hasPushState), options);
        }
        /**
         * Navigates to a new location corresponding to the route and params specified. Equivallent to [[Router.generate]] followed
         * by [[Router.navigate]].
         *
         * @param route The name of the route to use when generating the navigation location.
         * @param params The route parameters to be used when populating the route pattern.
         * @param options The navigation options.
         */
        navigateToRoute(route, params, options) {
            let path = this.generate(route, params);
            return this.navigate(path, options);
        }
        /**
         * Navigates back to the most recent location in history.
         */
        navigateBack() {
            this.isExplicitNavigationBack = true;
            this.history.navigateBack();
        }
        /**
         * Creates a child router of the current router.
         *
         * @param container The [[Container]] to provide to the child router. Uses the current [[Router]]'s [[Container]] if unspecified.
         * @returns {Router} The new child Router.
         */
        createChild(container) {
            let childRouter = new Router(container || this.container.createChild(), this.history);
            childRouter.parent = this;
            return childRouter;
        }
        /**
         * Generates a URL fragment matching the specified route pattern.
         *
         * @param name The name of the route whose pattern should be used to generate the fragment.
         * @param params The route params to be used to populate the route pattern.
         * @param options If options.absolute = true, then absolute url will be generated; otherwise, it will be relative url.
         * @returns {string} A string containing the generated URL fragment.
         */
        generate(nameOrRoute, params = {}, options = {}) {
            // A child recognizer generates routes for potential child routes. Any potential child route is added
            // to the childRoute property of params for the childRouter to recognize. When generating routes, we
            // use the childRecognizer when childRoute params are available to generate a child router enabled route.
            let recognizer = 'childRoute' in params ? this._childRecognizer : this._recognizer;
            let hasRoute = recognizer.hasRoute(nameOrRoute);
            if (!hasRoute) {
                if (this.parent) {
                    return this.parent.generate(nameOrRoute, params, options);
                }
                throw new Error(`A route with name '${nameOrRoute}' could not be found. Check that \`name: '${nameOrRoute}'\` was specified in the route's config.`);
            }
            let path = recognizer.generate(nameOrRoute, params);
            let rootedPath = _createRootedPath(path, this.baseUrl, this.history._hasPushState, options.absolute);
            return options.absolute ? `${this.history.getAbsoluteRoot()}${rootedPath}` : rootedPath;
        }
        /**
         * Creates a [[NavModel]] for the specified route config.
         *
         * @param config The route config.
         */
        createNavModel(config) {
            let navModel = new NavModel(this, 'href' in config
                ? config.href
                // potential error when config.route is a string[] ?
                : config.route);
            navModel.title = config.title;
            navModel.order = config.nav;
            navModel.href = config.href;
            navModel.settings = config.settings;
            navModel.config = config;
            return navModel;
        }
        /**
         * Registers a new route with the router.
         *
         * @param config The [[RouteConfig]].
         * @param navModel The [[NavModel]] to use for the route. May be omitted for single-pattern routes.
         */
        addRoute(config, navModel) {
            if (Array.isArray(config.route)) {
                let routeConfigs = _ensureArrayWithSingleRoutePerConfig(config);
                // the following is wrong. todo: fix this after TS refactoring release
                routeConfigs.forEach(this.addRoute.bind(this));
                return;
            }
            validateRouteConfig(config);
            if (!('viewPorts' in config) && !config.navigationStrategy) {
                config.viewPorts = {
                    'default': {
                        moduleId: config.moduleId,
                        view: config.view
                    }
                };
            }
            if (!navModel) {
                navModel = this.createNavModel(config);
            }
            this.routes.push(config);
            let path = config.route;
            if (path.charAt(0) === '/') {
                path = path.substr(1);
            }
            let caseSensitive = config.caseSensitive === true;
            let state = this._recognizer.add({
                path: path,
                handler: config,
                caseSensitive: caseSensitive
            });
            if (path) {
                let settings = config.settings;
                delete config.settings;
                let withChild = JSON.parse(JSON.stringify(config));
                config.settings = settings;
                withChild.route = `${path}/*childRoute`;
                withChild.hasChildRouter = true;
                this._childRecognizer.add({
                    path: withChild.route,
                    handler: withChild,
                    caseSensitive: caseSensitive
                });
                withChild.navModel = navModel;
                withChild.settings = config.settings;
                withChild.navigationStrategy = config.navigationStrategy;
            }
            config.navModel = navModel;
            let navigation = this.navigation;
            if ((navModel.order || navModel.order === 0) && navigation.indexOf(navModel) === -1) {
                if ((!navModel.href && navModel.href !== '') && (state.types.dynamics || state.types.stars)) {
                    throw new Error('Invalid route config for "' + config.route + '" : dynamic routes must specify an "href:" to be included in the navigation model.');
                }
                if (typeof navModel.order !== 'number') {
                    navModel.order = ++this._fallbackOrder;
                }
                navigation.push(navModel);
                // this is a potential error / inconsistency between browsers
                //
                // MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
                // If compareFunction(a, b) returns 0, leave a and b unchanged with respect to each other,
                // but sorted with respect to all different elements.
                // Note: the ECMAscript standard does not guarantee this behaviour,
                // and thus not all browsers (e.g. Mozilla versions dating back to at least 2003) respect this.
                navigation.sort((a, b) => a.order - b.order);
            }
        }
        /**
         * Gets a value indicating whether or not this [[Router]] or one of its ancestors has a route registered with the specified name.
         *
         * @param name The name of the route to check.
         */
        hasRoute(name) {
            return !!(this._recognizer.hasRoute(name) || this.parent && this.parent.hasRoute(name));
        }
        /**
         * Gets a value indicating whether or not this [[Router]] has a route registered with the specified name.
         *
         * @param name The name of the route to check.
         */
        hasOwnRoute(name) {
            return this._recognizer.hasRoute(name);
        }
        /**
         * Register a handler to use when the incoming URL fragment doesn't match any registered routes.
         *
         * @param config The moduleId, or a function that selects the moduleId, or a [[RouteConfig]].
         */
        handleUnknownRoutes(config) {
            if (!config) {
                throw new Error('Invalid unknown route handler');
            }
            this.catchAllHandler = instruction => {
                return this
                    ._createRouteConfig(config, instruction)
                    .then(c => {
                    instruction.config = c;
                    return instruction;
                });
            };
        }
        /**
         * Updates the document title using the current navigation instruction.
         */
        updateTitle() {
            let parentRouter = this.parent;
            if (parentRouter) {
                return parentRouter.updateTitle();
            }
            let currentInstruction = this.currentInstruction;
            if (currentInstruction) {
                currentInstruction._updateTitle();
            }
            return undefined;
        }
        /**
         * Updates the navigation routes with hrefs relative to the current location.
         * Note: This method will likely move to a plugin in a future release.
         */
        refreshNavigation() {
            let nav = this.navigation;
            for (let i = 0, length = nav.length; i < length; i++) {
                let current = nav[i];
                if (!current.config.href) {
                    current.href = _createRootedPath(current.relativeHref, this.baseUrl, this.history._hasPushState);
                }
                else {
                    current.href = _normalizeAbsolutePath(current.config.href, this.history._hasPushState);
                }
            }
        }
        /**
         * Sets the default configuration for the view ports. This specifies how to
         *  populate a view port for which no module is specified. The default is
         *  an empty view/view-model pair.
         */
        useViewPortDefaults($viewPortDefaults) {
            // a workaround to have strong typings while not requiring to expose interface ViewPortInstruction
            let viewPortDefaults = $viewPortDefaults;
            for (let viewPortName in viewPortDefaults) {
                let viewPortConfig = viewPortDefaults[viewPortName];
                this.viewPortDefaults[viewPortName] = {
                    moduleId: viewPortConfig.moduleId
                };
            }
        }
        /**@internal */
        _refreshBaseUrl() {
            let parentRouter = this.parent;
            if (parentRouter) {
                this.baseUrl = generateBaseUrl(parentRouter, parentRouter.currentInstruction);
            }
        }
        /**@internal */
        _createNavigationInstruction(url = '', parentInstruction = null) {
            let fragment = url;
            let queryString = '';
            let queryIndex = url.indexOf('?');
            if (queryIndex !== -1) {
                fragment = url.substr(0, queryIndex);
                queryString = url.substr(queryIndex + 1);
            }
            let urlRecognizationResults = this._recognizer.recognize(url);
            if (!urlRecognizationResults || !urlRecognizationResults.length) {
                urlRecognizationResults = this._childRecognizer.recognize(url);
            }
            let instructionInit = {
                fragment,
                queryString,
                config: null,
                parentInstruction,
                previousInstruction: this.currentInstruction,
                router: this,
                options: {
                    compareQueryParams: this.options.compareQueryParams
                }
            };
            let result;
            if (urlRecognizationResults && urlRecognizationResults.length) {
                let first = urlRecognizationResults[0];
                let instruction = new NavigationInstruction(Object.assign({}, instructionInit, {
                    params: first.params,
                    queryParams: first.queryParams || urlRecognizationResults.queryParams,
                    config: first.config || first.handler
                }));
                if (typeof first.handler === 'function') {
                    result = evaluateNavigationStrategy(instruction, first.handler, first);
                }
                else if (first.handler && typeof first.handler.navigationStrategy === 'function') {
                    result = evaluateNavigationStrategy(instruction, first.handler.navigationStrategy, first.handler);
                }
                else {
                    result = Promise.resolve(instruction);
                }
            }
            else if (this.catchAllHandler) {
                let instruction = new NavigationInstruction(Object.assign({}, instructionInit, {
                    params: { path: fragment },
                    queryParams: urlRecognizationResults ? urlRecognizationResults.queryParams : {},
                    config: null // config will be created by the catchAllHandler
                }));
                result = evaluateNavigationStrategy(instruction, this.catchAllHandler);
            }
            else if (this.parent) {
                let router = this._parentCatchAllHandler(this.parent);
                if (router) {
                    let newParentInstruction = this._findParentInstructionFromRouter(router, parentInstruction);
                    let instruction = new NavigationInstruction(Object.assign({}, instructionInit, {
                        params: { path: fragment },
                        queryParams: urlRecognizationResults ? urlRecognizationResults.queryParams : {},
                        router: router,
                        parentInstruction: newParentInstruction,
                        parentCatchHandler: true,
                        config: null // config will be created by the chained parent catchAllHandler
                    }));
                    result = evaluateNavigationStrategy(instruction, router.catchAllHandler);
                }
            }
            if (result && parentInstruction) {
                this.baseUrl = generateBaseUrl(this.parent, parentInstruction);
            }
            return result || Promise.reject(new Error(`Route not found: ${url}`));
        }
        /**@internal */
        _findParentInstructionFromRouter(router, instruction) {
            if (instruction.router === router) {
                instruction.fragment = router.baseUrl; // need to change the fragment in case of a redirect instead of moduleId
                return instruction;
            }
            else if (instruction.parentInstruction) {
                return this._findParentInstructionFromRouter(router, instruction.parentInstruction);
            }
            return undefined;
        }
        /**@internal */
        _parentCatchAllHandler(router) {
            if (router.catchAllHandler) {
                return router;
            }
            else if (router.parent) {
                return this._parentCatchAllHandler(router.parent);
            }
            return false;
        }
        /**
         * @internal
         */
        _createRouteConfig(config, instruction) {
            return Promise
                .resolve(config)
                .then((c) => {
                if (typeof c === 'string') {
                    return { moduleId: c };
                }
                else if (typeof c === 'function') {
                    return c(instruction);
                }
                return c;
            })
                // typing here could be either RouteConfig or RedirectConfig
                // but temporarily treat both as RouteConfig
                // todo: improve typings precision
                .then((c) => typeof c === 'string' ? { moduleId: c } : c)
                .then((c) => {
                c.route = instruction.params.path;
                validateRouteConfig(c);
                if (!c.navModel) {
                    c.navModel = this.createNavModel(c);
                }
                return c;
            });
        }
    }
    /* @internal exported for unit testing */
    const generateBaseUrl = (router, instruction) => {
        return `${router.baseUrl || ''}${instruction.getBaseUrl() || ''}`;
    };
    /* @internal exported for unit testing */
    const validateRouteConfig = (config) => {
        if (typeof config !== 'object') {
            throw new Error('Invalid Route Config');
        }
        if (typeof config.route !== 'string') {
            let name = config.name || '(no name)';
            throw new Error('Invalid Route Config for "' + name + '": You must specify a "route:" pattern.');
        }
        if (!('redirect' in config || config.moduleId || config.navigationStrategy || config.viewPorts)) {
            throw new Error('Invalid Route Config for "' + config.route + '": You must specify a "moduleId:", "redirect:", "navigationStrategy:", or "viewPorts:".');
        }
    };
    /* @internal exported for unit testing */
    const evaluateNavigationStrategy = (instruction, evaluator, context) => {
        return Promise
            .resolve(evaluator.call(context, instruction))
            .then(() => {
            if (!('viewPorts' in instruction.config)) {
                instruction.config.viewPorts = {
                    'default': {
                        moduleId: instruction.config.moduleId
                    }
                };
            }
            return instruction;
        });
    };
  
    /**@internal exported for unit testing */
    const createNextFn = (instruction, steps) => {
        let index = -1;
        const next = function () {
            index++;
            if (index < steps.length) {
                let currentStep = steps[index];
                try {
                    return currentStep(instruction, next);
                }
                catch (e) {
                    return next.reject(e);
                }
            }
            else {
                return next.complete();
            }
        };
        next.complete = createCompletionHandler(next, "completed" /* Completed */);
        next.cancel = createCompletionHandler(next, "canceled" /* Canceled */);
        next.reject = createCompletionHandler(next, "rejected" /* Rejected */);
        return next;
    };
    /**@internal exported for unit testing */
    const createCompletionHandler = (next, status) => {
        return (output) => Promise
            .resolve({
            status,
            output,
            completed: status === "completed" /* Completed */
        });
    };
  
    /**
     * The class responsible for managing and processing the navigation pipeline.
     */
    class Pipeline {
        constructor() {
            /**
             * The pipeline steps. And steps added via addStep will be converted to a function
             * The actualy running functions with correct step contexts of this pipeline
             */
            this.steps = [];
        }
        /**
         * Adds a step to the pipeline.
         *
         * @param step The pipeline step.
         */
        addStep(step) {
            let run;
            if (typeof step === 'function') {
                run = step;
            }
            else if (typeof step.getSteps === 'function') {
                // getSteps is to enable support open slots
                // where devs can add multiple steps into the same slot name
                let steps = step.getSteps();
                for (let i = 0, l = steps.length; i < l; i++) {
                    this.addStep(steps[i]);
                }
                return this;
            }
            else {
                run = step.run.bind(step);
            }
            this.steps.push(run);
            return this;
        }
        /**
         * Runs the pipeline.
         *
         * @param instruction The navigation instruction to process.
         */
        run(instruction) {
            const nextFn = createNextFn(instruction, this.steps);
            return nextFn();
        }
    }
  
    /**
    * Determines if the provided object is a navigation command.
    * A navigation command is anything with a navigate method.
    *
    * @param obj The object to check.
    */
    function isNavigationCommand(obj) {
        return obj && typeof obj.navigate === 'function';
    }
    /**
    * Used during the activation lifecycle to cause a redirect.
    */
    class Redirect {
        /**
         * @param url The URL fragment to use as the navigation destination.
         * @param options The navigation options.
         */
        constructor(url, options = {}) {
            this.url = url;
            this.options = Object.assign({ trigger: true, replace: true }, options);
            this.shouldContinueProcessing = false;
        }
        /**
         * Called by the activation system to set the child router.
         *
         * @param router The router.
         */
        setRouter(router) {
            this.router = router;
        }
        /**
         * Called by the navigation pipeline to navigate.
         *
         * @param appRouter The router to be redirected.
         */
        navigate(appRouter) {
            let navigatingRouter = this.options.useAppRouter ? appRouter : (this.router || appRouter);
            navigatingRouter.navigate(this.url, this.options);
        }
    }
    /**
     * Used during the activation lifecycle to cause a redirect to a named route.
     */
    class RedirectToRoute {
        /**
         * @param route The name of the route.
         * @param params The parameters to be sent to the activation method.
         * @param options The options to use for navigation.
         */
        constructor(route, params = {}, options = {}) {
            this.route = route;
            this.params = params;
            this.options = Object.assign({ trigger: true, replace: true }, options);
            this.shouldContinueProcessing = false;
        }
        /**
         * Called by the activation system to set the child router.
         *
         * @param router The router.
         */
        setRouter(router) {
            this.router = router;
        }
        /**
         * Called by the navigation pipeline to navigate.
         *
         * @param appRouter The router to be redirected.
         */
        navigate(appRouter) {
            let navigatingRouter = this.options.useAppRouter ? appRouter : (this.router || appRouter);
            navigatingRouter.navigateToRoute(this.route, this.params, this.options);
        }
    }
  
    /**
     * @internal exported for unit testing
     */
    function _buildNavigationPlan(instruction, forceLifecycleMinimum) {
        let config = instruction.config;
        if ('redirect' in config) {
            return buildRedirectPlan(instruction);
        }
        const prevInstruction = instruction.previousInstruction;
        const defaultViewPortConfigs = instruction.router.viewPortDefaults;
        if (prevInstruction) {
            return buildTransitionPlans(instruction, prevInstruction, defaultViewPortConfigs, forceLifecycleMinimum);
        }
        // first navigation, only need to prepare a few information for each viewport plan
        const viewPortPlans = {};
        let viewPortConfigs = config.viewPorts;
        for (let viewPortName in viewPortConfigs) {
            let viewPortConfig = viewPortConfigs[viewPortName];
            if (viewPortConfig.moduleId === null && viewPortName in defaultViewPortConfigs) {
                viewPortConfig = defaultViewPortConfigs[viewPortName];
            }
            viewPortPlans[viewPortName] = {
                name: viewPortName,
                strategy: "replace" /* Replace */,
                config: viewPortConfig
            };
        }
        return Promise.resolve(viewPortPlans);
    }
    /**
     * Build redirect plan based on config of a navigation instruction
     * @internal exported for unit testing
     */
    const buildRedirectPlan = (instruction) => {
        const config = instruction.config;
        const router = instruction.router;
        return router
            ._createNavigationInstruction(config.redirect)
            .then(redirectInstruction => {
            const params = {};
            const originalInstructionParams = instruction.params;
            const redirectInstructionParams = redirectInstruction.params;
            for (let key in redirectInstructionParams) {
                // If the param on the redirect points to another param, e.g. { route: first/:this, redirect: second/:this }
                let val = redirectInstructionParams[key];
                if (typeof val === 'string' && val[0] === ':') {
                    val = val.slice(1);
                    // And if that param is found on the original instruction then use it
                    if (val in originalInstructionParams) {
                        params[key] = originalInstructionParams[val];
                    }
                }
                else {
                    params[key] = redirectInstructionParams[key];
                }
            }
            let redirectLocation = router.generate(redirectInstruction.config, params, instruction.options);
            // Special handling for child routes
            for (let key in originalInstructionParams) {
                redirectLocation = redirectLocation.replace(`:${key}`, originalInstructionParams[key]);
            }
            let queryString = instruction.queryString;
            if (queryString) {
                redirectLocation += '?' + queryString;
            }
            return Promise.resolve(new Redirect(redirectLocation));
        });
    };
    /**
     * @param viewPortPlans the Plan record that holds information about built plans
     * @internal exported for unit testing
     */
    const buildTransitionPlans = (currentInstruction, previousInstruction, defaultViewPortConfigs, forceLifecycleMinimum) => {
        let viewPortPlans = {};
        let newInstructionConfig = currentInstruction.config;
        let hasNewParams = hasDifferentParameterValues(previousInstruction, currentInstruction);
        let pending = [];
        let previousViewPortInstructions = previousInstruction.viewPortInstructions;
        for (let viewPortName in previousViewPortInstructions) {
            const prevViewPortInstruction = previousViewPortInstructions[viewPortName];
            const prevViewPortComponent = prevViewPortInstruction.component;
            const newInstructionViewPortConfigs = newInstructionConfig.viewPorts;
            // if this is invoked on a viewport without any changes, based on new url,
            // newViewPortConfig will be the existing viewport instruction
            let nextViewPortConfig = viewPortName in newInstructionViewPortConfigs
                ? newInstructionViewPortConfigs[viewPortName]
                : prevViewPortInstruction;
            if (nextViewPortConfig.moduleId === null && viewPortName in defaultViewPortConfigs) {
                nextViewPortConfig = defaultViewPortConfigs[viewPortName];
            }
            const viewPortActivationStrategy = determineActivationStrategy(currentInstruction, prevViewPortInstruction, nextViewPortConfig, hasNewParams, forceLifecycleMinimum);
            const viewPortPlan = viewPortPlans[viewPortName] = {
                name: viewPortName,
                // ViewPortInstruction can quack like a RouteConfig
                config: nextViewPortConfig,
                prevComponent: prevViewPortComponent,
                prevModuleId: prevViewPortInstruction.moduleId,
                strategy: viewPortActivationStrategy
            };
            // recursively build nav plans for all existing child routers/viewports of this viewport
            // this is possible because existing child viewports and routers already have necessary information
            // to process the wildcard path from parent instruction
            if (viewPortActivationStrategy !== "replace" /* Replace */ && prevViewPortInstruction.childRouter) {
                const path = currentInstruction.getWildcardPath();
                const task = prevViewPortInstruction
                    .childRouter
                    ._createNavigationInstruction(path, currentInstruction)
                    .then((childInstruction) => {
                    viewPortPlan.childNavigationInstruction = childInstruction;
                    return _buildNavigationPlan(childInstruction, 
                    // is it safe to assume viewPortPlan has not been changed from previous assignment?
                    // if so, can just use local variable viewPortPlanStrategy
                    // there could be user code modifying viewport plan during _createNavigationInstruction?
                    viewPortPlan.strategy === "invoke-lifecycle" /* InvokeLifecycle */)
                        .then(childPlan => {
                        if (childPlan instanceof Redirect) {
                            return Promise.reject(childPlan);
                        }
                        childInstruction.plan = childPlan;
                        // for bluebird ?
                        return null;
                    });
                });
                pending.push(task);
            }
        }
        return Promise.all(pending).then(() => viewPortPlans);
    };
    /**
     * @param newViewPortConfig if this is invoked on a viewport without any changes, based on new url, newViewPortConfig will be the existing viewport instruction
     * @internal exported for unit testing
     */
    const determineActivationStrategy = (currentNavInstruction, prevViewPortInstruction, newViewPortConfig, 
    // indicates whether there is difference between old and new url params
    hasNewParams, forceLifecycleMinimum) => {
        let newInstructionConfig = currentNavInstruction.config;
        let prevViewPortViewModel = prevViewPortInstruction.component.viewModel;
        let viewPortPlanStrategy;
        if (prevViewPortInstruction.moduleId !== newViewPortConfig.moduleId) {
            viewPortPlanStrategy = "replace" /* Replace */;
        }
        else if ('determineActivationStrategy' in prevViewPortViewModel) {
            viewPortPlanStrategy = prevViewPortViewModel.determineActivationStrategy(...currentNavInstruction.lifecycleArgs);
        }
        else if (newInstructionConfig.activationStrategy) {
            viewPortPlanStrategy = newInstructionConfig.activationStrategy;
        }
        else if (hasNewParams || forceLifecycleMinimum) {
            viewPortPlanStrategy = "invoke-lifecycle" /* InvokeLifecycle */;
        }
        else {
            viewPortPlanStrategy = "no-change" /* NoChange */;
        }
        return viewPortPlanStrategy;
    };
    /**@internal exported for unit testing */
    const hasDifferentParameterValues = (prev, next) => {
        let prevParams = prev.params;
        let nextParams = next.params;
        let nextWildCardName = next.config.hasChildRouter ? next.getWildCardName() : null;
        for (let key in nextParams) {
            if (key === nextWildCardName) {
                continue;
            }
            if (prevParams[key] !== nextParams[key]) {
                return true;
            }
        }
        for (let key in prevParams) {
            if (key === nextWildCardName) {
                continue;
            }
            if (prevParams[key] !== nextParams[key]) {
                return true;
            }
        }
        if (!next.options.compareQueryParams) {
            return false;
        }
        let prevQueryParams = prev.queryParams;
        let nextQueryParams = next.queryParams;
        for (let key in nextQueryParams) {
            if (prevQueryParams[key] !== nextQueryParams[key]) {
                return true;
            }
        }
        for (let key in prevQueryParams) {
            if (prevQueryParams[key] !== nextQueryParams[key]) {
                return true;
            }
        }
        return false;
    };
  
    /**
     * Transform a navigation instruction into viewport plan record object,
     * or a redirect request if user viewmodel demands
     */
    class BuildNavigationPlanStep {
        run(navigationInstruction, next) {
            return _buildNavigationPlan(navigationInstruction)
                .then(plan => {
                if (plan instanceof Redirect) {
                    return next.cancel(plan);
                }
                navigationInstruction.plan = plan;
                return next();
            })
                .catch(next.cancel);
        }
    }
  
    /**
     * @internal Exported for unit testing
     */
    const loadNewRoute = (routeLoader, navigationInstruction) => {
        let loadingPlans = determineLoadingPlans(navigationInstruction);
        let loadPromises = loadingPlans.map((loadingPlan) => loadRoute(routeLoader, loadingPlan.navigationInstruction, loadingPlan.viewPortPlan));
        return Promise.all(loadPromises);
    };
    /**
     * @internal Exported for unit testing
     */
    const determineLoadingPlans = (navigationInstruction, loadingPlans = []) => {
        let viewPortPlans = navigationInstruction.plan;
        for (let viewPortName in viewPortPlans) {
            let viewPortPlan = viewPortPlans[viewPortName];
            let childNavInstruction = viewPortPlan.childNavigationInstruction;
            if (viewPortPlan.strategy === "replace" /* Replace */) {
                loadingPlans.push({ viewPortPlan, navigationInstruction });
                if (childNavInstruction) {
                    determineLoadingPlans(childNavInstruction, loadingPlans);
                }
            }
            else {
                let viewPortInstruction = navigationInstruction.addViewPortInstruction({
                    name: viewPortName,
                    strategy: viewPortPlan.strategy,
                    moduleId: viewPortPlan.prevModuleId,
                    component: viewPortPlan.prevComponent
                });
                if (childNavInstruction) {
                    viewPortInstruction.childNavigationInstruction = childNavInstruction;
                    determineLoadingPlans(childNavInstruction, loadingPlans);
                }
            }
        }
        return loadingPlans;
    };
    /**
     * @internal Exported for unit testing
     */
    const loadRoute = (routeLoader, navigationInstruction, viewPortPlan) => {
        let planConfig = viewPortPlan.config;
        let moduleId = planConfig ? planConfig.moduleId : null;
        return loadComponent(routeLoader, navigationInstruction, planConfig)
            .then((component) => {
            let viewPortInstruction = navigationInstruction.addViewPortInstruction({
                name: viewPortPlan.name,
                strategy: viewPortPlan.strategy,
                moduleId: moduleId,
                component: component
            });
            let childRouter = component.childRouter;
            if (childRouter) {
                let path = navigationInstruction.getWildcardPath();
                return childRouter
                    ._createNavigationInstruction(path, navigationInstruction)
                    .then((childInstruction) => {
                    viewPortPlan.childNavigationInstruction = childInstruction;
                    return _buildNavigationPlan(childInstruction)
                        .then((childPlan) => {
                        if (childPlan instanceof Redirect) {
                            return Promise.reject(childPlan);
                        }
                        childInstruction.plan = childPlan;
                        viewPortInstruction.childNavigationInstruction = childInstruction;
                        return loadNewRoute(routeLoader, childInstruction);
                    });
                });
            }
            // ts complains without this, though they are same
            return void 0;
        });
    };
    /**
     * Load a routed-component based on navigation instruction and route config
     * @internal exported for unit testing only
     */
    const loadComponent = (routeLoader, navigationInstruction, config) => {
        let router = navigationInstruction.router;
        let lifecycleArgs = navigationInstruction.lifecycleArgs;
        return Promise.resolve()
            .then(() => routeLoader.loadRoute(router, config, navigationInstruction))
            .then(
        /**
         * @param component an object carrying information about loaded route
         * typically contains information about view model, childContainer, view and router
         */
        (component) => {
            let { viewModel, childContainer } = component;
            component.router = router;
            component.config = config;
            if ('configureRouter' in viewModel) {
                let childRouter = childContainer.getChildRouter();
                component.childRouter = childRouter;
                return childRouter
                    .configure(c => viewModel.configureRouter(c, childRouter, lifecycleArgs[0], lifecycleArgs[1], lifecycleArgs[2]))
                    .then(() => component);
            }
            return component;
        });
    };
  
    /**
     * Abstract class that is responsible for loading view / view model from a route config
     * The default implementation can be found in `aurelia-templating-router`
     */
    class RouteLoader {
        /**
         * Load a route config based on its viewmodel / view configuration
         */
        // return typing: return typings used to be never
        // as it was a throw. Changing it to Promise<any> should not cause any issues
        loadRoute(router, config, navigationInstruction) {
            throw new Error('Route loaders must implement "loadRoute(router, config, navigationInstruction)".');
        }
    }
  
    /**
     * A pipeline step responsible for loading a route config of a navigation instruction
     */
    class LoadRouteStep {
        /**@internal */
        static inject() { return [RouteLoader]; }
        constructor(routeLoader) {
            this.routeLoader = routeLoader;
        }
        /**
         * Run the internal to load route config of a navigation instruction to prepare for next steps in the pipeline
         */
        run(navigationInstruction, next) {
            return loadNewRoute(this.routeLoader, navigationInstruction)
                .then(next, next.cancel);
        }
    }
  
    /**
     * A pipeline step for instructing a piepline to commit changes on a navigation instruction
     */
    class CommitChangesStep {
        run(navigationInstruction, next) {
            return navigationInstruction
                ._commitChanges(/*wait to swap?*/ true)
                .then(() => {
                navigationInstruction._updateTitle();
                return next();
            });
        }
    }
  
    /**
     * An optional interface describing the available activation strategies.
     * @internal Used internally.
     */
    var InternalActivationStrategy;
    (function (InternalActivationStrategy) {
        /**
         * Reuse the existing view model, without invoking Router lifecycle hooks.
         */
        InternalActivationStrategy["NoChange"] = "no-change";
        /**
         * Reuse the existing view model, invoking Router lifecycle hooks.
         */
        InternalActivationStrategy["InvokeLifecycle"] = "invoke-lifecycle";
        /**
         * Replace the existing view model, invoking Router lifecycle hooks.
         */
        InternalActivationStrategy["Replace"] = "replace";
    })(InternalActivationStrategy || (InternalActivationStrategy = {}));
    /**
     * The strategy to use when activating modules during navigation.
     */
    // kept for compat reason
    const activationStrategy = {
        noChange: "no-change" /* NoChange */,
        invokeLifecycle: "invoke-lifecycle" /* InvokeLifecycle */,
        replace: "replace" /* Replace */
    };
  
    /**
     * Recursively find list of deactivate-able view models
     * and invoke the either 'canDeactivate' or 'deactivate' on each
     * @internal exported for unit testing
     */
    const processDeactivatable = (navigationInstruction, callbackName, next, ignoreResult) => {
        let plan = navigationInstruction.plan;
        let infos = findDeactivatable(plan, callbackName);
        let i = infos.length; // query from inside out
        function inspect(val) {
            if (ignoreResult || shouldContinue(val)) {
                return iterate();
            }
            return next.cancel(val);
        }
        function iterate() {
            if (i--) {
                try {
                    let viewModel = infos[i];
                    let result = viewModel[callbackName](navigationInstruction);
                    return processPotential(result, inspect, next.cancel);
                }
                catch (error) {
                    return next.cancel(error);
                }
            }
            navigationInstruction.router.couldDeactivate = true;
            return next();
        }
        return iterate();
    };
    /**
     * Recursively find and returns a list of deactivate-able view models
     * @internal exported for unit testing
     */
    const findDeactivatable = (plan, callbackName, list = []) => {
        for (let viewPortName in plan) {
            let viewPortPlan = plan[viewPortName];
            let prevComponent = viewPortPlan.prevComponent;
            if ((viewPortPlan.strategy === activationStrategy.invokeLifecycle || viewPortPlan.strategy === activationStrategy.replace)
                && prevComponent) {
                let viewModel = prevComponent.viewModel;
                if (callbackName in viewModel) {
                    list.push(viewModel);
                }
            }
            if (viewPortPlan.strategy === activationStrategy.replace && prevComponent) {
                addPreviousDeactivatable(prevComponent, callbackName, list);
            }
            else if (viewPortPlan.childNavigationInstruction) {
                findDeactivatable(viewPortPlan.childNavigationInstruction.plan, callbackName, list);
            }
        }
        return list;
    };
    /**
     * @internal exported for unit testing
     */
    const addPreviousDeactivatable = (component, callbackName, list) => {
        let childRouter = component.childRouter;
        if (childRouter && childRouter.currentInstruction) {
            let viewPortInstructions = childRouter.currentInstruction.viewPortInstructions;
            for (let viewPortName in viewPortInstructions) {
                let viewPortInstruction = viewPortInstructions[viewPortName];
                let prevComponent = viewPortInstruction.component;
                let prevViewModel = prevComponent.viewModel;
                if (callbackName in prevViewModel) {
                    list.push(prevViewModel);
                }
                addPreviousDeactivatable(prevComponent, callbackName, list);
            }
        }
    };
    /**
     * @internal exported for unit testing
     */
    const processActivatable = (navigationInstruction, callbackName, next, ignoreResult) => {
        let infos = findActivatable(navigationInstruction, callbackName);
        let length = infos.length;
        let i = -1; // query from top down
        function inspect(val, router) {
            if (ignoreResult || shouldContinue(val, router)) {
                return iterate();
            }
            return next.cancel(val);
        }
        function iterate() {
            i++;
            if (i < length) {
                try {
                    let current = infos[i];
                    let result = current.viewModel[callbackName](...current.lifecycleArgs);
                    return processPotential(result, (val) => inspect(val, current.router), next.cancel);
                }
                catch (error) {
                    return next.cancel(error);
                }
            }
            return next();
        }
        return iterate();
    };
    /**
     * Find list of activatable view model and add to list (3rd parameter)
     * @internal exported for unit testing
     */
    const findActivatable = (navigationInstruction, callbackName, list = [], router) => {
        let plan = navigationInstruction.plan;
        Object
            .keys(plan)
            .forEach((viewPortName) => {
            let viewPortPlan = plan[viewPortName];
            let viewPortInstruction = navigationInstruction.viewPortInstructions[viewPortName];
            let viewPortComponent = viewPortInstruction.component;
            let viewModel = viewPortComponent.viewModel;
            if ((viewPortPlan.strategy === activationStrategy.invokeLifecycle
                || viewPortPlan.strategy === activationStrategy.replace)
                && callbackName in viewModel) {
                list.push({
                    viewModel,
                    lifecycleArgs: viewPortInstruction.lifecycleArgs,
                    router
                });
            }
            let childNavInstruction = viewPortPlan.childNavigationInstruction;
            if (childNavInstruction) {
                findActivatable(childNavInstruction, callbackName, list, viewPortComponent.childRouter || router);
            }
        });
        return list;
    };
    const shouldContinue = (output, router) => {
        if (output instanceof Error) {
            return false;
        }
        if (isNavigationCommand(output)) {
            if (typeof output.setRouter === 'function') {
                output.setRouter(router);
            }
            return !!output.shouldContinueProcessing;
        }
        if (output === undefined) {
            return true;
        }
        return output;
    };
    /**
     * wraps a subscription, allowing unsubscribe calls even if
     * the first value comes synchronously
     */
    class SafeSubscription {
        constructor(subscriptionFunc) {
            this._subscribed = true;
            this._subscription = subscriptionFunc(this);
            if (!this._subscribed) {
                this.unsubscribe();
            }
        }
        get subscribed() {
            return this._subscribed;
        }
        unsubscribe() {
            if (this._subscribed && this._subscription) {
                this._subscription.unsubscribe();
            }
            this._subscribed = false;
        }
    }
    /**
     * A function to process return value from `activate`/`canActivate` steps
     * Supports observable/promise
     *
     * For observable, resolve at first next() or on complete()
     */
    const processPotential = (obj, resolve, reject) => {
        // if promise like
        if (obj && typeof obj.then === 'function') {
            return Promise.resolve(obj).then(resolve).catch(reject);
        }
        // if observable
        if (obj && typeof obj.subscribe === 'function') {
            let obs = obj;
            return new SafeSubscription(sub => obs.subscribe({
                next() {
                    if (sub.subscribed) {
                        sub.unsubscribe();
                        resolve(obj);
                    }
                },
                error(error) {
                    if (sub.subscribed) {
                        sub.unsubscribe();
                        reject(error);
                    }
                },
                complete() {
                    if (sub.subscribed) {
                        sub.unsubscribe();
                        resolve(obj);
                    }
                }
            }));
        }
        // else just resolve
        try {
            return resolve(obj);
        }
        catch (error) {
            return reject(error);
        }
    };
  
    /**
     * A pipeline step responsible for finding and activating method `canDeactivate` on a view model of a route
     */
    class CanDeactivatePreviousStep {
        run(navigationInstruction, next) {
            return processDeactivatable(navigationInstruction, 'canDeactivate', next);
        }
    }
    /**
     * A pipeline step responsible for finding and activating method `canActivate` on a view model of a route
     */
    class CanActivateNextStep {
        run(navigationInstruction, next) {
            return processActivatable(navigationInstruction, 'canActivate', next);
        }
    }
    /**
     * A pipeline step responsible for finding and activating method `deactivate` on a view model of a route
     */
    class DeactivatePreviousStep {
        run(navigationInstruction, next) {
            return processDeactivatable(navigationInstruction, 'deactivate', next, true);
        }
    }
    /**
     * A pipeline step responsible for finding and activating method `activate` on a view model of a route
     */
    class ActivateNextStep {
        run(navigationInstruction, next) {
            return processActivatable(navigationInstruction, 'activate', next, true);
        }
    }
  
    /**
     * A multi-slots Pipeline Placeholder Step for hooking into a pipeline execution
     */
    class PipelineSlot {
        constructor(container, name, alias) {
            this.steps = [];
            this.container = container;
            this.slotName = name;
            this.slotAlias = alias;
        }
        getSteps() {
            return this.steps.map(x => this.container.get(x));
        }
    }
    /**
     * Class responsible for creating the navigation pipeline.
     */
    class PipelineProvider {
        /**@internal */
        static inject() { return [Container]; }
        constructor(container) {
            this.container = container;
            this.steps = [
                BuildNavigationPlanStep,
                CanDeactivatePreviousStep,
                LoadRouteStep,
                createPipelineSlot(container, "authorize" /* Authorize */),
                CanActivateNextStep,
                createPipelineSlot(container, "preActivate" /* PreActivate */, 'modelbind'),
                // NOTE: app state changes start below - point of no return
                DeactivatePreviousStep,
                ActivateNextStep,
                createPipelineSlot(container, "preRender" /* PreRender */, 'precommit'),
                CommitChangesStep,
                createPipelineSlot(container, "postRender" /* PostRender */, 'postcomplete')
            ];
        }
        /**
         * Create the navigation pipeline.
         */
        createPipeline(useCanDeactivateStep = true) {
            let pipeline = new Pipeline();
            this.steps.forEach(step => {
                if (useCanDeactivateStep || step !== CanDeactivatePreviousStep) {
                    pipeline.addStep(this.container.get(step));
                }
            });
            return pipeline;
        }
        /**@internal */
        _findStep(name) {
            // Steps that are not PipelineSlots are constructor functions, and they will automatically fail. Probably.
            return this.steps.find(x => x.slotName === name || x.slotAlias === name);
        }
        /**
         * Adds a step into the pipeline at a known slot location.
         */
        addStep(name, step) {
            let found = this._findStep(name);
            if (found) {
                let slotSteps = found.steps;
                // prevent duplicates
                if (!slotSteps.includes(step)) {
                    slotSteps.push(step);
                }
            }
            else {
                throw new Error(`Invalid pipeline slot name: ${name}.`);
            }
        }
        /**
         * Removes a step from a slot in the pipeline
         */
        removeStep(name, step) {
            let slot = this._findStep(name);
            if (slot) {
                let slotSteps = slot.steps;
                slotSteps.splice(slotSteps.indexOf(step), 1);
            }
        }
        /**
         * Clears all steps from a slot in the pipeline
         * @internal
         */
        _clearSteps(name = '') {
            let slot = this._findStep(name);
            if (slot) {
                slot.steps = [];
            }
        }
        /**
         * Resets all pipeline slots
         */
        reset() {
            this._clearSteps("authorize" /* Authorize */);
            this._clearSteps("preActivate" /* PreActivate */);
            this._clearSteps("preRender" /* PreRender */);
            this._clearSteps("postRender" /* PostRender */);
        }
    }
    /**@internal */
    const createPipelineSlot = (container, name, alias) => {
        return new PipelineSlot(container, name, alias);
    };
  
    const logger$4 = getLogger('app-router');
    /**
     * The main application router.
     */
    class AppRouter extends Router {
        /**@internal */
        static inject() { return [Container, History, PipelineProvider, EventAggregator]; }
        constructor(container, history, pipelineProvider, events) {
            super(container, history); // Note the super will call reset internally.
            this.pipelineProvider = pipelineProvider;
            this.events = events;
        }
        /**
         * Fully resets the router's internal state. Primarily used internally by the framework when multiple calls to setRoot are made.
         * Use with caution (actually, avoid using this). Do not use this to simply change your navigation model.
         */
        reset() {
            super.reset();
            this.maxInstructionCount = 10;
            if (!this._queue) {
                this._queue = [];
            }
            else {
                this._queue.length = 0;
            }
        }
        /**
         * Loads the specified URL.
         *
         * @param url The URL fragment to load.
         */
        loadUrl(url) {
            return this
                ._createNavigationInstruction(url)
                .then(instruction => this._queueInstruction(instruction))
                .catch(error => {
                logger$4.error(error);
                restorePreviousLocation(this);
            });
        }
        /**
         * Registers a viewPort to be used as a rendering target for activated routes.
         *
         * @param viewPort The viewPort. This is typically a <router-view/> element in Aurelia default impl
         * @param name The name of the viewPort. 'default' if unspecified.
         */
        registerViewPort(viewPort, name) {
            // having strong typing without changing public API
            const $viewPort = viewPort;
            super.registerViewPort($viewPort, name);
            // beside adding viewport to the registry of this instance
            // AppRouter also configure routing/history to start routing functionality
            // There are situation where there are more than 1 <router-view/> element at root view
            // in that case, still only activate once via the following guard
            if (!this.isActive) {
                const viewModel = this._findViewModel($viewPort);
                if ('configureRouter' in viewModel) {
                    // If there are more than one <router-view/> element at root view
                    // use this flag to guard against configure method being invoked multiple times
                    // this flag is set inside method configure
                    if (!this.isConfigured) {
                        // replace the real resolve with a noop to guarantee that any action in base class Router
                        // won't resolve the configurePromise prematurely
                        const resolveConfiguredPromise = this._resolveConfiguredPromise;
                        this._resolveConfiguredPromise = () => { };
                        return this
                            .configure(config => Promise
                            .resolve(viewModel.configureRouter(config, this))
                            // an issue with configure interface. Should be fixed there
                            // todo: fix this via configure interface in router
                            .then(() => config))
                            .then(() => {
                            this.activate();
                            resolveConfiguredPromise();
                        });
                    }
                }
                else {
                    this.activate();
                }
            }
            // when a viewport is added dynamically to a root view that is already activated
            // just process the navigation instruction
            else {
                this._dequeueInstruction();
            }
            return Promise.resolve();
        }
        /**
         * Activates the router. This instructs the router to begin listening for history changes and processing instructions.
         *
         * @params options The set of options to activate the router with.
         */
        activate(options) {
            if (this.isActive) {
                return;
            }
            this.isActive = true;
            // route handler property is responsible for handling url change
            // the interface of aurelia-history isn't clear on this perspective
            this.options = Object.assign({ routeHandler: this.loadUrl.bind(this) }, this.options, options);
            this.history.activate(this.options);
            this._dequeueInstruction();
        }
        /**
         * Deactivates the router.
         */
        deactivate() {
            this.isActive = false;
            this.history.deactivate();
        }
        /**@internal */
        _queueInstruction(instruction) {
            return new Promise((resolve) => {
                instruction.resolve = resolve;
                this._queue.unshift(instruction);
                this._dequeueInstruction();
            });
        }
        /**@internal */
        _dequeueInstruction(instructionCount = 0) {
            return Promise.resolve().then(() => {
                if (this.isNavigating && !instructionCount) {
                    // ts complains about inconsistent returns without void 0
                    return void 0;
                }
                let instruction = this._queue.shift();
                this._queue.length = 0;
                if (!instruction) {
                    // ts complains about inconsistent returns without void 0
                    return void 0;
                }
                this.isNavigating = true;
                let navtracker = this.history.getState('NavigationTracker');
                let currentNavTracker = this.currentNavigationTracker;
                if (!navtracker && !currentNavTracker) {
                    this.isNavigatingFirst = true;
                    this.isNavigatingNew = true;
                }
                else if (!navtracker) {
                    this.isNavigatingNew = true;
                }
                else if (!currentNavTracker) {
                    this.isNavigatingRefresh = true;
                }
                else if (currentNavTracker < navtracker) {
                    this.isNavigatingForward = true;
                }
                else if (currentNavTracker > navtracker) {
                    this.isNavigatingBack = true;
                }
                if (!navtracker) {
                    navtracker = Date.now();
                    this.history.setState('NavigationTracker', navtracker);
                }
                this.currentNavigationTracker = navtracker;
                instruction.previousInstruction = this.currentInstruction;
                let maxInstructionCount = this.maxInstructionCount;
                if (!instructionCount) {
                    this.events.publish("router:navigation:processing" /* Processing */, { instruction });
                }
                else if (instructionCount === maxInstructionCount - 1) {
                    logger$4.error(`${instructionCount + 1} navigation instructions have been attempted without success. Restoring last known good location.`);
                    restorePreviousLocation(this);
                    return this._dequeueInstruction(instructionCount + 1);
                }
                else if (instructionCount > maxInstructionCount) {
                    throw new Error('Maximum navigation attempts exceeded. Giving up.');
                }
                let pipeline = this.pipelineProvider.createPipeline(!this.couldDeactivate);
                return pipeline
                    .run(instruction)
                    .then(result => processResult(instruction, result, instructionCount, this))
                    .catch(error => {
                    return { output: error instanceof Error ? error : new Error(error) };
                })
                    .then(result => resolveInstruction(instruction, result, !!instructionCount, this));
            });
        }
        /**@internal */
        _findViewModel(viewPort) {
            if (this.container.viewModel) {
                return this.container.viewModel;
            }
            if (viewPort.container) {
                let container = viewPort.container;
                while (container) {
                    if (container.viewModel) {
                        this.container.viewModel = container.viewModel;
                        return container.viewModel;
                    }
                    container = container.parent;
                }
            }
            return undefined;
        }
    }
    const processResult = (instruction, result, instructionCount, router) => {
        if (!(result && 'completed' in result && 'output' in result)) {
            result = result || {};
            result.output = new Error(`Expected router pipeline to return a navigation result, but got [${JSON.stringify(result)}] instead.`);
        }
        let finalResult = null;
        let navigationCommandResult = null;
        if (isNavigationCommand(result.output)) {
            navigationCommandResult = result.output.navigate(router);
        }
        else {
            finalResult = result;
            if (!result.completed) {
                if (result.output instanceof Error) {
                    logger$4.error(result.output.toString());
                }
                restorePreviousLocation(router);
            }
        }
        return Promise.resolve(navigationCommandResult)
            .then(_ => router._dequeueInstruction(instructionCount + 1))
            .then(innerResult => finalResult || innerResult || result);
    };
    const resolveInstruction = (instruction, result, isInnerInstruction, router) => {
        instruction.resolve(result);
        let eventAggregator = router.events;
        let eventArgs = { instruction, result };
        if (!isInnerInstruction) {
            router.isNavigating = false;
            router.isExplicitNavigation = false;
            router.isExplicitNavigationBack = false;
            router.isNavigatingFirst = false;
            router.isNavigatingNew = false;
            router.isNavigatingRefresh = false;
            router.isNavigatingForward = false;
            router.isNavigatingBack = false;
            router.couldDeactivate = false;
            let eventName;
            if (result.output instanceof Error) {
                eventName = "router:navigation:error" /* Error */;
            }
            else if (!result.completed) {
                eventName = "router:navigation:canceled" /* Canceled */;
            }
            else {
                let queryString = instruction.queryString ? ('?' + instruction.queryString) : '';
                router.history.previousLocation = instruction.fragment + queryString;
                eventName = "router:navigation:success" /* Success */;
            }
            eventAggregator.publish(eventName, eventArgs);
            eventAggregator.publish("router:navigation:complete" /* Complete */, eventArgs);
        }
        else {
            eventAggregator.publish("router:navigation:child:complete" /* ChildComplete */, eventArgs);
        }
        return result;
    };
    const restorePreviousLocation = (router) => {
        let previousLocation = router.history.previousLocation;
        if (previousLocation) {
            router.navigate(previousLocation, { trigger: false, replace: true });
        }
        else if (router.fallbackRoute) {
            router.navigate(router.fallbackRoute, { trigger: true, replace: true });
        }
        else {
            logger$4.error('Router navigation failed, and no previous location or fallbackRoute could be restored.');
        }
    };
  
    /**
    * The status of a Pipeline.
    */
  
    (function (PipelineStatus) {
        PipelineStatus["Completed"] = "completed";
        PipelineStatus["Canceled"] = "canceled";
        PipelineStatus["Rejected"] = "rejected";
        PipelineStatus["Running"] = "running";
    })(exports.PipelineStatus || (exports.PipelineStatus = {}));
  
    /**
     * A list of known router events used by the Aurelia router
     * to signal the pipeline has come to a certain state
     */
    // const enum is preserved in tsconfig
    var RouterEvent;
    (function (RouterEvent) {
        RouterEvent["Processing"] = "router:navigation:processing";
        RouterEvent["Error"] = "router:navigation:error";
        RouterEvent["Canceled"] = "router:navigation:canceled";
        RouterEvent["Complete"] = "router:navigation:complete";
        RouterEvent["Success"] = "router:navigation:success";
        RouterEvent["ChildComplete"] = "router:navigation:child:complete";
    })(RouterEvent || (RouterEvent = {}));
  
    /**
     * Available pipeline slot names to insert interceptor into router pipeline
     */
    // const enum is preserved in tsconfig
    var PipelineSlotName;
    (function (PipelineSlotName) {
        /**
         * Authorization slot. Invoked early in the pipeline,
         * before `canActivate` hook of incoming route
         */
        PipelineSlotName["Authorize"] = "authorize";
        /**
         * Pre-activation slot. Invoked early in the pipeline,
         * Invoked timing:
         *   - after Authorization slot
         *   - after canActivate hook on new view model
         *   - before deactivate hook on old view model
         *   - before activate hook on new view model
         */
        PipelineSlotName["PreActivate"] = "preActivate";
        /**
         * Pre-render slot. Invoked later in the pipeline
         * Invokcation timing:
         *   - after activate hook on new view model
         *   - before commit step on new navigation instruction
         */
        PipelineSlotName["PreRender"] = "preRender";
        /**
         * Post-render slot. Invoked last in the pipeline
         */
        PipelineSlotName["PostRender"] = "postRender";
    })(PipelineSlotName || (PipelineSlotName = {}));
  
    class EmptyLayoutViewModel {
    }
    /**
     * Implementation of Aurelia Router ViewPort. Responsible for loading route, composing and swapping routes views
     */
    class RouterView {
        constructor(element, container, viewSlot, router, viewLocator, compositionTransaction, compositionEngine) {
            this.element = element;
            this.container = container;
            this.viewSlot = viewSlot;
            this.router = router;
            this.viewLocator = viewLocator;
            this.compositionTransaction = compositionTransaction;
            this.compositionEngine = compositionEngine;
            // add this <router-view/> to router view ports lookup based on name attribute
            // when this router is the root router-view
            // also trigger AppRouter registerViewPort extra flow
            this.router.registerViewPort(this, this.element.getAttribute('name'));
            // Each <router-view/> process its instruction as a composition transaction
            // there are differences between intial composition and subsequent compositions
            // also there are differences between root composition and child <router-view/> composition
            // mark the first composition transaction with a property initialComposition to distinguish it
            // when the root <router-view/> gets new instruction for the first time
            if (!('initialComposition' in compositionTransaction)) {
                compositionTransaction.initialComposition = true;
                this.compositionTransactionNotifier = compositionTransaction.enlist();
            }
        }
        /**@internal */
        static inject() {
            return [DOM.Element, Container, ViewSlot, Router, ViewLocator, CompositionTransaction, CompositionEngine];
        }
        created(owningView) {
            this.owningView = owningView;
        }
        bind(bindingContext, overrideContext) {
            // router needs to get access to view model of current route parent
            // doing it in generic way via viewModel property on container
            this.container.viewModel = bindingContext;
            this.overrideContext = overrideContext;
        }
        /**
         * Implementation of `aurelia-router` ViewPort interface, responsible for templating related part in routing Pipeline
         */
        process($viewPortInstruction, waitToSwap) {
            // have strong typings without exposing it in public typings, this is to ensure maximum backward compat
            const viewPortInstruction = $viewPortInstruction;
            const component = viewPortInstruction.component;
            const childContainer = component.childContainer;
            const viewModel = component.viewModel;
            const viewModelResource = component.viewModelResource;
            const metadata = viewModelResource.metadata;
            const config = component.router.currentInstruction.config;
            const viewPortConfig = config.viewPorts ? (config.viewPorts[viewPortInstruction.name] || {}) : {};
            childContainer.get(RouterViewLocator)._notify(this);
            // layoutInstruction is our layout viewModel
            const layoutInstruction = {
                viewModel: viewPortConfig.layoutViewModel || config.layoutViewModel || this.layoutViewModel,
                view: viewPortConfig.layoutView || config.layoutView || this.layoutView,
                model: viewPortConfig.layoutModel || config.layoutModel || this.layoutModel,
                router: viewPortInstruction.component.router,
                childContainer: childContainer,
                viewSlot: this.viewSlot
            };
            // viewport will be a thin wrapper around composition engine
            // to process instruction/configuration from users
            // preparing all information related to a composition process
            // first by getting view strategy of a ViewPortComponent View
            const viewStrategy = this.viewLocator.getViewStrategy(component.view || viewModel);
            if (viewStrategy && component.view) {
                viewStrategy.makeRelativeTo(Origin.get(component.router.container.viewModel.constructor).moduleId);
            }
            // using metadata of a custom element view model to load appropriate view-factory instance
            return metadata
                .load(childContainer, viewModelResource.value, null, viewStrategy, true)
                // for custom element, viewFactory typing is always ViewFactory
                // for custom attribute, it will be HtmlBehaviorResource
                .then((viewFactory) => {
                // if this is not the first time that this <router-view/> is composing its instruction
                // try to capture ownership of the composition transaction
                // child <router-view/> will not be able to capture, since root <router-view/> typically captures
                // the ownership token
                if (!this.compositionTransactionNotifier) {
                    this.compositionTransactionOwnershipToken = this.compositionTransaction.tryCapture();
                }
                if (layoutInstruction.viewModel || layoutInstruction.view) {
                    viewPortInstruction.layoutInstruction = layoutInstruction;
                }
                const viewPortComponentBehaviorInstruction = BehaviorInstruction.dynamic(this.element, viewModel, viewFactory);
                viewPortInstruction.controller = metadata.create(childContainer, viewPortComponentBehaviorInstruction);
                if (waitToSwap) {
                    return null;
                }
                this.swap(viewPortInstruction);
            });
        }
        swap($viewPortInstruction) {
            // have strong typings without exposing it in public typings, this is to ensure maximum backward compat
            const viewPortInstruction = $viewPortInstruction;
            const viewPortController = viewPortInstruction.controller;
            const layoutInstruction = viewPortInstruction.layoutInstruction;
            const previousView = this.view;
            // Final step of swapping a <router-view/> ViewPortComponent
            const work = () => {
                const swapStrategy = SwapStrategies[this.swapOrder] || SwapStrategies.after;
                const viewSlot = this.viewSlot;
                swapStrategy(viewSlot, previousView, () => Promise.resolve(viewSlot.add(this.view))).then(() => {
                    this._notify();
                });
            };
            // Ensure all users setups have been completed
            const ready = (owningView_or_layoutView) => {
                viewPortController.automate(this.overrideContext, owningView_or_layoutView);
                const transactionOwnerShipToken = this.compositionTransactionOwnershipToken;
                // if this router-view is the root <router-view/> of a normal startup via aurelia.setRoot
                // attemp to take control of the transaction
                // if ownership can be taken
                // wait for transaction to complete before swapping
                if (transactionOwnerShipToken) {
                    return transactionOwnerShipToken
                        .waitForCompositionComplete()
                        .then(() => {
                        this.compositionTransactionOwnershipToken = null;
                        return work();
                    });
                }
                // otherwise, just swap
                return work();
            };
            // If there is layout instruction, new to compose layout before processing ViewPortComponent
            // layout controller/view/view-model is composed using composition engine APIs
            if (layoutInstruction) {
                if (!layoutInstruction.viewModel) {
                    // createController chokes if there's no viewmodel, so create a dummy one
                    // but avoid using a POJO as it creates unwanted metadata in Object constructor
                    layoutInstruction.viewModel = new EmptyLayoutViewModel();
                }
                // using composition engine to create compose layout
                return this.compositionEngine
                    // first create controller from layoutInstruction
                    // and treat it as CompositionContext
                    // then emulate slot projection with ViewPortComponent view
                    .createController(layoutInstruction)
                    .then((layoutController) => {
                    const layoutView = layoutController.view;
                    ShadowDOM.distributeView(viewPortController.view, layoutController.slots || layoutView.slots);
                    // when there is a layout
                    // view hierarchy is: <router-view/> owner view -> layout view -> ViewPortComponent view
                    layoutController.automate(createOverrideContext(layoutInstruction.viewModel), this.owningView);
                    layoutView.children.push(viewPortController.view);
                    return layoutView || layoutController;
                })
                    .then((newView) => {
                    this.view = newView;
                    return ready(newView);
                });
            }
            // if there is no layout, then get ViewPortComponent view ready as view property
            // and process controller/swapping
            // when there is no layout
            // view hierarchy is: <router-view/> owner view -> ViewPortComponent view
            this.view = viewPortController.view;
            return ready(this.owningView);
        }
        /**
         * Notify composition transaction that this router has finished processing
         * Happens when this <router-view/> is the root router-view
         * @internal
         */
        _notify() {
            const notifier = this.compositionTransactionNotifier;
            if (notifier) {
                notifier.done();
                this.compositionTransactionNotifier = null;
            }
        }
    }
    /**
     * @internal Actively avoid using decorator to reduce the amount of code generated
     *
     * There is no view to compose by default in a router view
     * This custom element is responsible for composing its own view, based on current config
     */
    RouterView.$view = null;
    /**
     * @internal Actively avoid using decorator to reduce the amount of code generated
     */
    RouterView.$resource = {
        name: 'router-view',
        bindables: ['swapOrder', 'layoutView', 'layoutViewModel', 'layoutModel', 'inherit-binding-context']
    };
    /**
    * Locator which finds the nearest RouterView, relative to the current dependency injection container.
    */
    class RouterViewLocator {
        /**
        * Creates an instance of the RouterViewLocator class.
        */
        constructor() {
            this.promise = new Promise((resolve) => this.resolve = resolve);
        }
        /**
        * Finds the nearest RouterView instance.
        * @returns A promise that will be resolved with the located RouterView instance.
        */
        findNearest() {
            return this.promise;
        }
        /**@internal */
        _notify(routerView) {
            this.resolve(routerView);
        }
    }
  
    /**@internal exported for unit testing */
    class EmptyClass {
    }
    inlineView('<template></template>')(EmptyClass);
    /**
     * Default implementation of `RouteLoader` used for loading component based on a route config
     */
    class TemplatingRouteLoader extends RouteLoader {
        constructor(compositionEngine) {
            super();
            this.compositionEngine = compositionEngine;
        }
        /**
         * Resolve a view model from a RouteConfig
         * Throws when there is neither "moduleId" nor "viewModel" property
         * @internal
         */
        resolveViewModel(router, config) {
            return new Promise((resolve, reject) => {
                let viewModel;
                if ('moduleId' in config) {
                    let moduleId = config.moduleId;
                    if (moduleId === null) {
                        viewModel = EmptyClass;
                    }
                    else {
                        // this requires container of router has passes a certain point
                        // where a view model has been setup on the container
                        // it will fail in enhance scenario because no viewport has been registered
                        moduleId = relativeToFile(moduleId, Origin.get(router.container.viewModel.constructor).moduleId);
                        if (/\.html/i.test(moduleId)) {
                            viewModel = createDynamicClass(moduleId);
                        }
                        else {
                            viewModel = moduleId;
                        }
                    }
                    return resolve(viewModel);
                }
                // todo: add if ('viewModel' in config) to support static view model resolution
                reject(new Error('Invalid route config. No "moduleId" found.'));
            });
        }
        /**
         * Create child container based on a router container
         * Also ensures that child router are properly constructed in the newly created child container
         * @internal
         */
        createChildContainer(router) {
            const childContainer = router.container.createChild();
            childContainer.registerSingleton(RouterViewLocator);
            childContainer.getChildRouter = function () {
                let childRouter;
                childContainer.registerHandler(Router, () => childRouter || (childRouter = router.createChild(childContainer)));
                return childContainer.get(Router);
            };
            return childContainer;
        }
        /**
         * Load corresponding component of a route config of a navigation instruction
         */
        loadRoute(router, config, _navInstruction) {
            return this
                .resolveViewModel(router, config)
                .then(viewModel => this.compositionEngine.ensureViewModel({
                viewModel: viewModel,
                childContainer: this.createChildContainer(router),
                view: config.view || config.viewStrategy,
                router: router
            }));
        }
    }
    /**@internal */
    TemplatingRouteLoader.inject = [CompositionEngine];
    /**@internal exported for unit testing */
    function createDynamicClass(moduleId) {
        const name = /([^\/^\?]+)\.html/i.exec(moduleId)[1];
        class DynamicClass {
            bind(bindingContext) {
                this.$parent = bindingContext;
            }
        }
        customElement(name)(DynamicClass);
        useView(moduleId)(DynamicClass);
        return DynamicClass;
    }
  
    const logger$5 = getLogger('route-href');
    /**
     * Helper custom attribute to help associate an element with a route by name
     */
    class RouteHref {
        constructor(router, element) {
            this.router = router;
            this.element = element;
            this.attribute = 'href';
        }
        /*@internal */
        static inject() {
            return [Router, DOM.Element];
        }
        bind() {
            this.isActive = true;
            this.processChange();
        }
        unbind() {
            this.isActive = false;
        }
        attributeChanged(value, previous) {
            if (previous) {
                this.element.removeAttribute(previous);
            }
            return this.processChange();
        }
        processChange() {
            return this.router
                .ensureConfigured()
                .then(() => {
                if (!this.isActive) {
                    // returning null to avoid Bluebird warning
                    return null;
                }
                const element = this.element;
                const href = this.router.generate(this.route, this.params);
                if (element.au.controller) {
                    element.au.controller.viewModel[this.attribute] = href;
                }
                else {
                    element.setAttribute(this.attribute, href);
                }
                // returning null to avoid Bluebird warning
                return null;
            })
                .catch((reason) => {
                logger$5.error(reason);
            });
        }
    }
    /**
     * @internal Actively avoid using decorator to reduce the amount of code generated
     */
    RouteHref.$resource = {
        type: 'attribute',
        name: 'route-href',
        bindables: [
            { name: 'route', changeHandler: 'processChange', primaryProperty: true },
            { name: 'params', changeHandler: 'processChange' },
            'attribute'
        ] // type definition of Aurelia templating is wrong
    };
  
    function configure$5(config) {
        config
            .singleton(RouteLoader, TemplatingRouteLoader)
            .singleton(Router, AppRouter)
            .globalResources(RouterView, RouteHref);
        config.container.registerAlias(Router, AppRouter);
    }
  
    let ConsoleAppender = class ConsoleAppender {
      debug(logger, ...rest) {
        console.debug(`DEBUG [${logger.id}]`, ...rest);
      }
  
      info(logger, ...rest) {
        console.info(`INFO [${logger.id}]`, ...rest);
      }
  
      warn(logger, ...rest) {
        console.warn(`WARN [${logger.id}]`, ...rest);
      }
  
      error(logger, ...rest) {
        console.error(`ERROR [${logger.id}]`, ...rest);
      }
    };
  
    /**
     * Bootstrap a new Aurelia instance and start an application
     * @param {QuickStartOptions} options
     * @returns {Aurelia} the running Aurelia instance
     */
    const createAndStart = (options = {}) => {
      const aurelia = new Aurelia();
      const use = aurelia.use;
      use.standardConfiguration();
      if (options.debug) {
        use.developmentLogging();
      }
      if (Array.isArray(options.plugins)) {
        options.plugins.forEach((plgCfg) => {
          if (Array.isArray(plgCfg)) {
            use.plugin(plgCfg[0], plgCfg[1]);
          } else {
            use.plugin(plgCfg);
          }
        });
      }
      if (Array.isArray(options.resources)) {
        use.globalResources(options.resources);
      }
      return aurelia.start();
    };
  
    /**
     * Bootstrap a new Aurelia instance and start an application
     * @param {QuickStartOptions} options
     * @returns {Aurelia} the running Aurelia instance
     */
    function start(options = {}) {
      return createAndStart(options)
        .then(aurelia => aurelia.setRoot(options.root || 'app.js', options.host || document.body));
    }
  
    /**
     * Bootstrap a new Aurelia instance and start an application by enhancing a DOM tree
     * @param {QuickEnhanceOptions} options Configuration for enhancing a DOM tree
     * @returns {View} the enhanced View by selected options
     */
    function enhance(options = {}) {
      return createAndStart(options)
        .then(aurelia => {
          if (typeof options.root === 'function') {
            options.root = aurelia.container.get(options.root);
          }
          return aurelia.enhance(options.root || {}, options.host || document.body);
        });
    }
  
    /** @typed ConfigureFn
     * @param {FrameworkConfiguration} frameWorkConfig
     * @param {any} plugigConfig
     */
  
    /** @typedef QuickStartOptions
     * @property {string | Function} [root] application root. Either string or a class, which will be instantiated with DI
     * @property {string | Element} [host] application host, element or a string, which will be used to query the element
     * @property {Array<string | Function>} [resources] global resources for the application
     * @property {Array<string | {(fwCfg: FrameworkConfiguration) => any}  | [(fwCfg: FrameworkConfiguration, cfg: {}) => any, {}]>} [plugins]
     * @property {boolean} [debug] true to use development console logging
     */
  
    /** @typedef QuickEnhanceOptions
     * @property {{} | Function} [root] binding context for enhancement, can be either object or a class, which will be instantiated with DI
     * @property {string | Element} [host] host node of to be enhanced tree
     * @property {Array<string | Function>} [resources] global resources for the application
     * @property {Array<string | {(fwCfg: FrameworkConfiguration) => any}  | [(fwCfg: FrameworkConfiguration, cfg: {}) => any, {}]>} [plugins]
     * @property {boolean} [debug] true to use development console logging
     */
  
    initialize();
  
    // Using static convention to avoid having to fetch / load module dynamically
    (frameworkCfgProto => {
      frameworkCfgProto.developmentLogging = function() {
        LogManager.addAppender(new ConsoleAppender());
        LogManager.setLevel(LogManager.logLevel.debug);
        return this;
      };
  
      frameworkCfgProto.defaultBindingLanguage = function() {
        return this.plugin(configure);
      };
  
      frameworkCfgProto.defaultResources = function() {
        return this.plugin(configure$2);
      };
  
      frameworkCfgProto.eventAggregator = function() {
        return this.plugin(configure$3);
      };
  
      frameworkCfgProto.history = function() {
        return this.plugin(configure$4);
      };
  
      frameworkCfgProto.router = function() {
        return this.plugin(configure$5);
      };
    })(FrameworkConfiguration.prototype);
  
    exports.AbstractRepeater = AbstractRepeater;
    exports.AccessKeyed = AccessKeyed;
    exports.AccessMember = AccessMember;
    exports.AccessScope = AccessScope;
    exports.AccessThis = AccessThis;
    exports.ActivateNextStep = ActivateNextStep;
    exports.AggregateError = AggregateError;
    exports.All = All;
    exports.Animator = Animator;
    exports.AppRouter = AppRouter;
    exports.ArrayRepeatStrategy = ArrayRepeatStrategy;
    exports.Assign = Assign;
    exports.AttrBindingBehavior = AttrBindingBehavior;
    exports.Aurelia = Aurelia;
    exports.BehaviorInstruction = BehaviorInstruction;
    exports.BehaviorPropertyObserver = BehaviorPropertyObserver;
    exports.Binary = Binary;
    exports.BindableProperty = BindableProperty;
    exports.Binding = Binding;
    exports.BindingBehavior = BindingBehavior;
    exports.BindingBehaviorResource = BindingBehaviorResource;
    exports.BindingEngine = BindingEngine;
    exports.BindingExpression = BindingExpression;
    exports.BindingLanguage = BindingLanguage;
    exports.BindingSignaler = BindingSignaler;
    exports.BoundViewFactory = BoundViewFactory;
    exports.BuildNavigationPlanStep = BuildNavigationPlanStep;
    exports.Call = Call;
    exports.CallExpression = CallExpression;
    exports.CallFunction = CallFunction;
    exports.CallMember = CallMember;
    exports.CallScope = CallScope;
    exports.CanActivateNextStep = CanActivateNextStep;
    exports.CanDeactivatePreviousStep = CanDeactivatePreviousStep;
    exports.CheckedObserver = CheckedObserver;
    exports.ClassObserver = ClassObserver;
    exports.CollectionLengthObserver = CollectionLengthObserver;
    exports.CommitChangesStep = CommitChangesStep;
    exports.Compose = Compose;
    exports.CompositionEngine = CompositionEngine;
    exports.CompositionTransaction = CompositionTransaction;
    exports.CompositionTransactionNotifier = CompositionTransactionNotifier;
    exports.CompositionTransactionOwnershipToken = CompositionTransactionOwnershipToken;
    exports.ComputedExpression = ComputedExpression;
    exports.Conditional = Conditional;
    exports.Container = Container;
    exports.Controller = Controller;
    exports.ConventionalViewStrategy = ConventionalViewStrategy;
    exports.DOM = DOM;
    exports.DataAttributeObserver = DataAttributeObserver;
    exports.DeactivatePreviousStep = DeactivatePreviousStep;
    exports.DebounceBindingBehavior = DebounceBindingBehavior;
    exports.DirtyCheckProperty = DirtyCheckProperty;
    exports.DirtyChecker = DirtyChecker;
    exports.ElementConfigResource = ElementConfigResource;
    exports.ElementEvents = ElementEvents;
    exports.Else = Else;
    exports.EventAggregator = EventAggregator;
    exports.EventManager = EventManager;
    exports.EventSubscriber = EventSubscriber;
    exports.Expression = Expression;
    exports.ExpressionCloner = ExpressionCloner;
    exports.ExpressionObserver = ExpressionObserver;
    exports.FEATURE = FEATURE;
    exports.Factory = Factory;
    exports.FactoryInvoker = FactoryInvoker;
    exports.Focus = Focus;
    exports.FrameworkConfiguration = FrameworkConfiguration;
    exports.FromViewBindingBehavior = FromViewBindingBehavior;
    exports.HTMLSanitizer = HTMLSanitizer;
    exports.Hide = Hide;
    exports.HtmlBehaviorResource = HtmlBehaviorResource;
    exports.If = If;
    exports.InlineViewStrategy = InlineViewStrategy;
    exports.InvocationHandler = InvocationHandler;
    exports.Lazy = Lazy;
    exports.Listener = Listener;
    exports.ListenerExpression = ListenerExpression;
    exports.LiteralArray = LiteralArray;
    exports.LiteralObject = LiteralObject;
    exports.LiteralPrimitive = LiteralPrimitive;
    exports.LiteralString = LiteralString;
    exports.LiteralTemplate = LiteralTemplate;
    exports.LoadRouteStep = LoadRouteStep;
    exports.Loader = Loader;
    exports.LogManager = LogManager;
    exports.MapRepeatStrategy = MapRepeatStrategy;
    exports.ModifyCollectionObserver = ModifyCollectionObserver;
    exports.ModuleAnalyzer = ModuleAnalyzer;
    exports.NameExpression = NameExpression;
    exports.NavModel = NavModel;
    exports.NavigationInstruction = NavigationInstruction;
    exports.NewInstance = NewInstance;
    exports.NoViewStrategy = NoViewStrategy;
    exports.NullRepeatStrategy = NullRepeatStrategy;
    exports.NumberRepeatStrategy = NumberRepeatStrategy;
    exports.ObjectObservationAdapter = ObjectObservationAdapter;
    exports.ObserverLocator = ObserverLocator;
    exports.OneTimeBindingBehavior = OneTimeBindingBehavior;
    exports.OneWayBindingBehavior = OneWayBindingBehavior;
    exports.Optional = Optional;
    exports.Origin = Origin;
    exports.PLATFORM = PLATFORM;
    exports.Parent = Parent;
    exports.Parser = Parser;
    exports.ParserImplementation = ParserImplementation;
    exports.PassThroughSlot = PassThroughSlot;
    exports.Pipeline = Pipeline;
    exports.PipelineProvider = PipelineProvider;
    exports.PrimitiveObserver = PrimitiveObserver;
    exports.Redirect = Redirect;
    exports.RedirectToRoute = RedirectToRoute;
    exports.RelativeViewStrategy = RelativeViewStrategy;
    exports.Repeat = Repeat;
    exports.RepeatStrategyLocator = RepeatStrategyLocator;
    exports.Replaceable = Replaceable;
    exports.ResourceDescription = ResourceDescription;
    exports.ResourceLoadContext = ResourceLoadContext;
    exports.ResourceModule = ResourceModule;
    exports.RouteLoader = RouteLoader;
    exports.Router = Router;
    exports.RouterConfiguration = RouterConfiguration;
    exports.SVGAnalyzer = SVGAnalyzer;
    exports.SanitizeHTMLValueConverter = SanitizeHTMLValueConverter;
    exports.SelectValueObserver = SelectValueObserver;
    exports.SelfBindingBehavior = SelfBindingBehavior;
    exports.SetRepeatStrategy = SetRepeatStrategy;
    exports.SetterObserver = SetterObserver;
    exports.ShadowDOM = ShadowDOM;
    exports.ShadowSlot = ShadowSlot;
    exports.Show = Show;
    exports.SignalBindingBehavior = SignalBindingBehavior;
    exports.SingletonRegistration = SingletonRegistration;
    exports.SlotCustomAttribute = SlotCustomAttribute;
    exports.StaticViewStrategy = StaticViewStrategy;
    exports.StrategyResolver = StrategyResolver;
    exports.StyleObserver = StyleObserver;
    exports.SwapStrategies = SwapStrategies;
    exports.TargetInstruction = TargetInstruction;
    exports.TaskQueue = TaskQueue;
    exports.TemplateDependency = TemplateDependency;
    exports.TemplateRegistryEntry = TemplateRegistryEntry;
    exports.TemplateRegistryViewStrategy = TemplateRegistryViewStrategy;
    exports.TemplatingEngine = TemplatingEngine;
    exports.ThrottleBindingBehavior = ThrottleBindingBehavior;
    exports.ToViewBindingBehavior = ToViewBindingBehavior;
    exports.TransientRegistration = TransientRegistration;
    exports.TwoWayBindingBehavior = TwoWayBindingBehavior;
    exports.Unary = Unary;
    exports.UpdateTriggerBindingBehavior = UpdateTriggerBindingBehavior;
    exports.ValueAttributeObserver = ValueAttributeObserver;
    exports.ValueConverter = ValueConverter;
    exports.ValueConverterResource = ValueConverterResource;
    exports.View = View;
    exports.ViewCompileInstruction = ViewCompileInstruction;
    exports.ViewCompiler = ViewCompiler;
    exports.ViewEngine = ViewEngine;
    exports.ViewEngineHooksResource = ViewEngineHooksResource;
    exports.ViewFactory = ViewFactory;
    exports.ViewLocator = ViewLocator;
    exports.ViewResources = ViewResources;
    exports.ViewSlot = ViewSlot;
    exports.With = With;
    exports.XLinkAttributeObserver = XLinkAttributeObserver;
    exports._emptyParameters = _emptyParameters;
    exports._hyphenate = _hyphenate;
    exports._isAllWhitespace = _isAllWhitespace;
    exports.activationStrategy = activationStrategy;
    exports.all = all;
    exports.animationEvent = animationEvent;
    exports.autoinject = autoinject;
    exports.behavior = behavior;
    exports.bindable = bindable;
    exports.bindingBehavior = bindingBehavior;
    exports.bindingMode = bindingMode;
    exports.buildQueryString = buildQueryString;
    exports.calcSplices = calcSplices;
    exports.camelCase = camelCase;
    exports.child = child;
    exports.children = children;
    exports.cloneExpression = cloneExpression;
    exports.computedFrom = computedFrom;
    exports.connectBindingToSignal = connectBindingToSignal;
    exports.connectable = connectable;
    exports.containerless = containerless;
    exports.createComputedObserver = createComputedObserver;
    exports.createFullOverrideContext = createFullOverrideContext;
    exports.createOverrideContext = createOverrideContext;
    exports.createScopeForTest = createScopeForTest;
    exports.customAttribute = customAttribute;
    exports.customElement = customElement;
    exports.dataAttributeAccessor = dataAttributeAccessor;
    exports.declarePropertyDependencies = declarePropertyDependencies;
    exports.decorators = decorators;
    exports.delegationStrategy = delegationStrategy;
    exports.deprecated = deprecated;
    exports.disableConnectQueue = disableConnectQueue;
    exports.dynamicOptions = dynamicOptions;
    exports.elementConfig = elementConfig;
    exports.elements = elements;
    exports.enableConnectQueue = enableConnectQueue;
    exports.enhance = enhance;
    exports.enqueueBindingConnect = enqueueBindingConnect;
    exports.factory = factory;
    exports.getArrayObserver = getArrayObserver;
    exports.getChangeRecords = getChangeRecords;
    exports.getConnectQueueSize = getConnectQueueSize;
    exports.getContextFor = getContextFor;
    exports.getDecoratorDependencies = getDecoratorDependencies;
    exports.getItemsSourceExpression = getItemsSourceExpression;
    exports.getMapObserver = getMapObserver;
    exports.getSetObserver = getSetObserver;
    exports.hasDeclaredDependencies = hasDeclaredDependencies;
    exports.includeEventsIn = includeEventsIn;
    exports.initializePAL = initializePAL;
    exports.inject = inject;
    exports.inlineView = inlineView;
    exports.invokeAsFactory = invokeAsFactory;
    exports.invoker = invoker;
    exports.isNavigationCommand = isNavigationCommand;
    exports.isOneTime = isOneTime;
    exports.join = join;
    exports.lazy = lazy;
    exports.mergeSplice = mergeSplice;
    exports.metadata = metadata;
    exports.mixin = mixin;
    exports.newInstance = newInstance;
    exports.noView = noView;
    exports.observable = observable;
    exports.optional = optional;
    exports.parent = parent;
    exports.parseQueryString = parseQueryString;
    exports.presentationAttributes = presentationAttributes;
    exports.presentationElements = presentationElements;
    exports.processAttributes = processAttributes;
    exports.processContent = processContent;
    exports.projectArraySplices = projectArraySplices;
    exports.propertyAccessor = propertyAccessor;
    exports.protocol = protocol;
    exports.registration = registration;
    exports.relativeToFile = relativeToFile;
    exports.reset = reset;
    exports.resolver = resolver;
    exports.resource = resource;
    exports.setConnectQueueThreshold = setConnectQueueThreshold;
    exports.signalBindings = signalBindings;
    exports.singleton = singleton;
    exports.sourceContext = sourceContext;
    exports.start = start;
    exports.subscriberCollection = subscriberCollection;
    exports.targetContext = targetContext;
    exports.templateController = templateController;
    exports.transient = transient;
    exports.unwrapExpression = unwrapExpression;
    exports.updateOneTimeBinding = updateOneTimeBinding;
    exports.updateOverrideContext = updateOverrideContext;
    exports.useShadowDOM = useShadowDOM;
    exports.useView = useView;
    exports.useViewStrategy = useViewStrategy;
    exports.validateBehaviorName = validateBehaviorName;
    exports.valueConverter = valueConverter;
    exports.view = view;
    exports.viewEngineHooks = viewEngineHooks;
    exports.viewResources = viewResources;
    exports.viewStrategy = viewStrategy;
    exports.viewsRequireLifecycle = viewsRequireLifecycle;
  
    Object.defineProperty(exports, '__esModule', { value: true });
  
  }));
  