{"version":3,"file":"webcomponents.bundle.js","sources":["webpack:///webpack/bootstrap","webpack:///./node_modules/@polymer/font-roboto/roboto.js","webpack:///./node_modules/@polymer/iron-a11y-announcer/iron-a11y-announcer.js","webpack:///./node_modules/@polymer/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js","webpack:///./node_modules/@polymer/iron-behaviors/iron-button-state.js","webpack:///./node_modules/@polymer/iron-behaviors/iron-control-state.js","webpack:///./node_modules/@polymer/iron-checked-element-behavior/iron-checked-element-behavior.js","webpack:///./node_modules/@polymer/iron-fit-behavior/iron-fit-behavior.js","webpack:///./node_modules/@polymer/iron-flex-layout/iron-flex-layout.js","webpack:///./node_modules/@polymer/iron-form-element-behavior/iron-form-element-behavior.js","webpack:///./node_modules/@polymer/iron-icon/iron-icon.js","webpack:///./node_modules/@polymer/iron-icons/iron-icons.js","webpack:///./node_modules/@polymer/iron-iconset-svg/iron-iconset-svg.js","webpack:///./node_modules/@polymer/iron-input/iron-input.js","webpack:///./node_modules/@polymer/iron-menu-behavior/iron-menu-behavior.js","webpack:///./node_modules/@polymer/iron-menu-behavior/iron-menubar-behavior.js","webpack:///./node_modules/@polymer/iron-meta/iron-meta.js","webpack:///./node_modules/@polymer/iron-overlay-behavior/iron-focusables-helper.js","webpack:///./node_modules/@polymer/iron-overlay-behavior/iron-overlay-backdrop.js","webpack:///./node_modules/@polymer/iron-overlay-behavior/iron-overlay-behavior.js","webpack:///./node_modules/@polymer/iron-overlay-behavior/iron-overlay-manager.js","webpack:///./node_modules/@polymer/iron-overlay-behavior/iron-scroll-manager.js","webpack:///./node_modules/@polymer/iron-resizable-behavior/iron-resizable-behavior.js","webpack:///./node_modules/@polymer/iron-selector/iron-multi-selectable.js","webpack:///./node_modules/@polymer/iron-selector/iron-selectable.js","webpack:///./node_modules/@polymer/iron-selector/iron-selection.js","webpack:///./node_modules/@polymer/iron-validatable-behavior/iron-validatable-behavior.js","webpack:///./node_modules/@polymer/lit-element/lib/decorators.js","webpack:///./node_modules/@polymer/lit-element/lib/updating-element.js","webpack:///./node_modules/@polymer/lit-element/lit-element.js","webpack:///./node_modules/@polymer/paper-behaviors/paper-button-behavior.js","webpack:///./node_modules/@polymer/paper-behaviors/paper-checked-element-behavior.js","webpack:///./node_modules/@polymer/paper-behaviors/paper-inky-focus-behavior.js","webpack:///./node_modules/@polymer/paper-behaviors/paper-ripple-behavior.js","webpack:///./node_modules/@polymer/paper-fab/paper-fab.js","webpack:///./node_modules/@polymer/paper-input/paper-input-addon-behavior.js","webpack:///./node_modules/@polymer/paper-input/paper-input-behavior.js","webpack:///./node_modules/@polymer/paper-input/paper-input-char-counter.js","webpack:///./node_modules/@polymer/paper-input/paper-input-container.js","webpack:///./node_modules/@polymer/paper-input/paper-input-error.js","webpack:///./node_modules/@polymer/paper-input/paper-input.js","webpack:///./node_modules/@polymer/paper-item/paper-item-behavior.js","webpack:///./node_modules/@polymer/paper-item/paper-item-shared-styles.js","webpack:///./node_modules/@polymer/paper-item/paper-item.js","webpack:///./node_modules/@polymer/paper-radio-button/paper-radio-button.js","webpack:///./node_modules/@polymer/paper-radio-group/paper-radio-group.js","webpack:///./node_modules/@polymer/paper-ripple/paper-ripple.js","webpack:///./node_modules/@polymer/paper-styles/color.js","webpack:///./node_modules/@polymer/paper-styles/default-theme.js","webpack:///./node_modules/@polymer/paper-styles/element-styles/paper-material-styles.js","webpack:///./node_modules/@polymer/paper-styles/shadow.js","webpack:///./node_modules/@polymer/paper-styles/typography.js","webpack:///./node_modules/@polymer/paper-toast/paper-toast.js","webpack:///./node_modules/@polymer/paper-tooltip/paper-tooltip.js","webpack:///./node_modules/@polymer/polymer/lib/elements/array-selector.js","webpack:///./node_modules/@polymer/polymer/lib/elements/custom-style.js","webpack:///./node_modules/@polymer/polymer/lib/elements/dom-bind.js","webpack:///./node_modules/@polymer/polymer/lib/elements/dom-if.js","webpack:///./node_modules/@polymer/polymer/lib/elements/dom-module.js","webpack:///./node_modules/@polymer/polymer/lib/elements/dom-repeat.js","webpack:///./node_modules/@polymer/polymer/lib/legacy/class.js","webpack:///./node_modules/@polymer/polymer/lib/legacy/legacy-element-mixin.js","webpack:///./node_modules/@polymer/polymer/lib/legacy/mutable-data-behavior.js","webpack:///./node_modules/@polymer/polymer/lib/legacy/polymer-fn.js","webpack:///./node_modules/@polymer/polymer/lib/legacy/polymer.dom.js","webpack:///./node_modules/@polymer/polymer/lib/legacy/templatizer-behavior.js","webpack:///./node_modules/@polymer/polymer/lib/mixins/dir-mixin.js","webpack:///./node_modules/@polymer/polymer/lib/mixins/element-mixin.js","webpack:///./node_modules/@polymer/polymer/lib/mixins/gesture-event-listeners.js","webpack:///./node_modules/@polymer/polymer/lib/mixins/mutable-data.js","webpack:///./node_modules/@polymer/polymer/lib/mixins/properties-changed.js","webpack:///./node_modules/@polymer/polymer/lib/mixins/properties-mixin.js","webpack:///./node_modules/@polymer/polymer/lib/mixins/property-accessors.js","webpack:///./node_modules/@polymer/polymer/lib/mixins/property-effects.js","webpack:///./node_modules/@polymer/polymer/lib/mixins/template-stamp.js","webpack:///./node_modules/@polymer/polymer/lib/utils/array-splice.js","webpack:///./node_modules/@polymer/polymer/lib/utils/async.js","webpack:///./node_modules/@polymer/polymer/lib/utils/boot.js","webpack:///./node_modules/@polymer/polymer/lib/utils/case-map.js","webpack:///./node_modules/@polymer/polymer/lib/utils/debounce.js","webpack:///./node_modules/@polymer/polymer/lib/utils/flattened-nodes-observer.js","webpack:///./node_modules/@polymer/polymer/lib/utils/flush.js","webpack:///./node_modules/@polymer/polymer/lib/utils/gestures.js","webpack:///./node_modules/@polymer/polymer/lib/utils/html-tag.js","webpack:///./node_modules/@polymer/polymer/lib/utils/mixin.js","webpack:///./node_modules/@polymer/polymer/lib/utils/path.js","webpack:///./node_modules/@polymer/polymer/lib/utils/render-status.js","webpack:///./node_modules/@polymer/polymer/lib/utils/resolve-url.js","webpack:///./node_modules/@polymer/polymer/lib/utils/settings.js","webpack:///./node_modules/@polymer/polymer/lib/utils/style-gather.js","webpack:///./node_modules/@polymer/polymer/lib/utils/templatize.js","webpack:///./node_modules/@polymer/polymer/lib/utils/unresolved.js","webpack:///./node_modules/@polymer/polymer/polymer-element.js","webpack:///./node_modules/@polymer/polymer/polymer-legacy.js","webpack:///./node_modules/@webcomponents/shadycss/entrypoints/apply-shim.js","webpack:///./node_modules/@webcomponents/shadycss/entrypoints/custom-style-interface.js","webpack:///./node_modules/@webcomponents/shadycss/src/apply-shim-utils.js","webpack:///./node_modules/@webcomponents/shadycss/src/apply-shim.js","webpack:///./node_modules/@webcomponents/shadycss/src/common-regex.js","webpack:///./node_modules/@webcomponents/shadycss/src/common-utils.js","webpack:///./node_modules/@webcomponents/shadycss/src/css-parse.js","webpack:///./node_modules/@webcomponents/shadycss/src/custom-style-interface.js","webpack:///./node_modules/@webcomponents/shadycss/src/document-wait.js","webpack:///./node_modules/@webcomponents/shadycss/src/style-settings.js","webpack:///./node_modules/@webcomponents/shadycss/src/style-util.js","webpack:///./node_modules/@webcomponents/shadycss/src/template-map.js","webpack:///./node_modules/@webcomponents/shadycss/src/unscoped-style-handler.js","webpack:///./node_modules/lit-html/lib/default-template-processor.js","webpack:///./node_modules/lit-html/lib/directive.js","webpack:///./node_modules/lit-html/lib/dom.js","webpack:///./node_modules/lit-html/lib/modify-template.js","webpack:///./node_modules/lit-html/lib/part.js","webpack:///./node_modules/lit-html/lib/parts.js","webpack:///./node_modules/lit-html/lib/render.js","webpack:///./node_modules/lit-html/lib/shady-render.js","webpack:///./node_modules/lit-html/lib/template-factory.js","webpack:///./node_modules/lit-html/lib/template-instance.js","webpack:///./node_modules/lit-html/lib/template-result.js","webpack:///./node_modules/lit-html/lib/template.js","webpack:///./node_modules/lit-html/lit-html.js","webpack:///./scripts/webcomponents/app-layout/app-drawer-content.js","webpack:///./scripts/webcomponents/app-layout/app-drawer-layout.js","webpack:///./scripts/webcomponents/app-layout/app-drawer.js","webpack:///./scripts/webcomponents/app-layout/app-header.js","webpack:///./scripts/webcomponents/app-layout/app-layout.js","webpack:///./scripts/webcomponents/app-layout/app-toolbar.js","webpack:///./scripts/webcomponents/file-download/file-download.js","webpack:///./scripts/webcomponents/flex-box/flex-box.js","webpack:///./scripts/webcomponents/flex-grid/column-header.js","webpack:///./scripts/webcomponents/flex-grid/flex-grid.js","webpack:///./scripts/webcomponents/flex-grid/grid-item.js","webpack:///./scripts/webcomponents/flex-grid/grid-pagination.js","webpack:///./scripts/webcomponents/flex-grid/page-info.js","webpack:///./scripts/webcomponents/flex-grid/page-navigation.js","webpack:///./scripts/webcomponents/flex-table/cell-item.js","webpack:///./scripts/webcomponents/flex-table/flex-table.js","webpack:///./scripts/webcomponents/form/form-api-submit.js","webpack:///./scripts/webcomponents/form/form-notification.js","webpack:///./scripts/webcomponents/google-apis/google-map.js","webpack:///./scripts/webcomponents/google-apis/google-youtube.js","webpack:///./scripts/webcomponents/grid-layout/grid-columns.js","webpack:///./scripts/webcomponents/grid-layout/grid-row.js","webpack:///./scripts/webcomponents/light-gallery/light-gallery.js","webpack:///./scripts/webcomponents/md-input/md-autocomplete.js","webpack:///./scripts/webcomponents/md-input/md-checkbox.js","webpack:///./scripts/webcomponents/md-input/md-input.js","webpack:///./scripts/webcomponents/md-input/md-radio-list.js","webpack:///./scripts/webcomponents/md-input/md-radio.js","webpack:///./scripts/webcomponents/md-input/md-select.js","webpack:///./scripts/webcomponents/md-input/md-state-select.js","webpack:///./scripts/webcomponents/md-input/md-textarea.js","webpack:///./scripts/webcomponents/mutation-observer/mutation-observer.js","webpack:///./scripts/webcomponents/print-page/print-page.js","webpack:///./scripts/webcomponents/search-filters/search-filters.js","webpack:///./scripts/webcomponents/shopping-gallery/alt-image.js","webpack:///./scripts/webcomponents/shopping-gallery/alt-images.js","webpack:///./scripts/webcomponents/shopping-gallery/alt-video.js","webpack:///./scripts/webcomponents/shopping-gallery/gallery-item.js","webpack:///./scripts/webcomponents/shopping-gallery/item-detail.js","webpack:///./scripts/webcomponents/shopping-gallery/item-images.js","webpack:///./scripts/webcomponents/shopping-gallery/magic-zoom.js","webpack:///./scripts/webcomponents/shopping-gallery/shopping-gallery.js","webpack:///./scripts/webcomponents/shopping-gallery/shopping-item.js","webpack:///./scripts/webcomponents/silicon-history/silicon-history.js","webpack:///./scripts/webcomponents/social-buttons/social-buttons.js","webpack:///./scripts/webcomponents/ui-carousel/carousel-indicators.js","webpack:///./scripts/webcomponents/ui-carousel/carousel-inner-container.js","webpack:///./scripts/webcomponents/ui-carousel/carousel-item.js","webpack:///./scripts/webcomponents/ui-carousel/carousel-items.js","webpack:///./scripts/webcomponents/ui-carousel/carousel-navigation.js","webpack:///./scripts/webcomponents/ui-carousel/multi-slide-carousel.js","webpack:///./scripts/webcomponents/ui-carousel/ui-carousel.js","webpack:///./scripts/webcomponents/ui/material-card.js","webpack:///./scripts/webcomponents/ui/material-gallery.js","webpack:///./scripts/webcomponents/ui/material-item.js","webpack:///./scripts/webcomponents/ui/md-dialog.js","webpack:///./scripts/webcomponents/ui/state-select.js","webpack:///./scripts/webcomponents/ui/ui-input-addon.js","webpack:///./scripts/webcomponents/ui/ui-select.js","webpack:///./scripts/webcomponents/utility-helper/transition-helper.js","webpack:///./scripts/webcomponents/utility-helper/utility-helper.js","webpack:///./scripts/webpack/index.js"],"sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = \"./scripts/webpack/index.js\");\n","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nexport {}; // ensure this file can only be parsed as a module.\n// Give the user the choice to opt out of font loading.\n\nif (!window.polymerSkipLoadingFontRoboto) {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.type = 'text/css';\n link.crossOrigin = 'anonymous';\n link.href = 'https://fonts.googleapis.com/css?family=Roboto+Mono:400,700|Roboto:400,300,300italic,400italic,500,500italic,700,700italic';\n document.head.appendChild(link);\n}","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { Polymer } from '@polymer/polymer/lib/legacy/polymer-fn.js';\nimport { html } from '@polymer/polymer/lib/utils/html-tag.js';\n/**\n`iron-a11y-announcer` is a singleton element that is intended to add a11y\nto features that require on-demand announcement from screen readers. In\norder to make use of the announcer, it is best to request its availability\nin the announcing element.\n\nExample:\n\n Polymer({\n\n is: 'x-chatty',\n\n attached: function() {\n // This will create the singleton element if it has not\n // been created yet:\n Polymer.IronA11yAnnouncer.requestAvailability();\n }\n });\n\nAfter the `iron-a11y-announcer` has been made available, elements can\nmake announces by firing bubbling `iron-announce` events.\n\nExample:\n\n this.fire('iron-announce', {\n text: 'This is an announcement!'\n }, { bubbles: true });\n\nNote: announcements are only audible if you have a screen reader enabled.\n\n@group Iron Elements\n@demo demo/index.html\n*/\n\nexport const IronA11yAnnouncer = Polymer({\n _template: html`\n \n
[[_text]]
\n`,\n is: 'iron-a11y-announcer',\n properties: {\n /**\n * The value of mode is used to set the `aria-live` attribute\n * for the element that will be announced. Valid values are: `off`,\n * `polite` and `assertive`.\n */\n mode: {\n type: String,\n value: 'polite'\n },\n _text: {\n type: String,\n value: ''\n }\n },\n created: function created() {\n if (!IronA11yAnnouncer.instance) {\n IronA11yAnnouncer.instance = this;\n }\n\n document.body.addEventListener('iron-announce', this._onIronAnnounce.bind(this));\n },\n\n /**\n * Cause a text string to be announced by screen readers.\n *\n * @param {string} text The text that should be announced.\n */\n announce: function announce(text) {\n this._text = '';\n this.async(function () {\n this._text = text;\n }, 100);\n },\n _onIronAnnounce: function _onIronAnnounce(event) {\n if (event.detail && event.detail.text) {\n this.announce(event.detail.text);\n }\n }\n});\nIronA11yAnnouncer.instance = null;\n\nIronA11yAnnouncer.requestAvailability = function () {\n if (!IronA11yAnnouncer.instance) {\n IronA11yAnnouncer.instance = document.createElement('iron-a11y-announcer');\n }\n\n document.body.appendChild(IronA11yAnnouncer.instance);\n};","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\n/**\n * Chrome uses an older version of DOM Level 3 Keyboard Events\n *\n * Most keys are labeled as text, but some are Unicode codepoints.\n * Values taken from:\n * http://www.w3.org/TR/2007/WD-DOM-Level-3-Events-20071221/keyset.html#KeySet-Set\n */\n\nvar KEY_IDENTIFIER = {\n 'U+0008': 'backspace',\n 'U+0009': 'tab',\n 'U+001B': 'esc',\n 'U+0020': 'space',\n 'U+007F': 'del'\n};\n/**\n * Special table for KeyboardEvent.keyCode.\n * KeyboardEvent.keyIdentifier is better, and KeyBoardEvent.key is even better\n * than that.\n *\n * Values from:\n * https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.keyCode#Value_of_keyCode\n */\n\nvar KEY_CODE = {\n 8: 'backspace',\n 9: 'tab',\n 13: 'enter',\n 27: 'esc',\n 33: 'pageup',\n 34: 'pagedown',\n 35: 'end',\n 36: 'home',\n 32: 'space',\n 37: 'left',\n 38: 'up',\n 39: 'right',\n 40: 'down',\n 46: 'del',\n 106: '*'\n};\n/**\n * MODIFIER_KEYS maps the short name for modifier keys used in a key\n * combo string to the property name that references those same keys\n * in a KeyboardEvent instance.\n */\n\nvar MODIFIER_KEYS = {\n 'shift': 'shiftKey',\n 'ctrl': 'ctrlKey',\n 'alt': 'altKey',\n 'meta': 'metaKey'\n};\n/**\n * KeyboardEvent.key is mostly represented by printable character made by\n * the keyboard, with unprintable keys labeled nicely.\n *\n * However, on OS X, Alt+char can make a Unicode character that follows an\n * Apple-specific mapping. In this case, we fall back to .keyCode.\n */\n\nvar KEY_CHAR = /[a-z0-9*]/;\n/**\n * Matches a keyIdentifier string.\n */\n\nvar IDENT_CHAR = /U\\+/;\n/**\n * Matches arrow keys in Gecko 27.0+\n */\n\nvar ARROW_KEY = /^arrow/;\n/**\n * Matches space keys everywhere (notably including IE10's exceptional name\n * `spacebar`).\n */\n\nvar SPACE_KEY = /^space(bar)?/;\n/**\n * Matches ESC key.\n *\n * Value from: http://w3c.github.io/uievents-key/#key-Escape\n */\n\nvar ESC_KEY = /^escape$/;\n/**\n * Transforms the key.\n * @param {string} key The KeyBoardEvent.key\n * @param {Boolean} [noSpecialChars] Limits the transformation to\n * alpha-numeric characters.\n */\n\nfunction transformKey(key, noSpecialChars) {\n var validKey = '';\n\n if (key) {\n var lKey = key.toLowerCase();\n\n if (lKey === ' ' || SPACE_KEY.test(lKey)) {\n validKey = 'space';\n } else if (ESC_KEY.test(lKey)) {\n validKey = 'esc';\n } else if (lKey.length == 1) {\n if (!noSpecialChars || KEY_CHAR.test(lKey)) {\n validKey = lKey;\n }\n } else if (ARROW_KEY.test(lKey)) {\n validKey = lKey.replace('arrow', '');\n } else if (lKey == 'multiply') {\n // numpad '*' can map to Multiply on IE/Windows\n validKey = '*';\n } else {\n validKey = lKey;\n }\n }\n\n return validKey;\n}\n\nfunction transformKeyIdentifier(keyIdent) {\n var validKey = '';\n\n if (keyIdent) {\n if (keyIdent in KEY_IDENTIFIER) {\n validKey = KEY_IDENTIFIER[keyIdent];\n } else if (IDENT_CHAR.test(keyIdent)) {\n keyIdent = parseInt(keyIdent.replace('U+', '0x'), 16);\n validKey = String.fromCharCode(keyIdent).toLowerCase();\n } else {\n validKey = keyIdent.toLowerCase();\n }\n }\n\n return validKey;\n}\n\nfunction transformKeyCode(keyCode) {\n var validKey = '';\n\n if (Number(keyCode)) {\n if (keyCode >= 65 && keyCode <= 90) {\n // ascii a-z\n // lowercase is 32 offset from uppercase\n validKey = String.fromCharCode(32 + keyCode);\n } else if (keyCode >= 112 && keyCode <= 123) {\n // function keys f1-f12\n validKey = 'f' + (keyCode - 112 + 1);\n } else if (keyCode >= 48 && keyCode <= 57) {\n // top 0-9 keys\n validKey = String(keyCode - 48);\n } else if (keyCode >= 96 && keyCode <= 105) {\n // num pad 0-9\n validKey = String(keyCode - 96);\n } else {\n validKey = KEY_CODE[keyCode];\n }\n }\n\n return validKey;\n}\n/**\n * Calculates the normalized key for a KeyboardEvent.\n * @param {KeyboardEvent} keyEvent\n * @param {Boolean} [noSpecialChars] Set to true to limit keyEvent.key\n * transformation to alpha-numeric chars. This is useful with key\n * combinations like shift + 2, which on FF for MacOS produces\n * keyEvent.key = @\n * To get 2 returned, set noSpecialChars = true\n * To get @ returned, set noSpecialChars = false\n */\n\n\nfunction normalizedKeyForEvent(keyEvent, noSpecialChars) {\n // Fall back from .key, to .detail.key for artifical keyboard events,\n // and then to deprecated .keyIdentifier and .keyCode.\n if (keyEvent.key) {\n return transformKey(keyEvent.key, noSpecialChars);\n }\n\n if (keyEvent.detail && keyEvent.detail.key) {\n return transformKey(keyEvent.detail.key, noSpecialChars);\n }\n\n return transformKeyIdentifier(keyEvent.keyIdentifier) || transformKeyCode(keyEvent.keyCode) || '';\n}\n\nfunction keyComboMatchesEvent(keyCombo, event) {\n // For combos with modifiers we support only alpha-numeric keys\n var keyEvent = normalizedKeyForEvent(event, keyCombo.hasModifiers);\n return keyEvent === keyCombo.key && (!keyCombo.hasModifiers || !!event.shiftKey === !!keyCombo.shiftKey && !!event.ctrlKey === !!keyCombo.ctrlKey && !!event.altKey === !!keyCombo.altKey && !!event.metaKey === !!keyCombo.metaKey);\n}\n\nfunction parseKeyComboString(keyComboString) {\n if (keyComboString.length === 1) {\n return {\n combo: keyComboString,\n key: keyComboString,\n event: 'keydown'\n };\n }\n\n return keyComboString.split('+').reduce(function (parsedKeyCombo, keyComboPart) {\n var eventParts = keyComboPart.split(':');\n var keyName = eventParts[0];\n var event = eventParts[1];\n\n if (keyName in MODIFIER_KEYS) {\n parsedKeyCombo[MODIFIER_KEYS[keyName]] = true;\n parsedKeyCombo.hasModifiers = true;\n } else {\n parsedKeyCombo.key = keyName;\n parsedKeyCombo.event = event || 'keydown';\n }\n\n return parsedKeyCombo;\n }, {\n combo: keyComboString.split(':').shift()\n });\n}\n\nfunction parseEventString(eventString) {\n return eventString.trim().split(' ').map(function (keyComboString) {\n return parseKeyComboString(keyComboString);\n });\n}\n/**\n * `Polymer.IronA11yKeysBehavior` provides a normalized interface for processing\n * keyboard commands that pertain to [WAI-ARIA best\n * practices](http://www.w3.org/TR/wai-aria-practices/#kbd_general_binding). The\n * element takes care of browser differences with respect to Keyboard events and\n * uses an expressive syntax to filter key presses.\n *\n * Use the `keyBindings` prototype property to express what combination of keys\n * will trigger the callback. A key binding has the format\n * `\"KEY+MODIFIER:EVENT\": \"callback\"` (`\"KEY\": \"callback\"` or\n * `\"KEY:EVENT\": \"callback\"` are valid as well). Some examples:\n *\n * keyBindings: {\n * 'space': '_onKeydown', // same as 'space:keydown'\n * 'shift+tab': '_onKeydown',\n * 'enter:keypress': '_onKeypress',\n * 'esc:keyup': '_onKeyup'\n * }\n *\n * The callback will receive with an event containing the following information\n * in `event.detail`:\n *\n * _onKeydown: function(event) {\n * console.log(event.detail.combo); // KEY+MODIFIER, e.g. \"shift+tab\"\n * console.log(event.detail.key); // KEY only, e.g. \"tab\"\n * console.log(event.detail.event); // EVENT, e.g. \"keydown\"\n * console.log(event.detail.keyboardEvent); // the original KeyboardEvent\n * }\n *\n * Use the `keyEventTarget` attribute to set up event handlers on a specific\n * node.\n *\n * See the [demo source\n * code](https://github.com/PolymerElements/iron-a11y-keys-behavior/blob/master/demo/x-key-aware.html)\n * for an example.\n *\n * @demo demo/index.html\n * @polymerBehavior\n */\n\n\nexport const IronA11yKeysBehavior = {\n properties: {\n /**\n * The EventTarget that will be firing relevant KeyboardEvents. Set it to\n * `null` to disable the listeners.\n * @type {?EventTarget}\n */\n keyEventTarget: {\n type: Object,\n value: function value() {\n return this;\n }\n },\n\n /**\n * If true, this property will cause the implementing element to\n * automatically stop propagation on any handled KeyboardEvents.\n */\n stopKeyboardEventPropagation: {\n type: Boolean,\n value: false\n },\n _boundKeyHandlers: {\n type: Array,\n value: function value() {\n return [];\n }\n },\n // We use this due to a limitation in IE10 where instances will have\n // own properties of everything on the \"prototype\".\n _imperativeKeyBindings: {\n type: Object,\n value: function value() {\n return {};\n }\n }\n },\n observers: ['_resetKeyEventListeners(keyEventTarget, _boundKeyHandlers)'],\n\n /**\n * To be used to express what combination of keys will trigger the relative\n * callback. e.g. `keyBindings: { 'esc': '_onEscPressed'}`\n * @type {!Object}\n */\n keyBindings: {},\n registered: function registered() {\n this._prepKeyBindings();\n },\n attached: function attached() {\n this._listenKeyEventListeners();\n },\n detached: function detached() {\n this._unlistenKeyEventListeners();\n },\n\n /**\n * Can be used to imperatively add a key binding to the implementing\n * element. This is the imperative equivalent of declaring a keybinding\n * in the `keyBindings` prototype property.\n *\n * @param {string} eventString\n * @param {string} handlerName\n */\n addOwnKeyBinding: function addOwnKeyBinding(eventString, handlerName) {\n this._imperativeKeyBindings[eventString] = handlerName;\n\n this._prepKeyBindings();\n\n this._resetKeyEventListeners();\n },\n\n /**\n * When called, will remove all imperatively-added key bindings.\n */\n removeOwnKeyBindings: function removeOwnKeyBindings() {\n this._imperativeKeyBindings = {};\n\n this._prepKeyBindings();\n\n this._resetKeyEventListeners();\n },\n\n /**\n * Returns true if a keyboard event matches `eventString`.\n *\n * @param {KeyboardEvent} event\n * @param {string} eventString\n * @return {boolean}\n */\n keyboardEventMatchesKeys: function keyboardEventMatchesKeys(event, eventString) {\n var keyCombos = parseEventString(eventString);\n\n for (var i = 0; i < keyCombos.length; ++i) {\n if (keyComboMatchesEvent(keyCombos[i], event)) {\n return true;\n }\n }\n\n return false;\n },\n _collectKeyBindings: function _collectKeyBindings() {\n var keyBindings = this.behaviors.map(function (behavior) {\n return behavior.keyBindings;\n });\n\n if (keyBindings.indexOf(this.keyBindings) === -1) {\n keyBindings.push(this.keyBindings);\n }\n\n return keyBindings;\n },\n _prepKeyBindings: function _prepKeyBindings() {\n this._keyBindings = {};\n\n this._collectKeyBindings().forEach(function (keyBindings) {\n for (var eventString in keyBindings) {\n this._addKeyBinding(eventString, keyBindings[eventString]);\n }\n }, this);\n\n for (var eventString in this._imperativeKeyBindings) {\n this._addKeyBinding(eventString, this._imperativeKeyBindings[eventString]);\n } // Give precedence to combos with modifiers to be checked first.\n\n\n for (var eventName in this._keyBindings) {\n this._keyBindings[eventName].sort(function (kb1, kb2) {\n var b1 = kb1[0].hasModifiers;\n var b2 = kb2[0].hasModifiers;\n return b1 === b2 ? 0 : b1 ? -1 : 1;\n });\n }\n },\n _addKeyBinding: function _addKeyBinding(eventString, handlerName) {\n parseEventString(eventString).forEach(function (keyCombo) {\n this._keyBindings[keyCombo.event] = this._keyBindings[keyCombo.event] || [];\n\n this._keyBindings[keyCombo.event].push([keyCombo, handlerName]);\n }, this);\n },\n _resetKeyEventListeners: function _resetKeyEventListeners() {\n this._unlistenKeyEventListeners();\n\n if (this.isAttached) {\n this._listenKeyEventListeners();\n }\n },\n _listenKeyEventListeners: function _listenKeyEventListeners() {\n if (!this.keyEventTarget) {\n return;\n }\n\n Object.keys(this._keyBindings).forEach(function (eventName) {\n var keyBindings = this._keyBindings[eventName];\n\n var boundKeyHandler = this._onKeyBindingEvent.bind(this, keyBindings);\n\n this._boundKeyHandlers.push([this.keyEventTarget, eventName, boundKeyHandler]);\n\n this.keyEventTarget.addEventListener(eventName, boundKeyHandler);\n }, this);\n },\n _unlistenKeyEventListeners: function _unlistenKeyEventListeners() {\n var keyHandlerTuple;\n var keyEventTarget;\n var eventName;\n var boundKeyHandler;\n\n while (this._boundKeyHandlers.length) {\n // My kingdom for block-scope binding and destructuring assignment..\n keyHandlerTuple = this._boundKeyHandlers.pop();\n keyEventTarget = keyHandlerTuple[0];\n eventName = keyHandlerTuple[1];\n boundKeyHandler = keyHandlerTuple[2];\n keyEventTarget.removeEventListener(eventName, boundKeyHandler);\n }\n },\n _onKeyBindingEvent: function _onKeyBindingEvent(keyBindings, event) {\n if (this.stopKeyboardEventPropagation) {\n event.stopPropagation();\n } // if event has been already prevented, don't do anything\n\n\n if (event.defaultPrevented) {\n return;\n }\n\n for (var i = 0; i < keyBindings.length; i++) {\n var keyCombo = keyBindings[i][0];\n var handlerName = keyBindings[i][1];\n\n if (keyComboMatchesEvent(keyCombo, event)) {\n this._triggerKeyHandler(keyCombo, handlerName, event); // exit the loop if eventDefault was prevented\n\n\n if (event.defaultPrevented) {\n return;\n }\n }\n }\n },\n _triggerKeyHandler: function _triggerKeyHandler(keyCombo, handlerName, keyboardEvent) {\n var detail = Object.create(keyCombo);\n detail.keyboardEvent = keyboardEvent;\n var event = new CustomEvent(keyCombo.event, {\n detail: detail,\n cancelable: true\n });\n this[handlerName].call(this, event);\n\n if (event.defaultPrevented) {\n keyboardEvent.preventDefault();\n }\n }\n};","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport './iron-control-state.js';\nimport { IronA11yKeysBehavior } from '@polymer/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\n/**\n * @demo demo/index.html\n * @polymerBehavior IronButtonState\n */\n\nexport const IronButtonStateImpl = {\n properties: {\n /**\n * If true, the user is currently holding down the button.\n */\n pressed: {\n type: Boolean,\n readOnly: true,\n value: false,\n reflectToAttribute: true,\n observer: '_pressedChanged'\n },\n\n /**\n * If true, the button toggles the active state with each tap or press\n * of the spacebar.\n */\n toggles: {\n type: Boolean,\n value: false,\n reflectToAttribute: true\n },\n\n /**\n * If true, the button is a toggle and is currently in the active state.\n */\n active: {\n type: Boolean,\n value: false,\n notify: true,\n reflectToAttribute: true\n },\n\n /**\n * True if the element is currently being pressed by a \"pointer,\" which\n * is loosely defined as mouse or touch input (but specifically excluding\n * keyboard input).\n */\n pointerDown: {\n type: Boolean,\n readOnly: true,\n value: false\n },\n\n /**\n * True if the input device that caused the element to receive focus\n * was a keyboard.\n */\n receivedFocusFromKeyboard: {\n type: Boolean,\n readOnly: true\n },\n\n /**\n * The aria attribute to be set if the button is a toggle and in the\n * active state.\n */\n ariaActiveAttribute: {\n type: String,\n value: 'aria-pressed',\n observer: '_ariaActiveAttributeChanged'\n }\n },\n listeners: {\n down: '_downHandler',\n up: '_upHandler',\n tap: '_tapHandler'\n },\n observers: ['_focusChanged(focused)', '_activeChanged(active, ariaActiveAttribute)'],\n\n /**\n * @type {!Object}\n */\n keyBindings: {\n 'enter:keydown': '_asyncClick',\n 'space:keydown': '_spaceKeyDownHandler',\n 'space:keyup': '_spaceKeyUpHandler'\n },\n _mouseEventRe: /^mouse/,\n _tapHandler: function _tapHandler() {\n if (this.toggles) {\n // a tap is needed to toggle the active state\n this._userActivate(!this.active);\n } else {\n this.active = false;\n }\n },\n _focusChanged: function _focusChanged(focused) {\n this._detectKeyboardFocus(focused);\n\n if (!focused) {\n this._setPressed(false);\n }\n },\n _detectKeyboardFocus: function _detectKeyboardFocus(focused) {\n this._setReceivedFocusFromKeyboard(!this.pointerDown && focused);\n },\n // to emulate native checkbox, (de-)activations from a user interaction fire\n // 'change' events\n _userActivate: function _userActivate(active) {\n if (this.active !== active) {\n this.active = active;\n this.fire('change');\n }\n },\n _downHandler: function _downHandler(event) {\n this._setPointerDown(true);\n\n this._setPressed(true);\n\n this._setReceivedFocusFromKeyboard(false);\n },\n _upHandler: function _upHandler() {\n this._setPointerDown(false);\n\n this._setPressed(false);\n },\n\n /**\n * @param {!KeyboardEvent} event .\n */\n _spaceKeyDownHandler: function _spaceKeyDownHandler(event) {\n var keyboardEvent = event.detail.keyboardEvent;\n var target = dom(keyboardEvent).localTarget; // Ignore the event if this is coming from a focused light child, since that\n // element will deal with it.\n\n if (this.isLightDescendant(\n /** @type {Node} */\n target)) return;\n keyboardEvent.preventDefault();\n keyboardEvent.stopImmediatePropagation();\n\n this._setPressed(true);\n },\n\n /**\n * @param {!KeyboardEvent} event .\n */\n _spaceKeyUpHandler: function _spaceKeyUpHandler(event) {\n var keyboardEvent = event.detail.keyboardEvent;\n var target = dom(keyboardEvent).localTarget; // Ignore the event if this is coming from a focused light child, since that\n // element will deal with it.\n\n if (this.isLightDescendant(\n /** @type {Node} */\n target)) return;\n\n if (this.pressed) {\n this._asyncClick();\n }\n\n this._setPressed(false);\n },\n // trigger click asynchronously, the asynchrony is useful to allow one\n // event handler to unwind before triggering another event\n _asyncClick: function _asyncClick() {\n this.async(function () {\n this.click();\n }, 1);\n },\n // any of these changes are considered a change to button state\n _pressedChanged: function _pressedChanged(pressed) {\n this._changedButtonState();\n },\n _ariaActiveAttributeChanged: function _ariaActiveAttributeChanged(value, oldValue) {\n if (oldValue && oldValue != value && this.hasAttribute(oldValue)) {\n this.removeAttribute(oldValue);\n }\n },\n _activeChanged: function _activeChanged(active, ariaActiveAttribute) {\n if (this.toggles) {\n this.setAttribute(this.ariaActiveAttribute, active ? 'true' : 'false');\n } else {\n this.removeAttribute(this.ariaActiveAttribute);\n }\n\n this._changedButtonState();\n },\n _controlStateChanged: function _controlStateChanged() {\n if (this.disabled) {\n this._setPressed(false);\n } else {\n this._changedButtonState();\n }\n },\n // provide hook for follow-on behaviors to react to button-state\n _changedButtonState: function _changedButtonState() {\n if (this._buttonStateChanged) {\n this._buttonStateChanged(); // abstract\n\n }\n }\n};\n/** @polymerBehavior */\n\nexport const IronButtonState = [IronA11yKeysBehavior, IronButtonStateImpl];","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\n/**\n * @demo demo/index.html\n * @polymerBehavior\n */\n\nexport const IronControlState = {\n properties: {\n /**\n * If true, the element currently has focus.\n */\n focused: {\n type: Boolean,\n value: false,\n notify: true,\n readOnly: true,\n reflectToAttribute: true\n },\n\n /**\n * If true, the user cannot interact with this element.\n */\n disabled: {\n type: Boolean,\n value: false,\n notify: true,\n observer: '_disabledChanged',\n reflectToAttribute: true\n },\n\n /**\n * Value of the `tabindex` attribute before `disabled` was activated.\n * `null` means the attribute was not present.\n * @type {?string|undefined}\n */\n _oldTabIndex: {\n type: String\n },\n _boundFocusBlurHandler: {\n type: Function,\n value: function value() {\n return this._focusBlurHandler.bind(this);\n }\n }\n },\n observers: ['_changedControlState(focused, disabled)'],\n\n /**\n * @return {void}\n */\n ready: function ready() {\n this.addEventListener('focus', this._boundFocusBlurHandler, true);\n this.addEventListener('blur', this._boundFocusBlurHandler, true);\n },\n _focusBlurHandler: function _focusBlurHandler(event) {\n // Polymer takes care of retargeting events.\n this._setFocused(event.type === 'focus');\n\n return;\n },\n _disabledChanged: function _disabledChanged(disabled, old) {\n this.setAttribute('aria-disabled', disabled ? 'true' : 'false');\n this.style.pointerEvents = disabled ? 'none' : '';\n\n if (disabled) {\n // Read the `tabindex` attribute instead of the `tabIndex` property.\n // The property returns `-1` if there is no `tabindex` attribute.\n // This distinction is important when restoring the value because\n // leaving `-1` hides shadow root children from the tab order.\n this._oldTabIndex = this.getAttribute('tabindex');\n\n this._setFocused(false);\n\n this.tabIndex = -1;\n this.blur();\n } else if (this._oldTabIndex !== undefined) {\n if (this._oldTabIndex === null) {\n this.removeAttribute('tabindex');\n } else {\n this.setAttribute('tabindex', this._oldTabIndex);\n }\n }\n },\n _changedControlState: function _changedControlState() {\n // _controlStateChanged is abstract, follow-on behaviors may implement it\n if (this._controlStateChanged) {\n this._controlStateChanged();\n }\n }\n};","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { IronFormElementBehavior } from '@polymer/iron-form-element-behavior/iron-form-element-behavior.js';\nimport { IronValidatableBehavior } from '@polymer/iron-validatable-behavior/iron-validatable-behavior.js';\n/**\n * Use `IronCheckedElementBehavior` to implement a custom element that has a\n * `checked` property, which can be used for validation if the element is also\n * `required`. Element instances implementing this behavior will also be\n * registered for use in an `iron-form` element.\n *\n * @demo demo/index.html\n * @polymerBehavior IronCheckedElementBehavior\n */\n\nexport const IronCheckedElementBehaviorImpl = {\n properties: {\n /**\n * Fired when the checked state changes.\n *\n * @event iron-change\n */\n\n /**\n * Gets or sets the state, `true` is checked and `false` is unchecked.\n */\n checked: {\n type: Boolean,\n value: false,\n reflectToAttribute: true,\n notify: true,\n observer: '_checkedChanged'\n },\n\n /**\n * If true, the button toggles the active state with each tap or press\n * of the spacebar.\n */\n toggles: {\n type: Boolean,\n value: true,\n reflectToAttribute: true\n },\n\n /* Overriden from IronFormElementBehavior */\n value: {\n type: String,\n value: 'on',\n observer: '_valueChanged'\n }\n },\n observers: ['_requiredChanged(required)'],\n created: function created() {\n // Used by `iron-form` to handle the case that an element with this behavior\n // doesn't have a role of 'checkbox' or 'radio', but should still only be\n // included when the form is serialized if `this.checked === true`.\n this._hasIronCheckedElementBehavior = true;\n },\n\n /**\n * Returns false if the element is required and not checked, and true\n * otherwise.\n * @param {*=} _value Ignored.\n * @return {boolean} true if `required` is false or if `checked` is true.\n */\n _getValidity: function _getValidity(_value) {\n return this.disabled || !this.required || this.checked;\n },\n\n /**\n * Update the aria-required label when `required` is changed.\n */\n _requiredChanged: function _requiredChanged() {\n if (this.required) {\n this.setAttribute('aria-required', 'true');\n } else {\n this.removeAttribute('aria-required');\n }\n },\n\n /**\n * Fire `iron-changed` when the checked state changes.\n */\n _checkedChanged: function _checkedChanged() {\n this.active = this.checked;\n this.fire('iron-change');\n },\n\n /**\n * Reset value to 'on' if it is set to `undefined`.\n */\n _valueChanged: function _valueChanged() {\n if (this.value === undefined || this.value === null) {\n this.value = 'on';\n }\n }\n};\n/** @polymerBehavior */\n\nexport const IronCheckedElementBehavior = [IronFormElementBehavior, IronValidatableBehavior, IronCheckedElementBehaviorImpl];","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\n/**\n`Polymer.IronFitBehavior` fits an element in another element using `max-height`\nand `max-width`, and optionally centers it in the window or another element.\n\nThe element will only be sized and/or positioned if it has not already been\nsized and/or positioned by CSS.\n\nCSS properties | Action\n--------------------------|-------------------------------------------\n`position` set | Element is not centered horizontally or vertically\n`top` or `bottom` set | Element is not vertically centered\n`left` or `right` set | Element is not horizontally centered\n`max-height` set | Element respects `max-height`\n`max-width` set | Element respects `max-width`\n\n`Polymer.IronFitBehavior` can position an element into another element using\n`verticalAlign` and `horizontalAlign`. This will override the element's css\nposition.\n\n
\n \n Positioned into the container\n \n
\n\nUse `noOverlap` to position the element around another element without\noverlapping it.\n\n
\n \n Positioned around the container\n \n
\n\nUse `horizontalOffset, verticalOffset` to offset the element from its\n`positionTarget`; `Polymer.IronFitBehavior` will collapse these in order to\nkeep the element within `fitInto` boundaries, while preserving the element's\nCSS margin values.\n\n
\n \n With vertical offset\n \n
\n\n@demo demo/index.html\n@polymerBehavior\n*/\n\nexport const IronFitBehavior = {\n properties: {\n /**\n * The element that will receive a `max-height`/`width`. By default it is\n * the same as `this`, but it can be set to a child element. This is useful,\n * for example, for implementing a scrolling region inside the element.\n * @type {!Element}\n */\n sizingTarget: {\n type: Object,\n value: function value() {\n return this;\n }\n },\n\n /**\n * The element to fit `this` into.\n */\n fitInto: {\n type: Object,\n value: window\n },\n\n /**\n * Will position the element around the positionTarget without overlapping\n * it.\n */\n noOverlap: {\n type: Boolean\n },\n\n /**\n * The element that should be used to position the element. If not set, it\n * will default to the parent node.\n * @type {!Element}\n */\n positionTarget: {\n type: Element\n },\n\n /**\n * The orientation against which to align the element horizontally\n * relative to the `positionTarget`. Possible values are \"left\", \"right\",\n * \"center\", \"auto\".\n */\n horizontalAlign: {\n type: String\n },\n\n /**\n * The orientation against which to align the element vertically\n * relative to the `positionTarget`. Possible values are \"top\", \"bottom\",\n * \"middle\", \"auto\".\n */\n verticalAlign: {\n type: String\n },\n\n /**\n * If true, it will use `horizontalAlign` and `verticalAlign` values as\n * preferred alignment and if there's not enough space, it will pick the\n * values which minimize the cropping.\n */\n dynamicAlign: {\n type: Boolean\n },\n\n /**\n * A pixel value that will be added to the position calculated for the\n * given `horizontalAlign`, in the direction of alignment. You can think\n * of it as increasing or decreasing the distance to the side of the\n * screen given by `horizontalAlign`.\n *\n * If `horizontalAlign` is \"left\" or \"center\", this offset will increase or\n * decrease the distance to the left side of the screen: a negative offset\n * will move the dropdown to the left; a positive one, to the right.\n *\n * Conversely if `horizontalAlign` is \"right\", this offset will increase\n * or decrease the distance to the right side of the screen: a negative\n * offset will move the dropdown to the right; a positive one, to the left.\n */\n horizontalOffset: {\n type: Number,\n value: 0,\n notify: true\n },\n\n /**\n * A pixel value that will be added to the position calculated for the\n * given `verticalAlign`, in the direction of alignment. You can think\n * of it as increasing or decreasing the distance to the side of the\n * screen given by `verticalAlign`.\n *\n * If `verticalAlign` is \"top\" or \"middle\", this offset will increase or\n * decrease the distance to the top side of the screen: a negative offset\n * will move the dropdown upwards; a positive one, downwards.\n *\n * Conversely if `verticalAlign` is \"bottom\", this offset will increase\n * or decrease the distance to the bottom side of the screen: a negative\n * offset will move the dropdown downwards; a positive one, upwards.\n */\n verticalOffset: {\n type: Number,\n value: 0,\n notify: true\n },\n\n /**\n * Set to true to auto-fit on attach.\n */\n autoFitOnAttach: {\n type: Boolean,\n value: false\n },\n\n /** @type {?Object} */\n _fitInfo: {\n type: Object\n }\n },\n\n get _fitWidth() {\n var fitWidth;\n\n if (this.fitInto === window) {\n fitWidth = this.fitInto.innerWidth;\n } else {\n fitWidth = this.fitInto.getBoundingClientRect().width;\n }\n\n return fitWidth;\n },\n\n get _fitHeight() {\n var fitHeight;\n\n if (this.fitInto === window) {\n fitHeight = this.fitInto.innerHeight;\n } else {\n fitHeight = this.fitInto.getBoundingClientRect().height;\n }\n\n return fitHeight;\n },\n\n get _fitLeft() {\n var fitLeft;\n\n if (this.fitInto === window) {\n fitLeft = 0;\n } else {\n fitLeft = this.fitInto.getBoundingClientRect().left;\n }\n\n return fitLeft;\n },\n\n get _fitTop() {\n var fitTop;\n\n if (this.fitInto === window) {\n fitTop = 0;\n } else {\n fitTop = this.fitInto.getBoundingClientRect().top;\n }\n\n return fitTop;\n },\n\n /**\n * The element that should be used to position the element,\n * if no position target is configured.\n */\n get _defaultPositionTarget() {\n var parent = dom(this).parentNode;\n\n if (parent && parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n parent = parent.host;\n }\n\n return parent;\n },\n\n /**\n * The horizontal align value, accounting for the RTL/LTR text direction.\n */\n get _localeHorizontalAlign() {\n if (this._isRTL) {\n // In RTL, \"left\" becomes \"right\".\n if (this.horizontalAlign === 'right') {\n return 'left';\n }\n\n if (this.horizontalAlign === 'left') {\n return 'right';\n }\n }\n\n return this.horizontalAlign;\n },\n\n /**\n * True if the element should be positioned instead of centered.\n * @private\n */\n get __shouldPosition() {\n return (this.horizontalAlign || this.verticalAlign) && this.positionTarget;\n },\n\n attached: function attached() {\n // Memoize this to avoid expensive calculations & relayouts.\n // Make sure we do it only once\n if (typeof this._isRTL === 'undefined') {\n this._isRTL = window.getComputedStyle(this).direction == 'rtl';\n }\n\n this.positionTarget = this.positionTarget || this._defaultPositionTarget;\n\n if (this.autoFitOnAttach) {\n if (window.getComputedStyle(this).display === 'none') {\n setTimeout(function () {\n this.fit();\n }.bind(this));\n } else {\n // NOTE: shadydom applies distribution asynchronously\n // for performance reasons webcomponents/shadydom#120\n // Flush to get correct layout info.\n window.ShadyDOM && ShadyDOM.flush();\n this.fit();\n }\n }\n },\n detached: function detached() {\n if (this.__deferredFit) {\n clearTimeout(this.__deferredFit);\n this.__deferredFit = null;\n }\n },\n\n /**\n * Positions and fits the element into the `fitInto` element.\n */\n fit: function fit() {\n this.position();\n this.constrain();\n this.center();\n },\n\n /**\n * Memoize information needed to position and size the target element.\n * @suppress {deprecated}\n */\n _discoverInfo: function _discoverInfo() {\n if (this._fitInfo) {\n return;\n }\n\n var target = window.getComputedStyle(this);\n var sizer = window.getComputedStyle(this.sizingTarget);\n this._fitInfo = {\n inlineStyle: {\n top: this.style.top || '',\n left: this.style.left || '',\n position: this.style.position || ''\n },\n sizerInlineStyle: {\n maxWidth: this.sizingTarget.style.maxWidth || '',\n maxHeight: this.sizingTarget.style.maxHeight || '',\n boxSizing: this.sizingTarget.style.boxSizing || ''\n },\n positionedBy: {\n vertically: target.top !== 'auto' ? 'top' : target.bottom !== 'auto' ? 'bottom' : null,\n horizontally: target.left !== 'auto' ? 'left' : target.right !== 'auto' ? 'right' : null\n },\n sizedBy: {\n height: sizer.maxHeight !== 'none',\n width: sizer.maxWidth !== 'none',\n minWidth: parseInt(sizer.minWidth, 10) || 0,\n minHeight: parseInt(sizer.minHeight, 10) || 0\n },\n margin: {\n top: parseInt(target.marginTop, 10) || 0,\n right: parseInt(target.marginRight, 10) || 0,\n bottom: parseInt(target.marginBottom, 10) || 0,\n left: parseInt(target.marginLeft, 10) || 0\n }\n };\n },\n\n /**\n * Resets the target element's position and size constraints, and clear\n * the memoized data.\n */\n resetFit: function resetFit() {\n var info = this._fitInfo || {};\n\n for (var property in info.sizerInlineStyle) {\n this.sizingTarget.style[property] = info.sizerInlineStyle[property];\n }\n\n for (var property in info.inlineStyle) {\n this.style[property] = info.inlineStyle[property];\n }\n\n this._fitInfo = null;\n },\n\n /**\n * Equivalent to calling `resetFit()` and `fit()`. Useful to call this after\n * the element or the `fitInto` element has been resized, or if any of the\n * positioning properties (e.g. `horizontalAlign, verticalAlign`) is updated.\n * It preserves the scroll position of the sizingTarget.\n */\n refit: function refit() {\n var scrollLeft = this.sizingTarget.scrollLeft;\n var scrollTop = this.sizingTarget.scrollTop;\n this.resetFit();\n this.fit();\n this.sizingTarget.scrollLeft = scrollLeft;\n this.sizingTarget.scrollTop = scrollTop;\n },\n\n /**\n * Positions the element according to `horizontalAlign, verticalAlign`.\n */\n position: function position() {\n if (!this.__shouldPosition) {\n // needs to be centered, and it is done after constrain.\n return;\n }\n\n this._discoverInfo();\n\n this.style.position = 'fixed'; // Need border-box for margin/padding.\n\n this.sizingTarget.style.boxSizing = 'border-box'; // Set to 0, 0 in order to discover any offset caused by parent stacking\n // contexts.\n\n this.style.left = '0px';\n this.style.top = '0px';\n var rect = this.getBoundingClientRect();\n\n var positionRect = this.__getNormalizedRect(this.positionTarget);\n\n var fitRect = this.__getNormalizedRect(this.fitInto);\n\n var margin = this._fitInfo.margin; // Consider the margin as part of the size for position calculations.\n\n var size = {\n width: rect.width + margin.left + margin.right,\n height: rect.height + margin.top + margin.bottom\n };\n\n var position = this.__getPosition(this._localeHorizontalAlign, this.verticalAlign, size, rect, positionRect, fitRect);\n\n var left = position.left + margin.left;\n var top = position.top + margin.top; // We first limit right/bottom within fitInto respecting the margin,\n // then use those values to limit top/left.\n\n var right = Math.min(fitRect.right - margin.right, left + rect.width);\n var bottom = Math.min(fitRect.bottom - margin.bottom, top + rect.height); // Keep left/top within fitInto respecting the margin.\n\n left = Math.max(fitRect.left + margin.left, Math.min(left, right - this._fitInfo.sizedBy.minWidth));\n top = Math.max(fitRect.top + margin.top, Math.min(top, bottom - this._fitInfo.sizedBy.minHeight)); // Use right/bottom to set maxWidth/maxHeight, and respect\n // minWidth/minHeight.\n\n this.sizingTarget.style.maxWidth = Math.max(right - left, this._fitInfo.sizedBy.minWidth) + 'px';\n this.sizingTarget.style.maxHeight = Math.max(bottom - top, this._fitInfo.sizedBy.minHeight) + 'px'; // Remove the offset caused by any stacking context.\n\n this.style.left = left - rect.left + 'px';\n this.style.top = top - rect.top + 'px';\n },\n\n /**\n * Constrains the size of the element to `fitInto` by setting `max-height`\n * and/or `max-width`.\n */\n constrain: function constrain() {\n if (this.__shouldPosition) {\n return;\n }\n\n this._discoverInfo();\n\n var info = this._fitInfo; // position at (0px, 0px) if not already positioned, so we can measure the\n // natural size.\n\n if (!info.positionedBy.vertically) {\n this.style.position = 'fixed';\n this.style.top = '0px';\n }\n\n if (!info.positionedBy.horizontally) {\n this.style.position = 'fixed';\n this.style.left = '0px';\n } // need border-box for margin/padding\n\n\n this.sizingTarget.style.boxSizing = 'border-box'; // constrain the width and height if not already set\n\n var rect = this.getBoundingClientRect();\n\n if (!info.sizedBy.height) {\n this.__sizeDimension(rect, info.positionedBy.vertically, 'top', 'bottom', 'Height');\n }\n\n if (!info.sizedBy.width) {\n this.__sizeDimension(rect, info.positionedBy.horizontally, 'left', 'right', 'Width');\n }\n },\n\n /**\n * @protected\n * @deprecated\n */\n _sizeDimension: function _sizeDimension(rect, positionedBy, start, end, extent) {\n this.__sizeDimension(rect, positionedBy, start, end, extent);\n },\n\n /**\n * @private\n */\n __sizeDimension: function __sizeDimension(rect, positionedBy, start, end, extent) {\n var info = this._fitInfo;\n\n var fitRect = this.__getNormalizedRect(this.fitInto);\n\n var max = extent === 'Width' ? fitRect.width : fitRect.height;\n var flip = positionedBy === end;\n var offset = flip ? max - rect[end] : rect[start];\n var margin = info.margin[flip ? start : end];\n var offsetExtent = 'offset' + extent;\n var sizingOffset = this[offsetExtent] - this.sizingTarget[offsetExtent];\n this.sizingTarget.style['max' + extent] = max - margin - offset - sizingOffset + 'px';\n },\n\n /**\n * Centers horizontally and vertically if not already positioned. This also\n * sets `position:fixed`.\n */\n center: function center() {\n if (this.__shouldPosition) {\n return;\n }\n\n this._discoverInfo();\n\n var positionedBy = this._fitInfo.positionedBy;\n\n if (positionedBy.vertically && positionedBy.horizontally) {\n // Already positioned.\n return;\n } // Need position:fixed to center\n\n\n this.style.position = 'fixed'; // Take into account the offset caused by parents that create stacking\n // contexts (e.g. with transform: translate3d). Translate to 0,0 and\n // measure the bounding rect.\n\n if (!positionedBy.vertically) {\n this.style.top = '0px';\n }\n\n if (!positionedBy.horizontally) {\n this.style.left = '0px';\n } // It will take in consideration margins and transforms\n\n\n var rect = this.getBoundingClientRect();\n\n var fitRect = this.__getNormalizedRect(this.fitInto);\n\n if (!positionedBy.vertically) {\n var top = fitRect.top - rect.top + (fitRect.height - rect.height) / 2;\n this.style.top = top + 'px';\n }\n\n if (!positionedBy.horizontally) {\n var left = fitRect.left - rect.left + (fitRect.width - rect.width) / 2;\n this.style.left = left + 'px';\n }\n },\n __getNormalizedRect: function __getNormalizedRect(target) {\n if (target === document.documentElement || target === window) {\n return {\n top: 0,\n left: 0,\n width: window.innerWidth,\n height: window.innerHeight,\n right: window.innerWidth,\n bottom: window.innerHeight\n };\n }\n\n return target.getBoundingClientRect();\n },\n __getOffscreenArea: function __getOffscreenArea(position, size, fitRect) {\n var verticalCrop = Math.min(0, position.top) + Math.min(0, fitRect.bottom - (position.top + size.height));\n var horizontalCrop = Math.min(0, position.left) + Math.min(0, fitRect.right - (position.left + size.width));\n return Math.abs(verticalCrop) * size.width + Math.abs(horizontalCrop) * size.height;\n },\n __getPosition: function __getPosition(hAlign, vAlign, size, sizeNoMargins, positionRect, fitRect) {\n // All the possible configurations.\n // Ordered as top-left, top-right, bottom-left, bottom-right.\n var positions = [{\n verticalAlign: 'top',\n horizontalAlign: 'left',\n top: positionRect.top + this.verticalOffset,\n left: positionRect.left + this.horizontalOffset\n }, {\n verticalAlign: 'top',\n horizontalAlign: 'right',\n top: positionRect.top + this.verticalOffset,\n left: positionRect.right - size.width - this.horizontalOffset\n }, {\n verticalAlign: 'bottom',\n horizontalAlign: 'left',\n top: positionRect.bottom - size.height - this.verticalOffset,\n left: positionRect.left + this.horizontalOffset\n }, {\n verticalAlign: 'bottom',\n horizontalAlign: 'right',\n top: positionRect.bottom - size.height - this.verticalOffset,\n left: positionRect.right - size.width - this.horizontalOffset\n }];\n\n if (this.noOverlap) {\n // Duplicate.\n for (var i = 0, l = positions.length; i < l; i++) {\n var copy = {};\n\n for (var key in positions[i]) {\n copy[key] = positions[i][key];\n }\n\n positions.push(copy);\n } // Horizontal overlap only.\n\n\n positions[0].top = positions[1].top += positionRect.height;\n positions[2].top = positions[3].top -= positionRect.height; // Vertical overlap only.\n\n positions[4].left = positions[6].left += positionRect.width;\n positions[5].left = positions[7].left -= positionRect.width;\n } // Consider auto as null for coding convenience.\n\n\n vAlign = vAlign === 'auto' ? null : vAlign;\n hAlign = hAlign === 'auto' ? null : hAlign;\n\n if (!hAlign || hAlign === 'center') {\n positions.push({\n verticalAlign: 'top',\n horizontalAlign: 'center',\n top: positionRect.top + this.verticalOffset + (this.noOverlap ? positionRect.height : 0),\n left: positionRect.left - sizeNoMargins.width / 2 + positionRect.width / 2 + this.horizontalOffset\n });\n positions.push({\n verticalAlign: 'bottom',\n horizontalAlign: 'center',\n top: positionRect.bottom - size.height - this.verticalOffset - (this.noOverlap ? positionRect.height : 0),\n left: positionRect.left - sizeNoMargins.width / 2 + positionRect.width / 2 + this.horizontalOffset\n });\n }\n\n if (!vAlign || vAlign === 'middle') {\n positions.push({\n verticalAlign: 'middle',\n horizontalAlign: 'left',\n top: positionRect.top - sizeNoMargins.height / 2 + positionRect.height / 2 + this.verticalOffset,\n left: positionRect.left + this.horizontalOffset + (this.noOverlap ? positionRect.width : 0)\n });\n positions.push({\n verticalAlign: 'middle',\n horizontalAlign: 'right',\n top: positionRect.top - sizeNoMargins.height / 2 + positionRect.height / 2 + this.verticalOffset,\n left: positionRect.right - size.width - this.horizontalOffset - (this.noOverlap ? positionRect.width : 0)\n });\n }\n\n if (vAlign === 'middle' && hAlign === 'center') {\n positions.push({\n verticalAlign: 'middle',\n horizontalAlign: 'center',\n top: positionRect.top - sizeNoMargins.height / 2 + positionRect.height / 2 + this.verticalOffset,\n left: positionRect.left - sizeNoMargins.width / 2 + positionRect.width / 2 + this.horizontalOffset\n });\n }\n\n var position;\n\n for (var i = 0; i < positions.length; i++) {\n var candidate = positions[i];\n var vAlignOk = candidate.verticalAlign === vAlign;\n var hAlignOk = candidate.horizontalAlign === hAlign; // If both vAlign and hAlign are defined, return exact match.\n // For dynamicAlign and noOverlap we'll have more than one candidate, so\n // we'll have to check the offscreenArea to make the best choice.\n\n if (!this.dynamicAlign && !this.noOverlap && vAlignOk && hAlignOk) {\n position = candidate;\n break;\n } // Align is ok if alignment preferences are respected. If no preferences,\n // it is considered ok.\n\n\n var alignOk = (!vAlign || vAlignOk) && (!hAlign || hAlignOk); // Filter out elements that don't match the alignment (if defined).\n // With dynamicAlign, we need to consider all the positions to find the\n // one that minimizes the cropped area.\n\n if (!this.dynamicAlign && !alignOk) {\n continue;\n }\n\n candidate.offscreenArea = this.__getOffscreenArea(candidate, size, fitRect); // If not cropped and respects the align requirements, keep it.\n // This allows to prefer positions overlapping horizontally over the\n // ones overlapping vertically.\n\n if (candidate.offscreenArea === 0 && alignOk) {\n position = candidate;\n break;\n }\n\n position = position || candidate;\n var diff = candidate.offscreenArea - position.offscreenArea; // Check which crops less. If it crops equally, check if at least one\n // align setting is ok.\n\n if (diff < 0 || diff === 0 && (vAlignOk || hAlignOk)) {\n position = candidate;\n }\n }\n\n return position;\n }\n};","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { html } from '@polymer/polymer/lib/utils/html-tag.js';\n/**\nThe `` component provides simple ways to use\n[CSS flexible box\nlayout](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes),\nalso known as flexbox. Note that this is an old element, that was written\nbefore all modern browsers had non-prefixed flex styles. As such, nowadays you\ndon't really need to use this element anymore, and can use CSS flex styles\ndirectly in your code.\n\nThis component provides two different ways to use flexbox:\n\n1. [Layout\nclasses](https://github.com/PolymerElements/iron-flex-layout/tree/master/iron-flex-layout-classes.html).\nThe layout class stylesheet provides a simple set of class-based flexbox rules,\nthat let you specify layout properties directly in markup. You must include this\nfile in every element that needs to use them.\n\n Sample use:\n\n ```\n \n \n \n ```\n\n ```js\n import {html} from '@polymer/polymer/lib/utils/html-tag.js';\n import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';\n\n const template = html`\n \n \n
\n
horizontal layout center alignment
\n
\n `;\n document.body.appendChild(template.content);\n ```\n\n2. [Custom CSS\nmixins](https://github.com/PolymerElements/iron-flex-layout/blob/master/iron-flex-layout.html).\nThe mixin stylesheet includes custom CSS mixins that can be applied inside a CSS\nrule using the `@apply` function.\n\nPlease note that the old [/deep/ layout\nclasses](https://github.com/PolymerElements/iron-flex-layout/tree/master/classes)\nare deprecated, and should not be used. To continue using layout properties\ndirectly in markup, please switch to using the new `dom-module`-based\n[layout\nclasses](https://github.com/PolymerElements/iron-flex-layout/tree/master/iron-flex-layout-classes.html).\nPlease note that the new version does not use `/deep/`, and therefore requires\nyou to import the `dom-modules` in every element that needs to use them.\n\n@group Iron Elements\n@pseudoElement iron-flex-layout\n@demo demo/index.html\n*/\n\nconst template = html`\n\n \n\n\n \n`;\ntemplate.setAttribute('style', 'display: none;');\ndocument.head.appendChild(template.content);\nvar style = document.createElement('style');\nstyle.textContent = '[hidden] { display: none !important; }';\ndocument.head.appendChild(style);","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\n/**\n IronFormElementBehavior adds a `name`, `value` and `required` properties to\n a custom element. It mostly exists for backcompatibility with Polymer 1.x, and\n is probably not something you want to use.\n\n @demo demo/index.html\n @polymerBehavior\n */\n\nexport const IronFormElementBehavior = {\n properties: {\n /**\n * The name of this element.\n */\n name: {\n type: String\n },\n\n /**\n * The value for this element.\n * @type {*}\n */\n value: {\n notify: true,\n type: String\n },\n\n /**\n * Set to true to mark the input as required. If used in a form, a\n * custom element that uses this behavior should also use\n * IronValidatableBehavior and define a custom validation method.\n * Otherwise, a `required` element will always be considered valid.\n * It's also strongly recommended to provide a visual style for the element\n * when its value is invalid.\n */\n required: {\n type: Boolean,\n value: false\n }\n },\n // Empty implementations for backcompatibility.\n attached: function attached() {},\n detached: function detached() {}\n};","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/iron-flex-layout/iron-flex-layout.js';\nimport { IronMeta } from '@polymer/iron-meta/iron-meta.js';\nimport { Polymer } from '@polymer/polymer/lib/legacy/polymer-fn.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\nimport { html } from '@polymer/polymer/lib/utils/html-tag.js';\nimport { Base } from '@polymer/polymer/polymer-legacy.js';\n/**\n\nThe `iron-icon` element displays an icon. By default an icon renders as a 24px\nsquare.\n\nExample using src:\n\n \n\nExample setting size to 32px x 32px:\n\n \n\n \n\nThe iron elements include several sets of icons. To use the default set of\nicons, import `iron-icons.js` and use the `icon` attribute to specify an icon:\n\n \n\n \n\nTo use a different built-in set of icons, import the specific\n`iron-icons/-icons.js`, and specify the icon as `:`.\nFor example, to use a communication icon, you would use:\n\n \n\n \n\nYou can also create custom icon sets of bitmap or SVG icons.\n\nExample of using an icon named `cherry` from a custom iconset with the ID\n`fruit`:\n\n \n\nSee `` and `` for more information about how to\ncreate a custom iconset.\n\nSee the `iron-icons` demo to see the icons available in the various iconsets.\n\n### Styling\n\nThe following custom properties are available for styling:\n\nCustom property | Description | Default\n----------------|-------------|----------\n`--iron-icon` | Mixin applied to the icon | {}\n`--iron-icon-width` | Width of the icon | `24px`\n`--iron-icon-height` | Height of the icon | `24px`\n`--iron-icon-fill-color` | Fill color of the svg icon | `currentcolor`\n`--iron-icon-stroke-color` | Stroke color of the svg icon | none\n\n@group Iron Elements\n@element iron-icon\n@demo demo/index.html\n@hero hero.svg\n@homepage polymer.github.io\n*/\n\nPolymer({\n _template: html`\n \n`,\n is: 'iron-icon',\n properties: {\n /**\n * The name of the icon to use. The name should be of the form:\n * `iconset_name:icon_name`.\n */\n icon: {\n type: String\n },\n\n /**\n * The name of the theme to used, if one is specified by the\n * iconset.\n */\n theme: {\n type: String\n },\n\n /**\n * If using iron-icon without an iconset, you can set the src to be\n * the URL of an individual icon image file. Note that this will take\n * precedence over a given icon attribute.\n */\n src: {\n type: String\n },\n\n /**\n * @type {!IronMeta}\n */\n _meta: {\n value: Base.create('iron-meta', {\n type: 'iconset'\n })\n }\n },\n observers: ['_updateIcon(_meta, isAttached)', '_updateIcon(theme, isAttached)', '_srcChanged(src, isAttached)', '_iconChanged(icon, isAttached)'],\n _DEFAULT_ICONSET: 'icons',\n _iconChanged: function _iconChanged(icon) {\n var parts = (icon || '').split(':');\n this._iconName = parts.pop();\n this._iconsetName = parts.pop() || this._DEFAULT_ICONSET;\n\n this._updateIcon();\n },\n _srcChanged: function _srcChanged(src) {\n this._updateIcon();\n },\n _usesIconset: function _usesIconset() {\n return this.icon || !this.src;\n },\n\n /** @suppress {visibility} */\n _updateIcon: function _updateIcon() {\n if (this._usesIconset()) {\n if (this._img && this._img.parentNode) {\n dom(this.root).removeChild(this._img);\n }\n\n if (this._iconName === '') {\n if (this._iconset) {\n this._iconset.removeIcon(this);\n }\n } else if (this._iconsetName && this._meta) {\n this._iconset =\n /** @type {?Polymer.Iconset} */\n this._meta.byKey(this._iconsetName);\n\n if (this._iconset) {\n this._iconset.applyIcon(this, this._iconName, this.theme);\n\n this.unlisten(window, 'iron-iconset-added', '_updateIcon');\n } else {\n this.listen(window, 'iron-iconset-added', '_updateIcon');\n }\n }\n } else {\n if (this._iconset) {\n this._iconset.removeIcon(this);\n }\n\n if (!this._img) {\n this._img = document.createElement('img');\n this._img.style.width = '100%';\n this._img.style.height = '100%';\n this._img.draggable = false;\n }\n\n this._img.src = this.src;\n dom(this.root).appendChild(this._img);\n }\n }\n});","/**\n@license\nCopyright (c) 2014 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/iron-icon/iron-icon.js';\nimport '@polymer/iron-iconset-svg/iron-iconset-svg.js';\nimport { html } from '@polymer/polymer/lib/utils/html-tag.js';\n/**\n\n`iron-icons` is a utility import that includes the definition for the\n`iron-icon` element, `iron-iconset-svg` element, as well as an import for the\ndefault icon set.\n\nThe `iron-icons` directory also includes imports for additional icon sets that\ncan be loaded into your project.\n\nExample loading icon set:\n\n \n\nTo use an icon from one of these sets, first prefix your `iron-icon` with the\nicon set name, followed by a colon, \":\", and then the icon id.\n\nExample using the directions-bus icon from the maps icon set:\n\n \n\nSee [iron-icon](https://www.webcomponents.org/element/@polymer/iron-icon) for\nmore information about working with icons.\n\nSee [iron-iconset](https://www.webcomponents.org/element/@polymer/iron-iconset)\nand\n[iron-iconset-svg](https://www.webcomponents.org/element/@polymer/iron-iconset-svg)\nfor more information about how to create a custom iconset.\n\n@group Iron Elements\n@pseudoElement iron-icons\n@demo demo/index.html\n*/\n\nconst template = html`\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n`;\ndocument.head.appendChild(template.content);","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { IronMeta } from '@polymer/iron-meta/iron-meta.js';\nimport { Polymer } from '@polymer/polymer/lib/legacy/polymer-fn.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\n/**\n * The `iron-iconset-svg` element allows users to define their own icon sets\n * that contain svg icons. The svg icon elements should be children of the\n * `iron-iconset-svg` element. Multiple icons should be given distinct id's.\n *\n * Using svg elements to create icons has a few advantages over traditional\n * bitmap graphics like jpg or png. Icons that use svg are vector based so\n * they are resolution independent and should look good on any device. They\n * are stylable via css. Icons can be themed, colorized, and even animated.\n *\n * Example:\n *\n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n *\n * This will automatically register the icon set \"my-svg-icons\" to the iconset\n * database. To use these icons from within another element, make a\n * `iron-iconset` element and call the `byId` method\n * to retrieve a given iconset. To apply a particular icon inside an\n * element use the `applyIcon` method. For example:\n *\n * iconset.applyIcon(iconNode, 'car');\n *\n * @element iron-iconset-svg\n * @demo demo/index.html\n * @implements {Polymer.Iconset}\n */\n\nPolymer({\n is: 'iron-iconset-svg',\n properties: {\n /**\n * The name of the iconset.\n */\n name: {\n type: String,\n observer: '_nameChanged'\n },\n\n /**\n * The size of an individual icon. Note that icons must be square.\n */\n size: {\n type: Number,\n value: 24\n },\n\n /**\n * Set to true to enable mirroring of icons where specified when they are\n * stamped. Icons that should be mirrored should be decorated with a\n * `mirror-in-rtl` attribute.\n *\n * NOTE: For performance reasons, direction will be resolved once per\n * document per iconset, so moving icons in and out of RTL subtrees will\n * not cause their mirrored state to change.\n */\n rtlMirroring: {\n type: Boolean,\n value: false\n },\n\n /**\n * Set to true to measure RTL based on the dir attribute on the body or\n * html elements (measured on document.body or document.documentElement as\n * available).\n */\n useGlobalRtlAttribute: {\n type: Boolean,\n value: false\n }\n },\n created: function created() {\n this._meta = new IronMeta({\n type: 'iconset',\n key: null,\n value: null\n });\n },\n attached: function attached() {\n this.style.display = 'none';\n },\n\n /**\n * Construct an array of all icon names in this iconset.\n *\n * @return {!Array} Array of icon names.\n */\n getIconNames: function getIconNames() {\n this._icons = this._createIconMap();\n return Object.keys(this._icons).map(function (n) {\n return this.name + ':' + n;\n }, this);\n },\n\n /**\n * Applies an icon to the given element.\n *\n * An svg icon is prepended to the element's shadowRoot if it exists,\n * otherwise to the element itself.\n *\n * If RTL mirroring is enabled, and the icon is marked to be mirrored in\n * RTL, the element will be tested (once and only once ever for each\n * iconset) to determine the direction of the subtree the element is in.\n * This direction will apply to all future icon applications, although only\n * icons marked to be mirrored will be affected.\n *\n * @method applyIcon\n * @param {Element} element Element to which the icon is applied.\n * @param {string} iconName Name of the icon to apply.\n * @return {?Element} The svg element which renders the icon.\n */\n applyIcon: function applyIcon(element, iconName) {\n // Remove old svg element\n this.removeIcon(element); // install new svg element\n\n var svg = this._cloneIcon(iconName, this.rtlMirroring && this._targetIsRTL(element));\n\n if (svg) {\n // insert svg element into shadow root, if it exists\n var pde = dom(element.root || element);\n pde.insertBefore(svg, pde.childNodes[0]);\n return element._svgIcon = svg;\n }\n\n return null;\n },\n\n /**\n * Remove an icon from the given element by undoing the changes effected\n * by `applyIcon`.\n *\n * @param {Element} element The element from which the icon is removed.\n */\n removeIcon: function removeIcon(element) {\n // Remove old svg element\n if (element._svgIcon) {\n dom(element.root || element).removeChild(element._svgIcon);\n element._svgIcon = null;\n }\n },\n\n /**\n * Measures and memoizes the direction of the element. Note that this\n * measurement is only done once and the result is memoized for future\n * invocations.\n */\n _targetIsRTL: function _targetIsRTL(target) {\n if (this.__targetIsRTL == null) {\n if (this.useGlobalRtlAttribute) {\n var globalElement = document.body && document.body.hasAttribute('dir') ? document.body : document.documentElement;\n this.__targetIsRTL = globalElement.getAttribute('dir') === 'rtl';\n } else {\n if (target && target.nodeType !== Node.ELEMENT_NODE) {\n target = target.host;\n }\n\n this.__targetIsRTL = target && window.getComputedStyle(target)['direction'] === 'rtl';\n }\n }\n\n return this.__targetIsRTL;\n },\n\n /**\n *\n * When name is changed, register iconset metadata\n *\n */\n _nameChanged: function _nameChanged() {\n this._meta.value = null;\n this._meta.key = this.name;\n this._meta.value = this;\n this.async(function () {\n this.fire('iron-iconset-added', this, {\n node: window\n });\n });\n },\n\n /**\n * Create a map of child SVG elements by id.\n *\n * @return {!Object} Map of id's to SVG elements.\n */\n _createIconMap: function _createIconMap() {\n // Objects chained to Object.prototype (`{}`) have members. Specifically,\n // on FF there is a `watch` method that confuses the icon map, so we\n // need to use a null-based object here.\n var icons = Object.create(null);\n dom(this).querySelectorAll('[id]').forEach(function (icon) {\n icons[icon.id] = icon;\n });\n return icons;\n },\n\n /**\n * Produce installable clone of the SVG element matching `id` in this\n * iconset, or `undefined` if there is no matching element.\n *\n * @return {Element} Returns an installable clone of the SVG element\n * matching `id`.\n */\n _cloneIcon: function _cloneIcon(id, mirrorAllowed) {\n // create the icon map on-demand, since the iconset itself has no discrete\n // signal to know when it's children are fully parsed\n this._icons = this._icons || this._createIconMap();\n return this._prepareSvgClone(this._icons[id], this.size, mirrorAllowed);\n },\n\n /**\n * @param {Element} sourceSvg\n * @param {number} size\n * @param {Boolean} mirrorAllowed\n * @return {Element}\n */\n _prepareSvgClone: function _prepareSvgClone(sourceSvg, size, mirrorAllowed) {\n if (sourceSvg) {\n var content = sourceSvg.cloneNode(true),\n svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),\n viewBox = content.getAttribute('viewBox') || '0 0 ' + size + ' ' + size,\n cssText = 'pointer-events: none; display: block; width: 100%; height: 100%;';\n\n if (mirrorAllowed && content.hasAttribute('mirror-in-rtl')) {\n cssText += '-webkit-transform:scale(-1,1);transform:scale(-1,1);transform-origin:center;';\n }\n\n svg.setAttribute('viewBox', viewBox);\n svg.setAttribute('preserveAspectRatio', 'xMidYMid meet');\n svg.setAttribute('focusable', 'false'); // TODO(dfreedm): `pointer-events: none` works around\n // https://crbug.com/370136\n // TODO(sjmiles): inline style may not be ideal, but avoids requiring a\n // shadow-root\n\n svg.style.cssText = cssText;\n svg.appendChild(content).removeAttribute('id');\n return svg;\n }\n\n return null;\n }\n});","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { IronA11yAnnouncer } from '@polymer/iron-a11y-announcer/iron-a11y-announcer.js';\nimport { IronValidatableBehavior } from '@polymer/iron-validatable-behavior/iron-validatable-behavior.js';\nimport { Polymer } from '@polymer/polymer/lib/legacy/polymer-fn.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\nimport { html } from '@polymer/polymer/lib/utils/html-tag.js';\n/**\n`` is a wrapper to a native `` element, that adds two-way\nbinding and prevention of invalid input. To use it, you must distribute a native\n`` yourself. You can continue to use the native `input` as you would\nnormally:\n\n \n \n \n\n \n \n \n\n### Two-way binding\n\nBy default you can only get notified of changes to a native ``'s `value`\ndue to user input:\n\n \n\nThis means that if you imperatively set the value (i.e. `someNativeInput.value =\n'foo'`), no events will be fired and this change cannot be observed.\n\n`iron-input` adds the `bind-value` property that mirrors the native `input`'s\n'`value` property; this property can be used for two-way data binding.\n`bind-value` will notify if it is changed either by user input or by script.\n\n \n \n \n\nNote: this means that if you want to imperatively set the native `input`'s, you\n_must_ set `bind-value` instead, so that the wrapper `iron-input` can be\nnotified.\n\n### Validation\n\n`iron-input` uses the native `input`'s validation. For simplicity, `iron-input`\nhas a `validate()` method (which internally just checks the distributed\n`input`'s validity), which sets an `invalid` attribute that can also be used for\nstyling.\n\nTo validate automatically as you type, you can use the `auto-validate`\nattribute.\n\n`iron-input` also fires an `iron-input-validate` event after `validate()` is\ncalled. You can use it to implement a custom validator:\n\n var CatsOnlyValidator = {\n validate: function(ironInput) {\n var valid = !ironInput.bindValue || ironInput.bindValue === 'cat';\n ironInput.invalid = !valid;\n return valid;\n }\n }\n ironInput.addEventListener('iron-input-validate', function() {\n CatsOnly.validate(input2);\n });\n\nYou can also use an element implementing an\n[`IronValidatorBehavior`](/element/PolymerElements/iron-validatable-behavior).\nThis example can also be found in the demo for this element:\n\n \n \n \n\n### Preventing invalid input\n\nIt may be desirable to only allow users to enter certain characters. You can use\nthe `allowed-pattern` attribute to accomplish this. This feature is separate\nfrom validation, and `allowed-pattern` does not affect how the input is\nvalidated.\n\n // Only allow typing digits, but a valid input has exactly 5 digits.\n \n \n \n\n@demo demo/index.html\n*/\n\nPolymer({\n _template: html`\n \n \n`,\n is: 'iron-input',\n behaviors: [IronValidatableBehavior],\n\n /**\n * Fired whenever `validate()` is called.\n *\n * @event iron-input-validate\n */\n properties: {\n /**\n * Use this property instead of `value` for two-way data binding, or to\n * set a default value for the input. **Do not** use the distributed\n * input's `value` property to set a default value.\n */\n bindValue: {\n type: String,\n value: ''\n },\n\n /**\n * Computed property that echoes `bindValue` (mostly used for Polymer 1.0\n * backcompatibility, if you were one-way binding to the Polymer 1.0\n * `input is=\"iron-input\"` value attribute).\n */\n value: {\n type: String,\n computed: '_computeValue(bindValue)'\n },\n\n /**\n * Regex-like list of characters allowed as input; all characters not in the\n * list will be rejected. The recommended format should be a list of allowed\n * characters, for example, `[a-zA-Z0-9.+-!;:]`.\n *\n * This pattern represents the allowed characters for the field; as the user\n * inputs text, each individual character will be checked against the\n * pattern (rather than checking the entire value as a whole). If a\n * character is not a match, it will be rejected.\n *\n * Pasted input will have each character checked individually; if any\n * character doesn't match `allowedPattern`, the entire pasted string will\n * be rejected.\n *\n * Note: if you were using `iron-input` in 1.0, you were also required to\n * set `prevent-invalid-input`. This is no longer needed as of Polymer 2.0,\n * and will be set automatically for you if an `allowedPattern` is provided.\n *\n */\n allowedPattern: {\n type: String\n },\n\n /**\n * Set to true to auto-validate the input value as you type.\n */\n autoValidate: {\n type: Boolean,\n value: false\n },\n\n /**\n * The native input element.\n */\n _inputElement: Object\n },\n observers: ['_bindValueChanged(bindValue, _inputElement)'],\n listeners: {\n 'input': '_onInput',\n 'keypress': '_onKeypress'\n },\n created: function created() {\n IronA11yAnnouncer.requestAvailability();\n this._previousValidInput = '';\n this._patternAlreadyChecked = false;\n },\n attached: function attached() {\n // If the input is added at a later time, update the internal reference.\n this._observer = dom(this).observeNodes(function (info) {\n this._initSlottedInput();\n }.bind(this));\n },\n detached: function detached() {\n if (this._observer) {\n dom(this).unobserveNodes(this._observer);\n this._observer = null;\n }\n },\n\n /**\n * Returns the distributed input element.\n */\n get inputElement() {\n return this._inputElement;\n },\n\n _initSlottedInput: function _initSlottedInput() {\n this._inputElement = this.getEffectiveChildren()[0];\n\n if (this.inputElement && this.inputElement.value) {\n this.bindValue = this.inputElement.value;\n }\n\n this.fire('iron-input-ready');\n },\n\n get _patternRegExp() {\n var pattern;\n\n if (this.allowedPattern) {\n pattern = new RegExp(this.allowedPattern);\n } else {\n switch (this.inputElement.type) {\n case 'number':\n pattern = /[0-9.,e-]/;\n break;\n }\n }\n\n return pattern;\n },\n\n /**\n * @suppress {checkTypes}\n */\n _bindValueChanged: function _bindValueChanged(bindValue, inputElement) {\n // The observer could have run before attached() when we have actually\n // initialized this property.\n if (!inputElement) {\n return;\n }\n\n if (bindValue === undefined) {\n inputElement.value = null;\n } else if (bindValue !== inputElement.value) {\n this.inputElement.value = bindValue;\n }\n\n if (this.autoValidate) {\n this.validate();\n } // manually notify because we don't want to notify until after setting value\n\n\n this.fire('bind-value-changed', {\n value: bindValue\n });\n },\n _onInput: function _onInput() {\n // Need to validate each of the characters pasted if they haven't\n // been validated inside `_onKeypress` already.\n if (this.allowedPattern && !this._patternAlreadyChecked) {\n var valid = this._checkPatternValidity();\n\n if (!valid) {\n this._announceInvalidCharacter('Invalid string of characters not entered.');\n\n this.inputElement.value = this._previousValidInput;\n }\n }\n\n this.bindValue = this._previousValidInput = this.inputElement.value;\n this._patternAlreadyChecked = false;\n },\n _isPrintable: function _isPrintable(event) {\n // What a control/printable character is varies wildly based on the browser.\n // - most control characters (arrows, backspace) do not send a `keypress`\n // event\n // in Chrome, but the *do* on Firefox\n // - in Firefox, when they do send a `keypress` event, control chars have\n // a charCode = 0, keyCode = xx (for ex. 40 for down arrow)\n // - printable characters always send a keypress event.\n // - in Firefox, printable chars always have a keyCode = 0. In Chrome, the\n // keyCode\n // always matches the charCode.\n // None of this makes any sense.\n // For these keys, ASCII code == browser keycode.\n var anyNonPrintable = event.keyCode == 8 || // backspace\n event.keyCode == 9 || // tab\n event.keyCode == 13 || // enter\n event.keyCode == 27; // escape\n // For these keys, make sure it's a browser keycode and not an ASCII code.\n\n var mozNonPrintable = event.keyCode == 19 || // pause\n event.keyCode == 20 || // caps lock\n event.keyCode == 45 || // insert\n event.keyCode == 46 || // delete\n event.keyCode == 144 || // num lock\n event.keyCode == 145 || // scroll lock\n event.keyCode > 32 && event.keyCode < 41 || // page up/down, end, home, arrows\n event.keyCode > 111 && event.keyCode < 124; // fn keys\n\n return !anyNonPrintable && !(event.charCode == 0 && mozNonPrintable);\n },\n _onKeypress: function _onKeypress(event) {\n if (!this.allowedPattern && this.inputElement.type !== 'number') {\n return;\n }\n\n var regexp = this._patternRegExp;\n\n if (!regexp) {\n return;\n } // Handle special keys and backspace\n\n\n if (event.metaKey || event.ctrlKey || event.altKey) {\n return;\n } // Check the pattern either here or in `_onInput`, but not in both.\n\n\n this._patternAlreadyChecked = true;\n var thisChar = String.fromCharCode(event.charCode);\n\n if (this._isPrintable(event) && !regexp.test(thisChar)) {\n event.preventDefault();\n\n this._announceInvalidCharacter('Invalid character ' + thisChar + ' not entered.');\n }\n },\n _checkPatternValidity: function _checkPatternValidity() {\n var regexp = this._patternRegExp;\n\n if (!regexp) {\n return true;\n }\n\n for (var i = 0; i < this.inputElement.value.length; i++) {\n if (!regexp.test(this.inputElement.value[i])) {\n return false;\n }\n }\n\n return true;\n },\n\n /**\n * Returns true if `value` is valid. The validator provided in `validator`\n * will be used first, then any constraints.\n * @return {boolean} True if the value is valid.\n */\n validate: function validate() {\n if (!this.inputElement) {\n this.invalid = false;\n return true;\n } // Use the nested input's native validity.\n\n\n var valid = this.inputElement.checkValidity(); // Only do extra checking if the browser thought this was valid.\n\n if (valid) {\n // Empty, required input is invalid\n if (this.required && this.bindValue === '') {\n valid = false;\n } else if (this.hasValidator()) {\n valid = IronValidatableBehavior.validate.call(this, this.bindValue);\n }\n }\n\n this.invalid = !valid;\n this.fire('iron-input-validate');\n return valid;\n },\n _announceInvalidCharacter: function _announceInvalidCharacter(message) {\n this.fire('iron-announce', {\n text: message\n });\n },\n _computeValue: function _computeValue(bindValue) {\n return bindValue;\n }\n});","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { IronA11yKeysBehavior } from '@polymer/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';\nimport { IronMultiSelectableBehavior, IronMultiSelectableBehaviorImpl } from '@polymer/iron-selector/iron-multi-selectable.js';\nimport { IronSelectableBehavior } from '@polymer/iron-selector/iron-selectable.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\n/**\n * `IronMenuBehavior` implements accessible menu behavior.\n *\n * @demo demo/index.html\n * @polymerBehavior IronMenuBehavior\n */\n\nexport const IronMenuBehaviorImpl = {\n properties: {\n /**\n * Returns the currently focused item.\n * @type {?Object}\n */\n focusedItem: {\n observer: '_focusedItemChanged',\n readOnly: true,\n type: Object\n },\n\n /**\n * The attribute to use on menu items to look up the item title. Typing the\n * first letter of an item when the menu is open focuses that item. If\n * unset, `textContent` will be used.\n */\n attrForItemTitle: {\n type: String\n },\n\n /**\n * @type {boolean}\n */\n disabled: {\n type: Boolean,\n value: false,\n observer: '_disabledChanged'\n }\n },\n\n /**\n * The list of keys has been taken from\n * https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/getModifierState\n * @private\n */\n _MODIFIER_KEYS: ['Alt', 'AltGraph', 'CapsLock', 'Control', 'Fn', 'FnLock', 'Hyper', 'Meta', 'NumLock', 'OS', 'ScrollLock', 'Shift', 'Super', 'Symbol', 'SymbolLock'],\n\n /** @private */\n _SEARCH_RESET_TIMEOUT_MS: 1000,\n\n /** @private */\n _previousTabIndex: 0,\n hostAttributes: {\n 'role': 'menu'\n },\n observers: ['_updateMultiselectable(multi)'],\n listeners: {\n 'focus': '_onFocus',\n 'keydown': '_onKeydown',\n 'iron-items-changed': '_onIronItemsChanged'\n },\n\n /**\n * @type {!Object}\n */\n keyBindings: {\n 'up': '_onUpKey',\n 'down': '_onDownKey',\n 'esc': '_onEscKey',\n 'shift+tab:keydown': '_onShiftTabDown'\n },\n attached: function attached() {\n this._resetTabindices();\n },\n\n /**\n * Selects the given value. If the `multi` property is true, then the selected\n * state of the `value` will be toggled; otherwise the `value` will be\n * selected.\n *\n * @param {string|number} value the value to select.\n */\n select: function select(value) {\n // Cancel automatically focusing a default item if the menu received focus\n // through a user action selecting a particular item.\n if (this._defaultFocusAsync) {\n this.cancelAsync(this._defaultFocusAsync);\n this._defaultFocusAsync = null;\n }\n\n var item = this._valueToItem(value);\n\n if (item && item.hasAttribute('disabled')) return;\n\n this._setFocusedItem(item);\n\n IronMultiSelectableBehaviorImpl.select.apply(this, arguments);\n },\n\n /**\n * Resets all tabindex attributes to the appropriate value based on the\n * current selection state. The appropriate value is `0` (focusable) for\n * the default selected item, and `-1` (not keyboard focusable) for all\n * other items. Also sets the correct initial values for aria-selected\n * attribute, true for default selected item and false for others.\n */\n _resetTabindices: function _resetTabindices() {\n var firstSelectedItem = this.multi ? this.selectedItems && this.selectedItems[0] : this.selectedItem;\n this.items.forEach(function (item) {\n item.setAttribute('tabindex', item === firstSelectedItem ? '0' : '-1');\n item.setAttribute('aria-selected', this._selection.isSelected(item));\n }, this);\n },\n\n /**\n * Sets appropriate ARIA based on whether or not the menu is meant to be\n * multi-selectable.\n *\n * @param {boolean} multi True if the menu should be multi-selectable.\n */\n _updateMultiselectable: function _updateMultiselectable(multi) {\n if (multi) {\n this.setAttribute('aria-multiselectable', 'true');\n } else {\n this.removeAttribute('aria-multiselectable');\n }\n },\n\n /**\n * Given a KeyboardEvent, this method will focus the appropriate item in the\n * menu (if there is a relevant item, and it is possible to focus it).\n *\n * @param {KeyboardEvent} event A KeyboardEvent.\n */\n _focusWithKeyboardEvent: function _focusWithKeyboardEvent(event) {\n // Make sure that the key pressed is not a modifier key.\n // getModifierState is not being used, as it is not available in Safari\n // earlier than 10.0.2 (https://trac.webkit.org/changeset/206725/webkit)\n if (this._MODIFIER_KEYS.indexOf(event.key) !== -1) return;\n this.cancelDebouncer('_clearSearchText');\n var searchText = this._searchText || '';\n var key = event.key && event.key.length == 1 ? event.key : String.fromCharCode(event.keyCode);\n searchText += key.toLocaleLowerCase();\n var searchLength = searchText.length;\n\n for (var i = 0, item; item = this.items[i]; i++) {\n if (item.hasAttribute('disabled')) {\n continue;\n }\n\n var attr = this.attrForItemTitle || 'textContent';\n var title = (item[attr] || item.getAttribute(attr) || '').trim();\n\n if (title.length < searchLength) {\n continue;\n }\n\n if (title.slice(0, searchLength).toLocaleLowerCase() == searchText) {\n this._setFocusedItem(item);\n\n break;\n }\n }\n\n this._searchText = searchText;\n this.debounce('_clearSearchText', this._clearSearchText, this._SEARCH_RESET_TIMEOUT_MS);\n },\n _clearSearchText: function _clearSearchText() {\n this._searchText = '';\n },\n\n /**\n * Focuses the previous item (relative to the currently focused item) in the\n * menu, disabled items will be skipped.\n * Loop until length + 1 to handle case of single item in menu.\n */\n _focusPrevious: function _focusPrevious() {\n var length = this.items.length;\n var curFocusIndex = Number(this.indexOf(this.focusedItem));\n\n for (var i = 1; i < length + 1; i++) {\n var item = this.items[(curFocusIndex - i + length) % length];\n\n if (!item.hasAttribute('disabled')) {\n var owner = dom(item).getOwnerRoot() || document;\n\n this._setFocusedItem(item); // Focus might not have worked, if the element was hidden or not\n // focusable. In that case, try again.\n\n\n if (dom(owner).activeElement == item) {\n return;\n }\n }\n }\n },\n\n /**\n * Focuses the next item (relative to the currently focused item) in the\n * menu, disabled items will be skipped.\n * Loop until length + 1 to handle case of single item in menu.\n */\n _focusNext: function _focusNext() {\n var length = this.items.length;\n var curFocusIndex = Number(this.indexOf(this.focusedItem));\n\n for (var i = 1; i < length + 1; i++) {\n var item = this.items[(curFocusIndex + i) % length];\n\n if (!item.hasAttribute('disabled')) {\n var owner = dom(item).getOwnerRoot() || document;\n\n this._setFocusedItem(item); // Focus might not have worked, if the element was hidden or not\n // focusable. In that case, try again.\n\n\n if (dom(owner).activeElement == item) {\n return;\n }\n }\n }\n },\n\n /**\n * Mutates items in the menu based on provided selection details, so that\n * all items correctly reflect selection state.\n *\n * @param {Element} item An item in the menu.\n * @param {boolean} isSelected True if the item should be shown in a\n * selected state, otherwise false.\n */\n _applySelection: function _applySelection(item, isSelected) {\n if (isSelected) {\n item.setAttribute('aria-selected', 'true');\n } else {\n item.setAttribute('aria-selected', 'false');\n }\n\n IronSelectableBehavior._applySelection.apply(this, arguments);\n },\n\n /**\n * Discretely updates tabindex values among menu items as the focused item\n * changes.\n *\n * @param {Element} focusedItem The element that is currently focused.\n * @param {?Element} old The last element that was considered focused, if\n * applicable.\n */\n _focusedItemChanged: function _focusedItemChanged(focusedItem, old) {\n old && old.setAttribute('tabindex', '-1');\n\n if (focusedItem && !focusedItem.hasAttribute('disabled') && !this.disabled) {\n focusedItem.setAttribute('tabindex', '0');\n focusedItem.focus();\n }\n },\n\n /**\n * A handler that responds to mutation changes related to the list of items\n * in the menu.\n *\n * @param {CustomEvent} event An event containing mutation records as its\n * detail.\n */\n _onIronItemsChanged: function _onIronItemsChanged(event) {\n if (event.detail.addedNodes.length) {\n this._resetTabindices();\n }\n },\n\n /**\n * Handler that is called when a shift+tab keypress is detected by the menu.\n *\n * @param {CustomEvent} event A key combination event.\n */\n _onShiftTabDown: function _onShiftTabDown(event) {\n var oldTabIndex = this.getAttribute('tabindex');\n IronMenuBehaviorImpl._shiftTabPressed = true;\n\n this._setFocusedItem(null);\n\n this.setAttribute('tabindex', '-1');\n this.async(function () {\n this.setAttribute('tabindex', oldTabIndex);\n IronMenuBehaviorImpl._shiftTabPressed = false; // NOTE(cdata): polymer/polymer#1305\n }, 1);\n },\n\n /**\n * Handler that is called when the menu receives focus.\n *\n * @param {FocusEvent} event A focus event.\n */\n _onFocus: function _onFocus(event) {\n if (IronMenuBehaviorImpl._shiftTabPressed) {\n // do not focus the menu itself\n return;\n } // Do not focus the selected tab if the deepest target is part of the\n // menu element's local DOM and is focusable.\n\n\n var rootTarget =\n /** @type {?HTMLElement} */\n dom(event).rootTarget;\n\n if (rootTarget !== this && typeof rootTarget.tabIndex !== 'undefined' && !this.isLightDescendant(rootTarget)) {\n return;\n } // clear the cached focus item\n\n\n this._defaultFocusAsync = this.async(function () {\n // focus the selected item when the menu receives focus, or the first item\n // if no item is selected\n var firstSelectedItem = this.multi ? this.selectedItems && this.selectedItems[0] : this.selectedItem;\n\n this._setFocusedItem(null);\n\n if (firstSelectedItem) {\n this._setFocusedItem(firstSelectedItem);\n } else if (this.items[0]) {\n // We find the first none-disabled item (if one exists)\n this._focusNext();\n }\n });\n },\n\n /**\n * Handler that is called when the up key is pressed.\n *\n * @param {CustomEvent} event A key combination event.\n */\n _onUpKey: function _onUpKey(event) {\n // up and down arrows moves the focus\n this._focusPrevious();\n\n event.detail.keyboardEvent.preventDefault();\n },\n\n /**\n * Handler that is called when the down key is pressed.\n *\n * @param {CustomEvent} event A key combination event.\n */\n _onDownKey: function _onDownKey(event) {\n this._focusNext();\n\n event.detail.keyboardEvent.preventDefault();\n },\n\n /**\n * Handler that is called when the esc key is pressed.\n *\n * @param {CustomEvent} event A key combination event.\n */\n _onEscKey: function _onEscKey(event) {\n var focusedItem = this.focusedItem;\n\n if (focusedItem) {\n focusedItem.blur();\n }\n },\n\n /**\n * Handler that is called when a keydown event is detected.\n *\n * @param {KeyboardEvent} event A keyboard event.\n */\n _onKeydown: function _onKeydown(event) {\n if (!this.keyboardEventMatchesKeys(event, 'up down esc')) {\n // all other keys focus the menu item starting with that character\n this._focusWithKeyboardEvent(event);\n }\n\n event.stopPropagation();\n },\n // override _activateHandler\n _activateHandler: function _activateHandler(event) {\n IronSelectableBehavior._activateHandler.call(this, event);\n\n event.stopPropagation();\n },\n\n /**\n * Updates this element's tab index when it's enabled/disabled.\n * @param {boolean} disabled\n */\n _disabledChanged: function _disabledChanged(disabled) {\n if (disabled) {\n this._previousTabIndex = this.hasAttribute('tabindex') ? this.tabIndex : 0;\n this.removeAttribute('tabindex'); // No tabindex means not tab-able or select-able.\n } else if (!this.hasAttribute('tabindex')) {\n this.setAttribute('tabindex', this._previousTabIndex);\n }\n }\n};\nIronMenuBehaviorImpl._shiftTabPressed = false;\n/** @polymerBehavior */\n\nexport const IronMenuBehavior = [IronMultiSelectableBehavior, IronA11yKeysBehavior, IronMenuBehaviorImpl];","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { IronMenuBehavior } from './iron-menu-behavior.js';\n/**\n * `IronMenubarBehavior` implements accessible menubar behavior.\n *\n * @polymerBehavior IronMenubarBehavior\n */\n\nexport const IronMenubarBehaviorImpl = {\n hostAttributes: {\n 'role': 'menubar'\n },\n\n /**\n * @type {!Object}\n */\n keyBindings: {\n 'left': '_onLeftKey',\n 'right': '_onRightKey'\n },\n _onUpKey: function _onUpKey(event) {\n this.focusedItem.click();\n event.detail.keyboardEvent.preventDefault();\n },\n _onDownKey: function _onDownKey(event) {\n this.focusedItem.click();\n event.detail.keyboardEvent.preventDefault();\n },\n\n get _isRTL() {\n return window.getComputedStyle(this)['direction'] === 'rtl';\n },\n\n _onLeftKey: function _onLeftKey(event) {\n if (this._isRTL) {\n this._focusNext();\n } else {\n this._focusPrevious();\n }\n\n event.detail.keyboardEvent.preventDefault();\n },\n _onRightKey: function _onRightKey(event) {\n if (this._isRTL) {\n this._focusPrevious();\n } else {\n this._focusNext();\n }\n\n event.detail.keyboardEvent.preventDefault();\n },\n _onKeydown: function _onKeydown(event) {\n if (this.keyboardEventMatchesKeys(event, 'up down left right esc')) {\n return;\n } // all other keys focus the menu item starting with that character\n\n\n this._focusWithKeyboardEvent(event);\n }\n};\n/** @polymerBehavior */\n\nexport const IronMenubarBehavior = [IronMenuBehavior, IronMenubarBehaviorImpl];","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { Polymer } from '@polymer/polymer/lib/legacy/polymer-fn.js';\nexport class IronMeta {\n /**\n * @param {{\n * type: (string|null|undefined),\n * key: (string|null|undefined),\n * value: *,\n * }=} options\n */\n constructor(options) {\n IronMeta[' '](options);\n /** @type {string} */\n\n this.type = options && options.type || 'default';\n /** @type {string|null|undefined} */\n\n this.key = options && options.key;\n\n if (options && 'value' in options) {\n /** @type {*} */\n this.value = options.value;\n }\n }\n /** @return {*} */\n\n\n get value() {\n var type = this.type;\n var key = this.key;\n\n if (type && key) {\n return IronMeta.types[type] && IronMeta.types[type][key];\n }\n }\n /** @param {*} value */\n\n\n set value(value) {\n var type = this.type;\n var key = this.key;\n\n if (type && key) {\n type = IronMeta.types[type] = IronMeta.types[type] || {};\n\n if (value == null) {\n delete type[key];\n } else {\n type[key] = value;\n }\n }\n }\n /** @return {!Array<*>} */\n\n\n get list() {\n var type = this.type;\n\n if (type) {\n var items = IronMeta.types[this.type];\n\n if (!items) {\n return [];\n }\n\n return Object.keys(items).map(function (key) {\n return metaDatas[this.type][key];\n }, this);\n }\n }\n /**\n * @param {string} key\n * @return {*}\n */\n\n\n byKey(key) {\n this.key = key;\n return this.value;\n }\n\n}\n; // This function is used to convince Closure not to remove constructor calls\n// for instances that are not held anywhere. For example, when\n// `new IronMeta({...})` is used only for the side effect of adding a value.\n\nIronMeta[' '] = function () {};\n\nIronMeta.types = {};\nvar metaDatas = IronMeta.types;\n/**\n`iron-meta` is a generic element you can use for sharing information across the\nDOM tree. It uses [monostate pattern](http://c2.com/cgi/wiki?MonostatePattern)\nsuch that any instance of iron-meta has access to the shared information. You\ncan use `iron-meta` to share whatever you want (or create an extension [like\nx-meta] for enhancements).\n\nThe `iron-meta` instances containing your actual data can be loaded in an\nimport, or constructed in any way you see fit. The only requirement is that you\ncreate them before you try to access them.\n\nExamples:\n\nIf I create an instance like this:\n\n \n\nNote that value=\"foo/bar\" is the metadata I've defined. I could define more\nattributes or use child nodes to define additional metadata.\n\nNow I can access that element (and it's metadata) from any iron-meta instance\nvia the byKey method, e.g.\n\n meta.byKey('info');\n\nPure imperative form would be like:\n\n document.createElement('iron-meta').byKey('info');\n\nOr, in a Polymer element, you can include a meta in your template:\n\n \n ...\n this.$.meta.byKey('info');\n\n@group Iron Elements\n@demo demo/index.html\n@element iron-meta\n*/\n\nPolymer({\n is: 'iron-meta',\n properties: {\n /**\n * The type of meta-data. All meta-data of the same type is stored\n * together.\n * @type {string}\n */\n type: {\n type: String,\n value: 'default'\n },\n\n /**\n * The key used to store `value` under the `type` namespace.\n * @type {?string}\n */\n key: {\n type: String\n },\n\n /**\n * The meta-data to store or retrieve.\n * @type {*}\n */\n value: {\n type: String,\n notify: true\n },\n\n /**\n * If true, `value` is set to the iron-meta instance itself.\n */\n self: {\n type: Boolean,\n observer: '_selfChanged'\n },\n __meta: {\n type: Boolean,\n computed: '__computeMeta(type, key, value)'\n }\n },\n hostAttributes: {\n hidden: true\n },\n __computeMeta: function __computeMeta(type, key, value) {\n var meta = new IronMeta({\n type: type,\n key: key\n });\n\n if (value !== undefined && value !== meta.value) {\n meta.value = value;\n } else if (this.value !== meta.value) {\n this.value = meta.value;\n }\n\n return meta;\n },\n\n get list() {\n return this.__meta && this.__meta.list;\n },\n\n _selfChanged: function _selfChanged(self) {\n if (self) {\n this.value = this;\n }\n },\n\n /**\n * Retrieves meta data value by key.\n *\n * @method byKey\n * @param {string} key The key of the meta-data to be returned.\n * @return {*}\n */\n byKey: function byKey(key) {\n return new IronMeta({\n type: this.type,\n key: key\n }).value;\n }\n});","/**\n@license\nCopyright (c) 2016 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\nvar p = Element.prototype;\nvar matches = p.matches || p.matchesSelector || p.mozMatchesSelector || p.msMatchesSelector || p.oMatchesSelector || p.webkitMatchesSelector;\nexport const IronFocusablesHelper = {\n /**\n * Returns a sorted array of tabbable nodes, including the root node.\n * It searches the tabbable nodes in the light and shadow dom of the chidren,\n * sorting the result by tabindex.\n * @param {!Node} node\n * @return {!Array}\n */\n getTabbableNodes: function getTabbableNodes(node) {\n var result = []; // If there is at least one element with tabindex > 0, we need to sort\n // the final array by tabindex.\n\n var needsSortByTabIndex = this._collectTabbableNodes(node, result);\n\n if (needsSortByTabIndex) {\n return this._sortByTabIndex(result);\n }\n\n return result;\n },\n\n /**\n * Returns if a element is focusable.\n * @param {!HTMLElement} element\n * @return {boolean}\n */\n isFocusable: function isFocusable(element) {\n // From http://stackoverflow.com/a/1600194/4228703:\n // There isn't a definite list, it's up to the browser. The only\n // standard we have is DOM Level 2 HTML\n // https://www.w3.org/TR/DOM-Level-2-HTML/html.html, according to which the\n // only elements that have a focus() method are HTMLInputElement,\n // HTMLSelectElement, HTMLTextAreaElement and HTMLAnchorElement. This\n // notably omits HTMLButtonElement and HTMLAreaElement. Referring to these\n // tests with tabbables in different browsers\n // http://allyjs.io/data-tables/focusable.html\n // Elements that cannot be focused if they have [disabled] attribute.\n if (matches.call(element, 'input, select, textarea, button, object')) {\n return matches.call(element, ':not([disabled])');\n } // Elements that can be focused even if they have [disabled] attribute.\n\n\n return matches.call(element, 'a[href], area[href], iframe, [tabindex], [contentEditable]');\n },\n\n /**\n * Returns if a element is tabbable. To be tabbable, a element must be\n * focusable, visible, and with a tabindex !== -1.\n * @param {!HTMLElement} element\n * @return {boolean}\n */\n isTabbable: function isTabbable(element) {\n return this.isFocusable(element) && matches.call(element, ':not([tabindex=\"-1\"])') && this._isVisible(element);\n },\n\n /**\n * Returns the normalized element tabindex. If not focusable, returns -1.\n * It checks for the attribute \"tabindex\" instead of the element property\n * `tabIndex` since browsers assign different values to it.\n * e.g. in Firefox `
` has `tabIndex = -1`\n * @param {!HTMLElement} element\n * @return {!number}\n * @private\n */\n _normalizedTabIndex: function _normalizedTabIndex(element) {\n if (this.isFocusable(element)) {\n var tabIndex = element.getAttribute('tabindex') || 0;\n return Number(tabIndex);\n }\n\n return -1;\n },\n\n /**\n * Searches for nodes that are tabbable and adds them to the `result` array.\n * Returns if the `result` array needs to be sorted by tabindex.\n * @param {!Node} node The starting point for the search; added to `result`\n * if tabbable.\n * @param {!Array} result\n * @return {boolean}\n * @private\n */\n _collectTabbableNodes: function _collectTabbableNodes(node, result) {\n // If not an element or not visible, no need to explore children.\n if (node.nodeType !== Node.ELEMENT_NODE || !this._isVisible(node)) {\n return false;\n }\n\n var element =\n /** @type {!HTMLElement} */\n node;\n\n var tabIndex = this._normalizedTabIndex(element);\n\n var needsSort = tabIndex > 0;\n\n if (tabIndex >= 0) {\n result.push(element);\n } // In ShadowDOM v1, tab order is affected by the order of distrubution.\n // E.g. getTabbableNodes(#root) in ShadowDOM v1 should return [#A, #B];\n // in ShadowDOM v0 tab order is not affected by the distrubution order,\n // in fact getTabbableNodes(#root) returns [#B, #A].\n //
\n // \n // \n // \n // \n // \n // \n //
\n // TODO(valdrin) support ShadowDOM v1 when upgrading to Polymer v2.0.\n\n\n var children;\n\n if (element.localName === 'content' || element.localName === 'slot') {\n children = dom(element).getDistributedNodes();\n } else {\n // Use shadow root if possible, will check for distributed nodes.\n children = dom(element.root || element).children;\n }\n\n for (var i = 0; i < children.length; i++) {\n // Ensure method is always invoked to collect tabbable children.\n needsSort = this._collectTabbableNodes(children[i], result) || needsSort;\n }\n\n return needsSort;\n },\n\n /**\n * Returns false if the element has `visibility: hidden` or `display: none`\n * @param {!HTMLElement} element\n * @return {boolean}\n * @private\n */\n _isVisible: function _isVisible(element) {\n // Check inline style first to save a re-flow. If looks good, check also\n // computed style.\n var style = element.style;\n\n if (style.visibility !== 'hidden' && style.display !== 'none') {\n style = window.getComputedStyle(element);\n return style.visibility !== 'hidden' && style.display !== 'none';\n }\n\n return false;\n },\n\n /**\n * Sorts an array of tabbable elements by tabindex. Returns a new array.\n * @param {!Array} tabbables\n * @return {!Array}\n * @private\n */\n _sortByTabIndex: function _sortByTabIndex(tabbables) {\n // Implement a merge sort as Array.prototype.sort does a non-stable sort\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort\n var len = tabbables.length;\n\n if (len < 2) {\n return tabbables;\n }\n\n var pivot = Math.ceil(len / 2);\n\n var left = this._sortByTabIndex(tabbables.slice(0, pivot));\n\n var right = this._sortByTabIndex(tabbables.slice(pivot));\n\n return this._mergeSortByTabIndex(left, right);\n },\n\n /**\n * Merge sort iterator, merges the two arrays into one, sorted by tab index.\n * @param {!Array} left\n * @param {!Array} right\n * @return {!Array}\n * @private\n */\n _mergeSortByTabIndex: function _mergeSortByTabIndex(left, right) {\n var result = [];\n\n while (left.length > 0 && right.length > 0) {\n if (this._hasLowerTabOrder(left[0], right[0])) {\n result.push(right.shift());\n } else {\n result.push(left.shift());\n }\n }\n\n return result.concat(left, right);\n },\n\n /**\n * Returns if element `a` has lower tab order compared to element `b`\n * (both elements are assumed to be focusable and tabbable).\n * Elements with tabindex = 0 have lower tab order compared to elements\n * with tabindex > 0.\n * If both have same tabindex, it returns false.\n * @param {!HTMLElement} a\n * @param {!HTMLElement} b\n * @return {boolean}\n * @private\n */\n _hasLowerTabOrder: function _hasLowerTabOrder(a, b) {\n // Normalize tabIndexes\n // e.g. in Firefox `
` has `tabIndex = -1`\n var ati = Math.max(a.tabIndex, 0);\n var bti = Math.max(b.tabIndex, 0);\n return ati === 0 || bti === 0 ? bti > ati : ati > bti;\n }\n};","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { Polymer } from '@polymer/polymer/lib/legacy/polymer-fn.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\nimport { html } from '@polymer/polymer/lib/utils/html-tag.js';\n/*\n`iron-overlay-backdrop` is a backdrop used by `Polymer.IronOverlayBehavior`. It\nshould be a singleton.\n\n### Styling\n\nThe following custom properties and mixins are available for styling.\n\nCustom property | Description | Default\n-------------------------------------------|------------------------|---------\n`--iron-overlay-backdrop-background-color` | Backdrop background color | #000\n`--iron-overlay-backdrop-opacity` | Backdrop opacity | 0.6\n`--iron-overlay-backdrop` | Mixin applied to `iron-overlay-backdrop`. | {}\n`--iron-overlay-backdrop-opened` | Mixin applied to `iron-overlay-backdrop` when it is displayed | {}\n*/\n\nPolymer({\n _template: html`\n \n\n \n`,\n is: 'iron-overlay-backdrop',\n properties: {\n /**\n * Returns true if the backdrop is opened.\n */\n opened: {\n reflectToAttribute: true,\n type: Boolean,\n value: false,\n observer: '_openedChanged'\n }\n },\n listeners: {\n 'transitionend': '_onTransitionend'\n },\n created: function created() {\n // Used to cancel previous requestAnimationFrame calls when opened changes.\n this.__openedRaf = null;\n },\n attached: function attached() {\n this.opened && this._openedChanged(this.opened);\n },\n\n /**\n * Appends the backdrop to document body if needed.\n */\n prepare: function prepare() {\n if (this.opened && !this.parentNode) {\n dom(document.body).appendChild(this);\n }\n },\n\n /**\n * Shows the backdrop.\n */\n open: function open() {\n this.opened = true;\n },\n\n /**\n * Hides the backdrop.\n */\n close: function close() {\n this.opened = false;\n },\n\n /**\n * Removes the backdrop from document body if needed.\n */\n complete: function complete() {\n if (!this.opened && this.parentNode === document.body) {\n dom(this.parentNode).removeChild(this);\n }\n },\n _onTransitionend: function _onTransitionend(event) {\n if (event && event.target === this) {\n this.complete();\n }\n },\n\n /**\n * @param {boolean} opened\n * @private\n */\n _openedChanged: function _openedChanged(opened) {\n if (opened) {\n // Auto-attach.\n this.prepare();\n } else {\n // Animation might be disabled via the mixin or opacity custom property.\n // If it is disabled in other ways, it's up to the user to call complete.\n var cs = window.getComputedStyle(this);\n\n if (cs.transitionDuration === '0s' || cs.opacity == 0) {\n this.complete();\n }\n }\n\n if (!this.isAttached) {\n return;\n } // Always cancel previous requestAnimationFrame.\n\n\n if (this.__openedRaf) {\n window.cancelAnimationFrame(this.__openedRaf);\n this.__openedRaf = null;\n } // Force relayout to ensure proper transitions.\n\n\n this.scrollTop = this.scrollTop;\n this.__openedRaf = window.requestAnimationFrame(function () {\n this.__openedRaf = null;\n this.toggleClass('opened', this.opened);\n }.bind(this));\n }\n});","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { IronFitBehavior } from '@polymer/iron-fit-behavior/iron-fit-behavior.js';\nimport { IronResizableBehavior } from '@polymer/iron-resizable-behavior/iron-resizable-behavior.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\nimport { useShadow } from '@polymer/polymer/lib/utils/settings.js';\nimport { IronFocusablesHelper } from './iron-focusables-helper.js';\nimport { IronOverlayManager } from './iron-overlay-manager.js';\nimport { pushScrollLock, removeScrollLock } from './iron-scroll-manager.js';\n/** @polymerBehavior */\n\nexport const IronOverlayBehaviorImpl = {\n properties: {\n /**\n * True if the overlay is currently displayed.\n */\n opened: {\n observer: '_openedChanged',\n type: Boolean,\n value: false,\n notify: true\n },\n\n /**\n * True if the overlay was canceled when it was last closed.\n */\n canceled: {\n observer: '_canceledChanged',\n readOnly: true,\n type: Boolean,\n value: false\n },\n\n /**\n * Set to true to display a backdrop behind the overlay. It traps the focus\n * within the light DOM of the overlay.\n */\n withBackdrop: {\n observer: '_withBackdropChanged',\n type: Boolean\n },\n\n /**\n * Set to true to disable auto-focusing the overlay or child nodes with\n * the `autofocus` attribute` when the overlay is opened.\n */\n noAutoFocus: {\n type: Boolean,\n value: false\n },\n\n /**\n * Set to true to disable canceling the overlay with the ESC key.\n */\n noCancelOnEscKey: {\n type: Boolean,\n value: false\n },\n\n /**\n * Set to true to disable canceling the overlay by clicking outside it.\n */\n noCancelOnOutsideClick: {\n type: Boolean,\n value: false\n },\n\n /**\n * Contains the reason(s) this overlay was last closed (see\n * `iron-overlay-closed`). `IronOverlayBehavior` provides the `canceled`\n * reason; implementers of the behavior can provide other reasons in\n * addition to `canceled`.\n */\n closingReason: {\n // was a getter before, but needs to be a property so other\n // behaviors can override this.\n type: Object\n },\n\n /**\n * Set to true to enable restoring of focus when overlay is closed.\n */\n restoreFocusOnClose: {\n type: Boolean,\n value: false\n },\n\n /**\n * Set to true to allow clicks to go through overlays.\n * When the user clicks outside this overlay, the click may\n * close the overlay below.\n */\n allowClickThrough: {\n type: Boolean\n },\n\n /**\n * Set to true to keep overlay always on top.\n */\n alwaysOnTop: {\n type: Boolean\n },\n\n /**\n * Determines which action to perform when scroll outside an opened overlay\n * happens. Possible values: lock - blocks scrolling from happening, refit -\n * computes the new position on the overlay cancel - causes the overlay to\n * close\n */\n scrollAction: {\n type: String\n },\n\n /**\n * Shortcut to access to the overlay manager.\n * @private\n * @type {!IronOverlayManagerClass}\n */\n _manager: {\n type: Object,\n value: IronOverlayManager\n },\n\n /**\n * The node being focused.\n * @type {?Node}\n */\n _focusedChild: {\n type: Object\n }\n },\n listeners: {\n 'iron-resize': '_onIronResize'\n },\n observers: ['__updateScrollObservers(isAttached, opened, scrollAction)'],\n\n /**\n * The backdrop element.\n * @return {!Element}\n */\n get backdropElement() {\n return this._manager.backdropElement;\n },\n\n /**\n * Returns the node to give focus to.\n * @return {!Node}\n */\n get _focusNode() {\n return this._focusedChild || dom(this).querySelector('[autofocus]') || this;\n },\n\n /**\n * Array of nodes that can receive focus (overlay included), ordered by\n * `tabindex`. This is used to retrieve which is the first and last focusable\n * nodes in order to wrap the focus for overlays `with-backdrop`.\n *\n * If you know what is your content (specifically the first and last focusable\n * children), you can override this method to return only `[firstFocusable,\n * lastFocusable];`\n * @return {!Array}\n * @protected\n */\n get _focusableNodes() {\n return IronFocusablesHelper.getTabbableNodes(this);\n },\n\n /**\n * @return {void}\n */\n ready: function ready() {\n // Used to skip calls to notifyResize and refit while the overlay is\n // animating.\n this.__isAnimating = false; // with-backdrop needs tabindex to be set in order to trap the focus.\n // If it is not set, IronOverlayBehavior will set it, and remove it if\n // with-backdrop = false.\n\n this.__shouldRemoveTabIndex = false; // Used for wrapping the focus on TAB / Shift+TAB.\n\n this.__firstFocusableNode = this.__lastFocusableNode = null; // Used by to keep track of the RAF callbacks.\n\n this.__rafs = {}; // Focused node before overlay gets opened. Can be restored on close.\n\n this.__restoreFocusNode = null; // Scroll info to be restored.\n\n this.__scrollTop = this.__scrollLeft = null;\n this.__onCaptureScroll = this.__onCaptureScroll.bind(this); // Root nodes hosting the overlay, used to listen for scroll events on them.\n\n this.__rootNodes = null;\n\n this._ensureSetup();\n },\n attached: function attached() {\n // Call _openedChanged here so that position can be computed correctly.\n if (this.opened) {\n this._openedChanged(this.opened);\n }\n\n this._observer = dom(this).observeNodes(this._onNodesChange);\n },\n detached: function detached() {\n dom(this).unobserveNodes(this._observer);\n this._observer = null;\n\n for (var cb in this.__rafs) {\n if (this.__rafs[cb] !== null) {\n cancelAnimationFrame(this.__rafs[cb]);\n }\n }\n\n this.__rafs = {};\n\n this._manager.removeOverlay(this); // We got detached while animating, ensure we show/hide the overlay\n // and fire iron-overlay-opened/closed event!\n\n\n if (this.__isAnimating) {\n if (this.opened) {\n this._finishRenderOpened();\n } else {\n // Restore the focus if necessary.\n this._applyFocus();\n\n this._finishRenderClosed();\n }\n }\n },\n\n /**\n * Toggle the opened state of the overlay.\n */\n toggle: function toggle() {\n this._setCanceled(false);\n\n this.opened = !this.opened;\n },\n\n /**\n * Open the overlay.\n */\n open: function open() {\n this._setCanceled(false);\n\n this.opened = true;\n },\n\n /**\n * Close the overlay.\n */\n close: function close() {\n this._setCanceled(false);\n\n this.opened = false;\n },\n\n /**\n * Cancels the overlay.\n * @param {Event=} event The original event\n */\n cancel: function cancel(event) {\n var cancelEvent = this.fire('iron-overlay-canceled', event, {\n cancelable: true\n });\n\n if (cancelEvent.defaultPrevented) {\n return;\n }\n\n this._setCanceled(true);\n\n this.opened = false;\n },\n\n /**\n * Invalidates the cached tabbable nodes. To be called when any of the\n * focusable content changes (e.g. a button is disabled).\n */\n invalidateTabbables: function invalidateTabbables() {\n this.__firstFocusableNode = this.__lastFocusableNode = null;\n },\n _ensureSetup: function _ensureSetup() {\n if (this._overlaySetup) {\n return;\n }\n\n this._overlaySetup = true;\n this.style.outline = 'none';\n this.style.display = 'none';\n },\n\n /**\n * Called when `opened` changes.\n * @param {boolean=} opened\n * @protected\n */\n _openedChanged: function _openedChanged(opened) {\n if (opened) {\n this.removeAttribute('aria-hidden');\n } else {\n this.setAttribute('aria-hidden', 'true');\n } // Defer any animation-related code on attached\n // (_openedChanged gets called again on attached).\n\n\n if (!this.isAttached) {\n return;\n }\n\n this.__isAnimating = true; // Deraf for non-blocking rendering.\n\n this.__deraf('__openedChanged', this.__openedChanged);\n },\n _canceledChanged: function _canceledChanged() {\n this.closingReason = this.closingReason || {};\n this.closingReason.canceled = this.canceled;\n },\n _withBackdropChanged: function _withBackdropChanged() {\n // If tabindex is already set, no need to override it.\n if (this.withBackdrop && !this.hasAttribute('tabindex')) {\n this.setAttribute('tabindex', '-1');\n this.__shouldRemoveTabIndex = true;\n } else if (this.__shouldRemoveTabIndex) {\n this.removeAttribute('tabindex');\n this.__shouldRemoveTabIndex = false;\n }\n\n if (this.opened && this.isAttached) {\n this._manager.trackBackdrop();\n }\n },\n\n /**\n * tasks which must occur before opening; e.g. making the element visible.\n * @protected\n */\n _prepareRenderOpened: function _prepareRenderOpened() {\n // Store focused node.\n this.__restoreFocusNode = this._manager.deepActiveElement; // Needed to calculate the size of the overlay so that transitions on its\n // size will have the correct starting points.\n\n this._preparePositioning();\n\n this.refit();\n\n this._finishPositioning(); // Safari will apply the focus to the autofocus element when displayed\n // for the first time, so we make sure to return the focus where it was.\n\n\n if (this.noAutoFocus && document.activeElement === this._focusNode) {\n this._focusNode.blur();\n\n this.__restoreFocusNode.focus();\n }\n },\n\n /**\n * Tasks which cause the overlay to actually open; typically play an\n * animation.\n * @protected\n */\n _renderOpened: function _renderOpened() {\n this._finishRenderOpened();\n },\n\n /**\n * Tasks which cause the overlay to actually close; typically play an\n * animation.\n * @protected\n */\n _renderClosed: function _renderClosed() {\n this._finishRenderClosed();\n },\n\n /**\n * Tasks to be performed at the end of open action. Will fire\n * `iron-overlay-opened`.\n * @protected\n */\n _finishRenderOpened: function _finishRenderOpened() {\n this.notifyResize();\n this.__isAnimating = false;\n this.fire('iron-overlay-opened');\n },\n\n /**\n * Tasks to be performed at the end of close action. Will fire\n * `iron-overlay-closed`.\n * @protected\n */\n _finishRenderClosed: function _finishRenderClosed() {\n // Hide the overlay.\n this.style.display = 'none'; // Reset z-index only at the end of the animation.\n\n this.style.zIndex = '';\n this.notifyResize();\n this.__isAnimating = false;\n this.fire('iron-overlay-closed', this.closingReason);\n },\n _preparePositioning: function _preparePositioning() {\n this.style.transition = this.style.webkitTransition = 'none';\n this.style.transform = this.style.webkitTransform = 'none';\n this.style.display = '';\n },\n _finishPositioning: function _finishPositioning() {\n // First, make it invisible & reactivate animations.\n this.style.display = 'none'; // Force reflow before re-enabling animations so that they don't start.\n // Set scrollTop to itself so that Closure Compiler doesn't remove this.\n\n this.scrollTop = this.scrollTop;\n this.style.transition = this.style.webkitTransition = '';\n this.style.transform = this.style.webkitTransform = ''; // Now that animations are enabled, make it visible again\n\n this.style.display = ''; // Force reflow, so that following animations are properly started.\n // Set scrollTop to itself so that Closure Compiler doesn't remove this.\n\n this.scrollTop = this.scrollTop;\n },\n\n /**\n * Applies focus according to the opened state.\n * @protected\n */\n _applyFocus: function _applyFocus() {\n if (this.opened) {\n if (!this.noAutoFocus) {\n this._focusNode.focus();\n }\n } else {\n // Restore focus.\n if (this.restoreFocusOnClose && this.__restoreFocusNode) {\n // If the activeElement is `` or inside the overlay,\n // we are allowed to restore the focus. In all the other\n // cases focus might have been moved elsewhere by another\n // component or by an user interaction (e.g. click on a\n // button outside the overlay).\n var activeElement = this._manager.deepActiveElement;\n\n if (activeElement === document.body || dom(this).deepContains(activeElement)) {\n this.__restoreFocusNode.focus();\n }\n }\n\n this.__restoreFocusNode = null;\n\n this._focusNode.blur();\n\n this._focusedChild = null;\n }\n },\n\n /**\n * Cancels (closes) the overlay. Call when click happens outside the overlay.\n * @param {!Event} event\n * @protected\n */\n _onCaptureClick: function _onCaptureClick(event) {\n if (!this.noCancelOnOutsideClick) {\n this.cancel(event);\n }\n },\n\n /**\n * Keeps track of the focused child. If withBackdrop, traps focus within\n * overlay.\n * @param {!Event} event\n * @protected\n */\n _onCaptureFocus: function _onCaptureFocus(event) {\n if (!this.withBackdrop) {\n return;\n }\n\n var path = dom(event).path;\n\n if (path.indexOf(this) === -1) {\n event.stopPropagation();\n\n this._applyFocus();\n } else {\n this._focusedChild = path[0];\n }\n },\n\n /**\n * Handles the ESC key event and cancels (closes) the overlay.\n * @param {!Event} event\n * @protected\n */\n _onCaptureEsc: function _onCaptureEsc(event) {\n if (!this.noCancelOnEscKey) {\n this.cancel(event);\n }\n },\n\n /**\n * Handles TAB key events to track focus changes.\n * Will wrap focus for overlays withBackdrop.\n * @param {!Event} event\n * @protected\n */\n _onCaptureTab: function _onCaptureTab(event) {\n if (!this.withBackdrop) {\n return;\n }\n\n this.__ensureFirstLastFocusables(); // TAB wraps from last to first focusable.\n // Shift + TAB wraps from first to last focusable.\n\n\n var shift = event.shiftKey;\n var nodeToCheck = shift ? this.__firstFocusableNode : this.__lastFocusableNode;\n var nodeToSet = shift ? this.__lastFocusableNode : this.__firstFocusableNode;\n var shouldWrap = false;\n\n if (nodeToCheck === nodeToSet) {\n // If nodeToCheck is the same as nodeToSet, it means we have an overlay\n // with 0 or 1 focusables; in either case we still need to trap the\n // focus within the overlay.\n shouldWrap = true;\n } else {\n // In dom=shadow, the manager will receive focus changes on the main\n // root but not the ones within other shadow roots, so we can't rely on\n // _focusedChild, but we should check the deepest active element.\n var focusedNode = this._manager.deepActiveElement; // If the active element is not the nodeToCheck but the overlay itself,\n // it means the focus is about to go outside the overlay, hence we\n // should prevent that (e.g. user opens the overlay and hit Shift+TAB).\n\n shouldWrap = focusedNode === nodeToCheck || focusedNode === this;\n }\n\n if (shouldWrap) {\n // When the overlay contains the last focusable element of the document\n // and it's already focused, pressing TAB would move the focus outside\n // the document (e.g. to the browser search bar). Similarly, when the\n // overlay contains the first focusable element of the document and it's\n // already focused, pressing Shift+TAB would move the focus outside the\n // document (e.g. to the browser search bar).\n // In both cases, we would not receive a focus event, but only a blur.\n // In order to achieve focus wrapping, we prevent this TAB event and\n // force the focus. This will also prevent the focus to temporarily move\n // outside the overlay, which might cause scrolling.\n event.preventDefault();\n this._focusedChild = nodeToSet;\n\n this._applyFocus();\n }\n },\n\n /**\n * Refits if the overlay is opened and not animating.\n * @protected\n */\n _onIronResize: function _onIronResize() {\n if (this.opened && !this.__isAnimating) {\n this.__deraf('refit', this.refit);\n }\n },\n\n /**\n * Will call notifyResize if overlay is opened.\n * Can be overridden in order to avoid multiple observers on the same node.\n * @protected\n */\n _onNodesChange: function _onNodesChange() {\n if (this.opened && !this.__isAnimating) {\n // It might have added focusable nodes, so invalidate cached values.\n this.invalidateTabbables();\n this.notifyResize();\n }\n },\n\n /**\n * Updates the references to the first and last focusable nodes.\n * @private\n */\n __ensureFirstLastFocusables: function __ensureFirstLastFocusables() {\n var focusableNodes = this._focusableNodes;\n this.__firstFocusableNode = focusableNodes[0];\n this.__lastFocusableNode = focusableNodes[focusableNodes.length - 1];\n },\n\n /**\n * Tasks executed when opened changes: prepare for the opening, move the\n * focus, update the manager, render opened/closed.\n * @private\n */\n __openedChanged: function __openedChanged() {\n if (this.opened) {\n // Make overlay visible, then add it to the manager.\n this._prepareRenderOpened();\n\n this._manager.addOverlay(this); // Move the focus to the child node with [autofocus].\n\n\n this._applyFocus();\n\n this._renderOpened();\n } else {\n // Remove overlay, then restore the focus before actually closing.\n this._manager.removeOverlay(this);\n\n this._applyFocus();\n\n this._renderClosed();\n }\n },\n\n /**\n * Debounces the execution of a callback to the next animation frame.\n * @param {!string} jobname\n * @param {!Function} callback Always bound to `this`\n * @private\n */\n __deraf: function __deraf(jobname, callback) {\n var rafs = this.__rafs;\n\n if (rafs[jobname] !== null) {\n cancelAnimationFrame(rafs[jobname]);\n }\n\n rafs[jobname] = requestAnimationFrame(function nextAnimationFrame() {\n rafs[jobname] = null;\n callback.call(this);\n }.bind(this));\n },\n\n /**\n * @param {boolean} isAttached\n * @param {boolean} opened\n * @param {string=} scrollAction\n * @private\n */\n __updateScrollObservers: function __updateScrollObservers(isAttached, opened, scrollAction) {\n if (!isAttached || !opened || !this.__isValidScrollAction(scrollAction)) {\n removeScrollLock(this);\n\n this.__removeScrollListeners();\n } else {\n if (scrollAction === 'lock') {\n this.__saveScrollPosition();\n\n pushScrollLock(this);\n }\n\n this.__addScrollListeners();\n }\n },\n\n /**\n * @private\n */\n __addScrollListeners: function __addScrollListeners() {\n if (!this.__rootNodes) {\n this.__rootNodes = []; // Listen for scroll events in all shadowRoots hosting this overlay only\n // when in native ShadowDOM.\n\n if (useShadow) {\n var node = this;\n\n while (node) {\n if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && node.host) {\n this.__rootNodes.push(node);\n }\n\n node = node.host || node.assignedSlot || node.parentNode;\n }\n }\n\n this.__rootNodes.push(document);\n }\n\n this.__rootNodes.forEach(function (el) {\n el.addEventListener('scroll', this.__onCaptureScroll, {\n capture: true,\n passive: true\n });\n }, this);\n },\n\n /**\n * @private\n */\n __removeScrollListeners: function __removeScrollListeners() {\n if (this.__rootNodes) {\n this.__rootNodes.forEach(function (el) {\n el.removeEventListener('scroll', this.__onCaptureScroll, {\n capture: true,\n passive: true\n });\n }, this);\n }\n\n if (!this.isAttached) {\n this.__rootNodes = null;\n }\n },\n\n /**\n * @param {string=} scrollAction\n * @return {boolean}\n * @private\n */\n __isValidScrollAction: function __isValidScrollAction(scrollAction) {\n return scrollAction === 'lock' || scrollAction === 'refit' || scrollAction === 'cancel';\n },\n\n /**\n * @private\n */\n __onCaptureScroll: function __onCaptureScroll(event) {\n if (this.__isAnimating) {\n return;\n } // Check if scroll outside the overlay.\n\n\n if (dom(event).path.indexOf(this) >= 0) {\n return;\n }\n\n switch (this.scrollAction) {\n case 'lock':\n // NOTE: scrolling might happen if a scroll event is not cancellable, or\n // if user pressed keys that cause scrolling (they're not prevented in\n // order not to break a11y features like navigate with arrow keys).\n this.__restoreScrollPosition();\n\n break;\n\n case 'refit':\n this.__deraf('refit', this.refit);\n\n break;\n\n case 'cancel':\n this.cancel(event);\n break;\n }\n },\n\n /**\n * Memoizes the scroll position of the outside scrolling element.\n * @private\n */\n __saveScrollPosition: function __saveScrollPosition() {\n if (document.scrollingElement) {\n this.__scrollTop = document.scrollingElement.scrollTop;\n this.__scrollLeft = document.scrollingElement.scrollLeft;\n } else {\n // Since we don't know if is the body or html, get max.\n this.__scrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);\n this.__scrollLeft = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);\n }\n },\n\n /**\n * Resets the scroll position of the outside scrolling element.\n * @private\n */\n __restoreScrollPosition: function __restoreScrollPosition() {\n if (document.scrollingElement) {\n document.scrollingElement.scrollTop = this.__scrollTop;\n document.scrollingElement.scrollLeft = this.__scrollLeft;\n } else {\n // Since we don't know if is the body or html, set both.\n document.documentElement.scrollTop = document.body.scrollTop = this.__scrollTop;\n document.documentElement.scrollLeft = document.body.scrollLeft = this.__scrollLeft;\n }\n }\n};\n/**\n Use `Polymer.IronOverlayBehavior` to implement an element that can be hidden\n or shown, and displays on top of other content. It includes an optional\n backdrop, and can be used to implement a variety of UI controls including\n dialogs and drop downs. Multiple overlays may be displayed at once.\n\n See the [demo source\n code](https://github.com/PolymerElements/iron-overlay-behavior/blob/master/demo/simple-overlay.html)\n for an example.\n\n ### Closing and canceling\n\n An overlay may be hidden by closing or canceling. The difference between close\n and cancel is user intent. Closing generally implies that the user\n acknowledged the content on the overlay. By default, it will cancel whenever\n the user taps outside it or presses the escape key. This behavior is\n configurable with the `no-cancel-on-esc-key` and the\n `no-cancel-on-outside-click` properties. `close()` should be called explicitly\n by the implementer when the user interacts with a control in the overlay\n element. When the dialog is canceled, the overlay fires an\n 'iron-overlay-canceled' event. Call `preventDefault` on this event to prevent\n the overlay from closing.\n\n ### Positioning\n\n By default the element is sized and positioned to fit and centered inside the\n window. You can position and size it manually using CSS. See\n `Polymer.IronFitBehavior`.\n\n ### Backdrop\n\n Set the `with-backdrop` attribute to display a backdrop behind the overlay.\n The backdrop is appended to `` and is of type ``.\n See its doc page for styling options.\n\n In addition, `with-backdrop` will wrap the focus within the content in the\n light DOM. Override the [`_focusableNodes`\n getter](#Polymer.IronOverlayBehavior:property-_focusableNodes) to achieve a\n different behavior.\n\n ### Limitations\n\n The element is styled to appear on top of other content by setting its\n `z-index` property. You must ensure no element has a stacking context with a\n higher `z-index` than its parent stacking context. You should place this\n element as a child of `` whenever possible.\n\n @demo demo/index.html\n @polymerBehavior\n */\n\nexport const IronOverlayBehavior = [IronFitBehavior, IronResizableBehavior, IronOverlayBehaviorImpl];\n/**\n * Fired after the overlay opens.\n * @event iron-overlay-opened\n */\n\n/**\n * Fired when the overlay is canceled, but before it is closed.\n * @event iron-overlay-canceled\n * @param {Event} event The closing of the overlay can be prevented\n * by calling `event.preventDefault()`. The `event.detail` is the original event\n * that originated the canceling (e.g. ESC keyboard event or click event outside\n * the overlay).\n */\n\n/**\n * Fired after the overlay closes.\n * @event iron-overlay-closed\n * @param {Event} event The `event.detail` is the `closingReason` property\n * (contains `canceled`, whether the overlay was canceled).\n */","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport './iron-overlay-backdrop.js';\nimport { IronA11yKeysBehavior } from '@polymer/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\nimport * as gestures from '@polymer/polymer/lib/utils/gestures.js';\n/**\n * @struct\n * @constructor\n * @private\n */\n\nexport const IronOverlayManagerClass = function IronOverlayManagerClass() {\n /**\n * Used to keep track of the opened overlays.\n * @private {!Array}\n */\n this._overlays = [];\n /**\n * iframes have a default z-index of 100,\n * so this default should be at least that.\n * @private {number}\n */\n\n this._minimumZ = 101;\n /**\n * Memoized backdrop element.\n * @private {Element|null}\n */\n\n this._backdropElement = null; // Enable document-wide tap recognizer.\n // NOTE: Use useCapture=true to avoid accidentally prevention of the closing\n // of an overlay via event.stopPropagation(). The only way to prevent\n // closing of an overlay should be through its APIs.\n // NOTE: enable tap on to workaround Polymer/polymer#4459\n // Pass no-op function because MSEdge 15 doesn't handle null as 2nd argument\n // https://github.com/Microsoft/ChakraCore/issues/3863\n\n gestures.add(document.documentElement, 'tap', function () {});\n document.addEventListener('tap', this._onCaptureClick.bind(this), true);\n document.addEventListener('focus', this._onCaptureFocus.bind(this), true);\n document.addEventListener('keydown', this._onCaptureKeyDown.bind(this), true);\n};\nIronOverlayManagerClass.prototype = {\n constructor: IronOverlayManagerClass,\n\n /**\n * The shared backdrop element.\n * @return {!Element} backdropElement\n */\n get backdropElement() {\n if (!this._backdropElement) {\n this._backdropElement = document.createElement('iron-overlay-backdrop');\n }\n\n return this._backdropElement;\n },\n\n /**\n * The deepest active element.\n * @return {!Element} activeElement the active element\n */\n get deepActiveElement() {\n var active = document.activeElement; // document.activeElement can be null\n // https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement\n // In IE 11, it can also be an object when operating in iframes.\n // In these cases, default it to document.body.\n\n if (!active || active instanceof Element === false) {\n active = document.body;\n }\n\n while (active.root && dom(active.root).activeElement) {\n active = dom(active.root).activeElement;\n }\n\n return active;\n },\n\n /**\n * Brings the overlay at the specified index to the front.\n * @param {number} i\n * @private\n */\n _bringOverlayAtIndexToFront: function _bringOverlayAtIndexToFront(i) {\n var overlay = this._overlays[i];\n\n if (!overlay) {\n return;\n }\n\n var lastI = this._overlays.length - 1;\n var currentOverlay = this._overlays[lastI]; // Ensure always-on-top overlay stays on top.\n\n if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay)) {\n lastI--;\n } // If already the top element, return.\n\n\n if (i >= lastI) {\n return;\n } // Update z-index to be on top.\n\n\n var minimumZ = Math.max(this.currentOverlayZ(), this._minimumZ);\n\n if (this._getZ(overlay) <= minimumZ) {\n this._applyOverlayZ(overlay, minimumZ);\n } // Shift other overlays behind the new on top.\n\n\n while (i < lastI) {\n this._overlays[i] = this._overlays[i + 1];\n i++;\n }\n\n this._overlays[lastI] = overlay;\n },\n\n /**\n * Adds the overlay and updates its z-index if it's opened, or removes it if\n * it's closed. Also updates the backdrop z-index.\n * @param {!Element} overlay\n */\n addOrRemoveOverlay: function addOrRemoveOverlay(overlay) {\n if (overlay.opened) {\n this.addOverlay(overlay);\n } else {\n this.removeOverlay(overlay);\n }\n },\n\n /**\n * Tracks overlays for z-index and focus management.\n * Ensures the last added overlay with always-on-top remains on top.\n * @param {!Element} overlay\n */\n addOverlay: function addOverlay(overlay) {\n var i = this._overlays.indexOf(overlay);\n\n if (i >= 0) {\n this._bringOverlayAtIndexToFront(i);\n\n this.trackBackdrop();\n return;\n }\n\n var insertionIndex = this._overlays.length;\n var currentOverlay = this._overlays[insertionIndex - 1];\n var minimumZ = Math.max(this._getZ(currentOverlay), this._minimumZ);\n\n var newZ = this._getZ(overlay); // Ensure always-on-top overlay stays on top.\n\n\n if (currentOverlay && this._shouldBeBehindOverlay(overlay, currentOverlay)) {\n // This bumps the z-index of +2.\n this._applyOverlayZ(currentOverlay, minimumZ);\n\n insertionIndex--; // Update minimumZ to match previous overlay's z-index.\n\n var previousOverlay = this._overlays[insertionIndex - 1];\n minimumZ = Math.max(this._getZ(previousOverlay), this._minimumZ);\n } // Update z-index and insert overlay.\n\n\n if (newZ <= minimumZ) {\n this._applyOverlayZ(overlay, minimumZ);\n }\n\n this._overlays.splice(insertionIndex, 0, overlay);\n\n this.trackBackdrop();\n },\n\n /**\n * @param {!Element} overlay\n */\n removeOverlay: function removeOverlay(overlay) {\n var i = this._overlays.indexOf(overlay);\n\n if (i === -1) {\n return;\n }\n\n this._overlays.splice(i, 1);\n\n this.trackBackdrop();\n },\n\n /**\n * Returns the current overlay.\n * @return {!Element|undefined}\n */\n currentOverlay: function currentOverlay() {\n var i = this._overlays.length - 1;\n return this._overlays[i];\n },\n\n /**\n * Returns the current overlay z-index.\n * @return {number}\n */\n currentOverlayZ: function currentOverlayZ() {\n return this._getZ(this.currentOverlay());\n },\n\n /**\n * Ensures that the minimum z-index of new overlays is at least `minimumZ`.\n * This does not effect the z-index of any existing overlays.\n * @param {number} minimumZ\n */\n ensureMinimumZ: function ensureMinimumZ(minimumZ) {\n this._minimumZ = Math.max(this._minimumZ, minimumZ);\n },\n focusOverlay: function focusOverlay() {\n var current =\n /** @type {?} */\n this.currentOverlay();\n\n if (current) {\n current._applyFocus();\n }\n },\n\n /**\n * Updates the backdrop z-index.\n */\n trackBackdrop: function trackBackdrop() {\n var overlay = this._overlayWithBackdrop(); // Avoid creating the backdrop if there is no overlay with backdrop.\n\n\n if (!overlay && !this._backdropElement) {\n return;\n }\n\n this.backdropElement.style.zIndex = this._getZ(overlay) - 1;\n this.backdropElement.opened = !!overlay; // Property observers are not fired until element is attached\n // in Polymer 2.x, so we ensure element is attached if needed.\n // https://github.com/Polymer/polymer/issues/4526\n\n this.backdropElement.prepare();\n },\n\n /**\n * @return {!Array}\n */\n getBackdrops: function getBackdrops() {\n var backdrops = [];\n\n for (var i = 0; i < this._overlays.length; i++) {\n if (this._overlays[i].withBackdrop) {\n backdrops.push(this._overlays[i]);\n }\n }\n\n return backdrops;\n },\n\n /**\n * Returns the z-index for the backdrop.\n * @return {number}\n */\n backdropZ: function backdropZ() {\n return this._getZ(this._overlayWithBackdrop()) - 1;\n },\n\n /**\n * Returns the top opened overlay that has a backdrop.\n * @return {!Element|undefined}\n * @private\n */\n _overlayWithBackdrop: function _overlayWithBackdrop() {\n for (var i = this._overlays.length - 1; i >= 0; i--) {\n if (this._overlays[i].withBackdrop) {\n return this._overlays[i];\n }\n }\n },\n\n /**\n * Calculates the minimum z-index for the overlay.\n * @param {Element=} overlay\n * @private\n */\n _getZ: function _getZ(overlay) {\n var z = this._minimumZ;\n\n if (overlay) {\n var z1 = Number(overlay.style.zIndex || window.getComputedStyle(overlay).zIndex); // Check if is a number\n // Number.isNaN not supported in IE 10+\n\n if (z1 === z1) {\n z = z1;\n }\n }\n\n return z;\n },\n\n /**\n * @param {!Element} element\n * @param {number|string} z\n * @private\n */\n _setZ: function _setZ(element, z) {\n element.style.zIndex = z;\n },\n\n /**\n * @param {!Element} overlay\n * @param {number} aboveZ\n * @private\n */\n _applyOverlayZ: function _applyOverlayZ(overlay, aboveZ) {\n this._setZ(overlay, aboveZ + 2);\n },\n\n /**\n * Returns the deepest overlay in the path.\n * @param {!Array=} path\n * @return {!Element|undefined}\n * @suppress {missingProperties}\n * @private\n */\n _overlayInPath: function _overlayInPath(path) {\n path = path || [];\n\n for (var i = 0; i < path.length; i++) {\n if (path[i]._manager === this) {\n return path[i];\n }\n }\n },\n\n /**\n * Ensures the click event is delegated to the right overlay.\n * @param {!Event} event\n * @private\n */\n _onCaptureClick: function _onCaptureClick(event) {\n var i = this._overlays.length - 1;\n if (i === -1) return;\n var path =\n /** @type {!Array} */\n dom(event).path;\n var overlay; // Check if clicked outside of overlay.\n\n while ((overlay =\n /** @type {?} */\n this._overlays[i]) && this._overlayInPath(path) !== overlay) {\n overlay._onCaptureClick(event);\n\n if (overlay.allowClickThrough) {\n i--;\n } else {\n break;\n }\n }\n },\n\n /**\n * Ensures the focus event is delegated to the right overlay.\n * @param {!Event} event\n * @private\n */\n _onCaptureFocus: function _onCaptureFocus(event) {\n var overlay =\n /** @type {?} */\n this.currentOverlay();\n\n if (overlay) {\n overlay._onCaptureFocus(event);\n }\n },\n\n /**\n * Ensures TAB and ESC keyboard events are delegated to the right overlay.\n * @param {!Event} event\n * @private\n */\n _onCaptureKeyDown: function _onCaptureKeyDown(event) {\n var overlay =\n /** @type {?} */\n this.currentOverlay();\n\n if (overlay) {\n if (IronA11yKeysBehavior.keyboardEventMatchesKeys(event, 'esc')) {\n overlay._onCaptureEsc(event);\n } else if (IronA11yKeysBehavior.keyboardEventMatchesKeys(event, 'tab')) {\n overlay._onCaptureTab(event);\n }\n }\n },\n\n /**\n * Returns if the overlay1 should be behind overlay2.\n * @param {!Element} overlay1\n * @param {!Element} overlay2\n * @return {boolean}\n * @suppress {missingProperties}\n * @private\n */\n _shouldBeBehindOverlay: function _shouldBeBehindOverlay(overlay1, overlay2) {\n return !overlay1.alwaysOnTop && overlay2.alwaysOnTop;\n }\n};\nexport const IronOverlayManager = new IronOverlayManagerClass();","/**\n@license\nCopyright (c) 2017 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\n/**\n * Used to calculate the scroll direction during touch events.\n * @type {!Object}\n */\n\nvar lastTouchPosition = {\n pageX: 0,\n pageY: 0\n};\n/**\n * Used to avoid computing event.path and filter scrollable nodes (better perf).\n * @type {?EventTarget}\n */\n\nvar lastRootTarget = null;\n/**\n * @type {!Array}\n */\n\nvar lastScrollableNodes = [];\n/**\n * @type {!Array}\n */\n\nvar scrollEvents = [// Modern `wheel` event for mouse wheel scrolling:\n'wheel', // Older, non-standard `mousewheel` event for some FF:\n'mousewheel', // IE:\n'DOMMouseScroll', // Touch enabled devices\n'touchstart', 'touchmove']; // must be defined for modulizer\n\nvar _boundScrollHandler;\n\nvar currentLockingElement;\n/**\n * The IronScrollManager is intended to provide a central source\n * of authority and control over which elements in a document are currently\n * allowed to scroll.\n *\n */\n\n`TODO(modulizer): A namespace named Polymer.IronScrollManager was\ndeclared here. The surrounding comments should be reviewed,\nand this string can then be deleted`;\n/**\n * The current element that defines the DOM boundaries of the\n * scroll lock. This is always the most recently locking element.\n *\n * @return {!Node|undefined}\n */\n\nexport { currentLockingElement };\n/**\n * Returns true if the provided element is \"scroll locked\", which is to\n * say that it cannot be scrolled via pointer or keyboard interactions.\n *\n * @param {!HTMLElement} element An HTML element instance which may or may\n * not be scroll locked.\n */\n\nexport function elementIsScrollLocked(element) {\n var lockingElement = currentLockingElement;\n\n if (lockingElement === undefined) {\n return false;\n }\n\n var scrollLocked;\n\n if (_hasCachedLockedElement(element)) {\n return true;\n }\n\n if (_hasCachedUnlockedElement(element)) {\n return false;\n }\n\n scrollLocked = !!lockingElement && lockingElement !== element && !_composedTreeContains(lockingElement, element);\n\n if (scrollLocked) {\n _lockedElementCache.push(element);\n } else {\n _unlockedElementCache.push(element);\n }\n\n return scrollLocked;\n}\n/**\n * Push an element onto the current scroll lock stack. The most recently\n * pushed element and its children will be considered scrollable. All\n * other elements will not be scrollable.\n *\n * Scroll locking is implemented as a stack so that cases such as\n * dropdowns within dropdowns are handled well.\n *\n * @param {!HTMLElement} element The element that should lock scroll.\n */\n\nexport function pushScrollLock(element) {\n // Prevent pushing the same element twice\n if (_lockingElements.indexOf(element) >= 0) {\n return;\n }\n\n if (_lockingElements.length === 0) {\n _lockScrollInteractions();\n }\n\n _lockingElements.push(element);\n\n currentLockingElement = _lockingElements[_lockingElements.length - 1];\n _lockedElementCache = [];\n _unlockedElementCache = [];\n}\n/**\n * Remove an element from the scroll lock stack. The element being\n * removed does not need to be the most recently pushed element. However,\n * the scroll lock constraints only change when the most recently pushed\n * element is removed.\n *\n * @param {!HTMLElement} element The element to remove from the scroll\n * lock stack.\n */\n\nexport function removeScrollLock(element) {\n var index = _lockingElements.indexOf(element);\n\n if (index === -1) {\n return;\n }\n\n _lockingElements.splice(index, 1);\n\n currentLockingElement = _lockingElements[_lockingElements.length - 1];\n _lockedElementCache = [];\n _unlockedElementCache = [];\n\n if (_lockingElements.length === 0) {\n _unlockScrollInteractions();\n }\n}\nexport const _lockingElements = [];\nexport let _lockedElementCache = null;\nexport let _unlockedElementCache = null;\nexport function _hasCachedLockedElement(element) {\n return _lockedElementCache.indexOf(element) > -1;\n}\nexport function _hasCachedUnlockedElement(element) {\n return _unlockedElementCache.indexOf(element) > -1;\n}\nexport function _composedTreeContains(element, child) {\n // NOTE(cdata): This method iterates over content elements and their\n // corresponding distributed nodes to implement a contains-like method\n // that pierces through the composed tree of the ShadowDOM. Results of\n // this operation are cached (elsewhere) on a per-scroll-lock basis, to\n // guard against potentially expensive lookups happening repeatedly as\n // a user scrolls / touchmoves.\n var contentElements;\n var distributedNodes;\n var contentIndex;\n var nodeIndex;\n\n if (element.contains(child)) {\n return true;\n }\n\n contentElements = dom(element).querySelectorAll('content,slot');\n\n for (contentIndex = 0; contentIndex < contentElements.length; ++contentIndex) {\n distributedNodes = dom(contentElements[contentIndex]).getDistributedNodes();\n\n for (nodeIndex = 0; nodeIndex < distributedNodes.length; ++nodeIndex) {\n // Polymer 2.x returns slot.assignedNodes which can contain text nodes.\n if (distributedNodes[nodeIndex].nodeType !== Node.ELEMENT_NODE) continue;\n\n if (_composedTreeContains(distributedNodes[nodeIndex], child)) {\n return true;\n }\n }\n }\n\n return false;\n}\nexport function _scrollInteractionHandler(event) {\n // Avoid canceling an event with cancelable=false, e.g. scrolling is in\n // progress and cannot be interrupted.\n if (event.cancelable && _shouldPreventScrolling(event)) {\n event.preventDefault();\n } // If event has targetTouches (touch event), update last touch position.\n\n\n if (event.targetTouches) {\n var touch = event.targetTouches[0];\n lastTouchPosition.pageX = touch.pageX;\n lastTouchPosition.pageY = touch.pageY;\n }\n}\n/**\n * @private\n */\n\nexport { _boundScrollHandler };\nexport function _lockScrollInteractions() {\n _boundScrollHandler = _boundScrollHandler || _scrollInteractionHandler.bind(undefined);\n\n for (var i = 0, l = scrollEvents.length; i < l; i++) {\n // NOTE: browsers that don't support objects as third arg will\n // interpret it as boolean, hence useCapture = true in this case.\n document.addEventListener(scrollEvents[i], _boundScrollHandler, {\n capture: true,\n passive: false\n });\n }\n}\nexport function _unlockScrollInteractions() {\n for (var i = 0, l = scrollEvents.length; i < l; i++) {\n // NOTE: browsers that don't support objects as third arg will\n // interpret it as boolean, hence useCapture = true in this case.\n document.removeEventListener(scrollEvents[i], _boundScrollHandler, {\n capture: true,\n passive: false\n });\n }\n}\n/**\n * Returns true if the event causes scroll outside the current locking\n * element, e.g. pointer/keyboard interactions, or scroll \"leaking\"\n * outside the locking element when it is already at its scroll boundaries.\n * @param {!Event} event\n * @return {boolean}\n * @private\n */\n\nexport function _shouldPreventScrolling(event) {\n // Update if root target changed. For touch events, ensure we don't\n // update during touchmove.\n var target = dom(event).rootTarget;\n\n if (event.type !== 'touchmove' && lastRootTarget !== target) {\n lastRootTarget = target;\n lastScrollableNodes = _getScrollableNodes(dom(event).path);\n } // Prevent event if no scrollable nodes.\n\n\n if (!lastScrollableNodes.length) {\n return true;\n } // Don't prevent touchstart event inside the locking element when it has\n // scrollable nodes.\n\n\n if (event.type === 'touchstart') {\n return false;\n } // Get deltaX/Y.\n\n\n var info = _getScrollInfo(event); // Prevent if there is no child that can scroll.\n\n\n return !_getScrollingNode(lastScrollableNodes, info.deltaX, info.deltaY);\n}\n/**\n * Returns an array of scrollable nodes up to the current locking element,\n * which is included too if scrollable.\n * @param {!Array} nodes\n * @return {!Array} scrollables\n * @private\n */\n\nexport function _getScrollableNodes(nodes) {\n var scrollables = [];\n var lockingIndex = nodes.indexOf(currentLockingElement); // Loop from root target to locking element (included).\n\n for (var i = 0; i <= lockingIndex; i++) {\n // Skip non-Element nodes.\n if (nodes[i].nodeType !== Node.ELEMENT_NODE) {\n continue;\n }\n\n var node =\n /** @type {!Element} */\n nodes[i]; // Check inline style before checking computed style.\n\n var style = node.style;\n\n if (style.overflow !== 'scroll' && style.overflow !== 'auto') {\n style = window.getComputedStyle(node);\n }\n\n if (style.overflow === 'scroll' || style.overflow === 'auto') {\n scrollables.push(node);\n }\n }\n\n return scrollables;\n}\n/**\n * Returns the node that is scrolling. If there is no scrolling,\n * returns undefined.\n * @param {!Array} nodes\n * @param {number} deltaX Scroll delta on the x-axis\n * @param {number} deltaY Scroll delta on the y-axis\n * @return {!Node|undefined}\n * @private\n */\n\nexport function _getScrollingNode(nodes, deltaX, deltaY) {\n // No scroll.\n if (!deltaX && !deltaY) {\n return;\n } // Check only one axis according to where there is more scroll.\n // Prefer vertical to horizontal.\n\n\n var verticalScroll = Math.abs(deltaY) >= Math.abs(deltaX);\n\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i];\n var canScroll = false;\n\n if (verticalScroll) {\n // delta < 0 is scroll up, delta > 0 is scroll down.\n canScroll = deltaY < 0 ? node.scrollTop > 0 : node.scrollTop < node.scrollHeight - node.clientHeight;\n } else {\n // delta < 0 is scroll left, delta > 0 is scroll right.\n canScroll = deltaX < 0 ? node.scrollLeft > 0 : node.scrollLeft < node.scrollWidth - node.clientWidth;\n }\n\n if (canScroll) {\n return node;\n }\n }\n}\n/**\n * Returns scroll `deltaX` and `deltaY`.\n * @param {!Event} event The scroll event\n * @return {{deltaX: number, deltaY: number}} Object containing the\n * x-axis scroll delta (positive: scroll right, negative: scroll left,\n * 0: no scroll), and the y-axis scroll delta (positive: scroll down,\n * negative: scroll up, 0: no scroll).\n * @private\n */\n\nexport function _getScrollInfo(event) {\n var info = {\n deltaX: event.deltaX,\n deltaY: event.deltaY\n }; // Already available.\n\n if ('deltaX' in event) {} // do nothing, values are already good.\n // Safari has scroll info in `wheelDeltaX/Y`.\n else if ('wheelDeltaX' in event && 'wheelDeltaY' in event) {\n info.deltaX = -event.wheelDeltaX;\n info.deltaY = -event.wheelDeltaY;\n } // IE10 has only vertical scroll info in `wheelDelta`.\n else if ('wheelDelta' in event) {\n info.deltaX = 0;\n info.deltaY = -event.wheelDelta;\n } // Firefox has scroll info in `detail` and `axis`.\n else if ('axis' in event) {\n info.deltaX = event.axis === 1 ? event.detail : 0;\n info.deltaY = event.axis === 2 ? event.detail : 0;\n } // On mobile devices, calculate scroll direction.\n else if (event.targetTouches) {\n var touch = event.targetTouches[0]; // Touch moves from right to left => scrolling goes right.\n\n info.deltaX = lastTouchPosition.pageX - touch.pageX; // Touch moves from down to up => scrolling goes down.\n\n info.deltaY = lastTouchPosition.pageY - touch.pageY;\n }\n\n return info;\n}","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\nimport { useShadow } from '@polymer/polymer/lib/utils/settings.js'; // Contains all connected resizables that do not have a parent.\n\nvar ORPHANS = new Set();\n/**\n * `IronResizableBehavior` is a behavior that can be used in Polymer elements to\n * coordinate the flow of resize events between \"resizers\" (elements that\n *control the size or hidden state of their children) and \"resizables\" (elements\n *that need to be notified when they are resized or un-hidden by their parents\n *in order to take action on their new measurements).\n *\n * Elements that perform measurement should add the `IronResizableBehavior`\n *behavior to their element definition and listen for the `iron-resize` event on\n *themselves. This event will be fired when they become showing after having\n *been hidden, when they are resized explicitly by another resizable, or when\n *the window has been resized.\n *\n * Note, the `iron-resize` event is non-bubbling.\n *\n * @polymerBehavior\n * @demo demo/index.html\n **/\n\nexport const IronResizableBehavior = {\n properties: {\n /**\n * The closest ancestor element that implements `IronResizableBehavior`.\n */\n _parentResizable: {\n type: Object,\n observer: '_parentResizableChanged'\n },\n\n /**\n * True if this element is currently notifying its descendant elements of\n * resize.\n */\n _notifyingDescendant: {\n type: Boolean,\n value: false\n }\n },\n listeners: {\n 'iron-request-resize-notifications': '_onIronRequestResizeNotifications'\n },\n created: function created() {\n // We don't really need property effects on these, and also we want them\n // to be created before the `_parentResizable` observer fires:\n this._interestedResizables = [];\n this._boundNotifyResize = this.notifyResize.bind(this);\n this._boundOnDescendantIronResize = this._onDescendantIronResize.bind(this);\n },\n attached: function attached() {\n this._requestResizeNotifications();\n },\n detached: function detached() {\n if (this._parentResizable) {\n this._parentResizable.stopResizeNotificationsFor(this);\n } else {\n ORPHANS.delete(this);\n window.removeEventListener('resize', this._boundNotifyResize);\n }\n\n this._parentResizable = null;\n },\n\n /**\n * Can be called to manually notify a resizable and its descendant\n * resizables of a resize change.\n */\n notifyResize: function notifyResize() {\n if (!this.isAttached) {\n return;\n }\n\n this._interestedResizables.forEach(function (resizable) {\n if (this.resizerShouldNotify(resizable)) {\n this._notifyDescendant(resizable);\n }\n }, this);\n\n this._fireResize();\n },\n\n /**\n * Used to assign the closest resizable ancestor to this resizable\n * if the ancestor detects a request for notifications.\n */\n assignParentResizable: function assignParentResizable(parentResizable) {\n if (this._parentResizable) {\n this._parentResizable.stopResizeNotificationsFor(this);\n }\n\n this._parentResizable = parentResizable;\n\n if (parentResizable && parentResizable._interestedResizables.indexOf(this) === -1) {\n parentResizable._interestedResizables.push(this);\n\n parentResizable._subscribeIronResize(this);\n }\n },\n\n /**\n * Used to remove a resizable descendant from the list of descendants\n * that should be notified of a resize change.\n */\n stopResizeNotificationsFor: function stopResizeNotificationsFor(target) {\n var index = this._interestedResizables.indexOf(target);\n\n if (index > -1) {\n this._interestedResizables.splice(index, 1);\n\n this._unsubscribeIronResize(target);\n }\n },\n\n /**\n * Subscribe this element to listen to iron-resize events on the given target.\n *\n * Preferred over target.listen because the property renamer does not\n * understand to rename when the target is not specifically \"this\"\n *\n * @param {!HTMLElement} target Element to listen to for iron-resize events.\n */\n _subscribeIronResize: function _subscribeIronResize(target) {\n target.addEventListener('iron-resize', this._boundOnDescendantIronResize);\n },\n\n /**\n * Unsubscribe this element from listening to to iron-resize events on the\n * given target.\n *\n * Preferred over target.unlisten because the property renamer does not\n * understand to rename when the target is not specifically \"this\"\n *\n * @param {!HTMLElement} target Element to listen to for iron-resize events.\n */\n _unsubscribeIronResize: function _unsubscribeIronResize(target) {\n target.removeEventListener('iron-resize', this._boundOnDescendantIronResize);\n },\n\n /**\n * This method can be overridden to filter nested elements that should or\n * should not be notified by the current element. Return true if an element\n * should be notified, or false if it should not be notified.\n *\n * @param {HTMLElement} element A candidate descendant element that\n * implements `IronResizableBehavior`.\n * @return {boolean} True if the `element` should be notified of resize.\n */\n resizerShouldNotify: function resizerShouldNotify(element) {\n return true;\n },\n _onDescendantIronResize: function _onDescendantIronResize(event) {\n if (this._notifyingDescendant) {\n event.stopPropagation();\n return;\n } // no need to use this during shadow dom because of event retargeting\n\n\n if (!useShadow) {\n this._fireResize();\n }\n },\n _fireResize: function _fireResize() {\n this.fire('iron-resize', null, {\n node: this,\n bubbles: false\n });\n },\n _onIronRequestResizeNotifications: function _onIronRequestResizeNotifications(event) {\n var target =\n /** @type {!EventTarget} */\n dom(event).rootTarget;\n\n if (target === this) {\n return;\n }\n\n target.assignParentResizable(this);\n\n this._notifyDescendant(target);\n\n event.stopPropagation();\n },\n _parentResizableChanged: function _parentResizableChanged(parentResizable) {\n if (parentResizable) {\n window.removeEventListener('resize', this._boundNotifyResize);\n }\n },\n _notifyDescendant: function _notifyDescendant(descendant) {\n // NOTE(cdata): In IE10, attached is fired on children first, so it's\n // important not to notify them if the parent is not attached yet (or\n // else they will get redundantly notified when the parent attaches).\n if (!this.isAttached) {\n return;\n }\n\n this._notifyingDescendant = true;\n descendant.notifyResize();\n this._notifyingDescendant = false;\n },\n _requestResizeNotifications: function _requestResizeNotifications() {\n if (!this.isAttached) {\n return;\n }\n\n if (document.readyState === 'loading') {\n var _requestResizeNotifications = this._requestResizeNotifications.bind(this);\n\n document.addEventListener('readystatechange', function readystatechanged() {\n document.removeEventListener('readystatechange', readystatechanged);\n\n _requestResizeNotifications();\n });\n } else {\n this._findParent();\n\n if (!this._parentResizable) {\n // If this resizable is an orphan, tell other orphans to try to find\n // their parent again, in case it's this resizable.\n ORPHANS.forEach(function (orphan) {\n if (orphan !== this) {\n orphan._findParent();\n }\n }, this);\n window.addEventListener('resize', this._boundNotifyResize);\n this.notifyResize();\n } else {\n // If this resizable has a parent, tell other child resizables of\n // that parent to try finding their parent again, in case it's this\n // resizable.\n this._parentResizable._interestedResizables.forEach(function (resizable) {\n if (resizable !== this) {\n resizable._findParent();\n }\n }, this);\n }\n }\n },\n _findParent: function _findParent() {\n this.assignParentResizable(null);\n this.fire('iron-request-resize-notifications', null, {\n node: this,\n bubbles: true,\n cancelable: true\n });\n\n if (!this._parentResizable) {\n ORPHANS.add(this);\n } else {\n ORPHANS.delete(this);\n }\n }\n};","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { IronSelectableBehavior } from './iron-selectable.js';\n/**\n * @polymerBehavior IronMultiSelectableBehavior\n */\n\nexport const IronMultiSelectableBehaviorImpl = {\n properties: {\n /**\n * If true, multiple selections are allowed.\n */\n multi: {\n type: Boolean,\n value: false,\n observer: 'multiChanged'\n },\n\n /**\n * Gets or sets the selected elements. This is used instead of `selected`\n * when `multi` is true.\n */\n selectedValues: {\n type: Array,\n notify: true,\n value: function value() {\n return [];\n }\n },\n\n /**\n * Returns an array of currently selected items.\n */\n selectedItems: {\n type: Array,\n readOnly: true,\n notify: true,\n value: function value() {\n return [];\n }\n }\n },\n observers: ['_updateSelected(selectedValues.splices)'],\n\n /**\n * Selects the given value. If the `multi` property is true, then the selected\n * state of the `value` will be toggled; otherwise the `value` will be\n * selected.\n *\n * @method select\n * @param {string|number} value the value to select.\n */\n select: function select(value) {\n if (this.multi) {\n this._toggleSelected(value);\n } else {\n this.selected = value;\n }\n },\n multiChanged: function multiChanged(multi) {\n this._selection.multi = multi;\n\n this._updateSelected();\n },\n\n // UNUSED, FOR API COMPATIBILITY\n get _shouldUpdateSelection() {\n return this.selected != null || this.selectedValues != null && this.selectedValues.length;\n },\n\n _updateAttrForSelected: function _updateAttrForSelected() {\n if (!this.multi) {\n IronSelectableBehavior._updateAttrForSelected.apply(this);\n } else if (this.selectedItems && this.selectedItems.length > 0) {\n this.selectedValues = this.selectedItems.map(function (selectedItem) {\n return this._indexToValue(this.indexOf(selectedItem));\n }, this).filter(function (unfilteredValue) {\n return unfilteredValue != null;\n }, this);\n }\n },\n _updateSelected: function _updateSelected() {\n if (this.multi) {\n this._selectMulti(this.selectedValues);\n } else {\n this._selectSelected(this.selected);\n }\n },\n _selectMulti: function _selectMulti(values) {\n values = values || [];\n var selectedItems = (this._valuesToItems(values) || []).filter(function (item) {\n return item !== null && item !== undefined;\n }); // clear all but the current selected items\n\n this._selection.clear(selectedItems); // select only those not selected yet\n\n\n for (var i = 0; i < selectedItems.length; i++) {\n this._selection.setItemSelected(selectedItems[i], true);\n } // Check for items, since this array is populated only when attached\n\n\n if (this.fallbackSelection && !this._selection.get().length) {\n var fallback = this._valueToItem(this.fallbackSelection);\n\n if (fallback) {\n this.select(this.fallbackSelection);\n }\n }\n },\n _selectionChange: function _selectionChange() {\n var s = this._selection.get();\n\n if (this.multi) {\n this._setSelectedItems(s);\n\n this._setSelectedItem(s.length ? s[0] : null);\n } else {\n if (s !== null && s !== undefined) {\n this._setSelectedItems([s]);\n\n this._setSelectedItem(s);\n } else {\n this._setSelectedItems([]);\n\n this._setSelectedItem(null);\n }\n }\n },\n _toggleSelected: function _toggleSelected(value) {\n var i = this.selectedValues.indexOf(value);\n var unselected = i < 0;\n\n if (unselected) {\n this.push('selectedValues', value);\n } else {\n this.splice('selectedValues', i, 1);\n }\n },\n _valuesToItems: function _valuesToItems(values) {\n return values == null ? null : values.map(function (value) {\n return this._valueToItem(value);\n }, this);\n }\n};\n/** @polymerBehavior */\n\nexport const IronMultiSelectableBehavior = [IronSelectableBehavior, IronMultiSelectableBehaviorImpl];","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\nimport { dashToCamelCase } from '@polymer/polymer/lib/utils/case-map.js';\nimport { IronSelection } from './iron-selection.js';\n/**\n * @polymerBehavior\n */\n\nexport const IronSelectableBehavior = {\n /**\n * Fired when iron-selector is activated (selected or deselected).\n * It is fired before the selected items are changed.\n * Cancel the event to abort selection.\n *\n * @event iron-activate\n */\n\n /**\n * Fired when an item is selected\n *\n * @event iron-select\n */\n\n /**\n * Fired when an item is deselected\n *\n * @event iron-deselect\n */\n\n /**\n * Fired when the list of selectable items changes (e.g., items are\n * added or removed). The detail of the event is a mutation record that\n * describes what changed.\n *\n * @event iron-items-changed\n */\n properties: {\n /**\n * If you want to use an attribute value or property of an element for\n * `selected` instead of the index, set this to the name of the attribute\n * or property. Hyphenated values are converted to camel case when used to\n * look up the property of a selectable element. Camel cased values are\n * *not* converted to hyphenated values for attribute lookup. It's\n * recommended that you provide the hyphenated form of the name so that\n * selection works in both cases. (Use `attr-or-property-name` instead of\n * `attrOrPropertyName`.)\n */\n attrForSelected: {\n type: String,\n value: null\n },\n\n /**\n * Gets or sets the selected element. The default is to use the index of the\n * item.\n * @type {string|number}\n */\n selected: {\n type: String,\n notify: true\n },\n\n /**\n * Returns the currently selected item.\n *\n * @type {?Object}\n */\n selectedItem: {\n type: Object,\n readOnly: true,\n notify: true\n },\n\n /**\n * The event that fires from items when they are selected. Selectable\n * will listen for this event from items and update the selection state.\n * Set to empty string to listen to no events.\n */\n activateEvent: {\n type: String,\n value: 'tap',\n observer: '_activateEventChanged'\n },\n\n /**\n * This is a CSS selector string. If this is set, only items that match the\n * CSS selector are selectable.\n */\n selectable: String,\n\n /**\n * The class to set on elements when selected.\n */\n selectedClass: {\n type: String,\n value: 'iron-selected'\n },\n\n /**\n * The attribute to set on elements when selected.\n */\n selectedAttribute: {\n type: String,\n value: null\n },\n\n /**\n * Default fallback if the selection based on selected with\n * `attrForSelected` is not found.\n */\n fallbackSelection: {\n type: String,\n value: null\n },\n\n /**\n * The list of items from which a selection can be made.\n */\n items: {\n type: Array,\n readOnly: true,\n notify: true,\n value: function value() {\n return [];\n }\n },\n\n /**\n * The set of excluded elements where the key is the `localName`\n * of the element that will be ignored from the item list.\n *\n * @default {template: 1}\n */\n _excludedLocalNames: {\n type: Object,\n value: function value() {\n return {\n 'template': 1,\n 'dom-bind': 1,\n 'dom-if': 1,\n 'dom-repeat': 1\n };\n }\n }\n },\n observers: ['_updateAttrForSelected(attrForSelected)', '_updateSelected(selected)', '_checkFallback(fallbackSelection)'],\n created: function created() {\n this._bindFilterItem = this._filterItem.bind(this);\n this._selection = new IronSelection(this._applySelection.bind(this));\n },\n attached: function attached() {\n this._observer = this._observeItems(this);\n\n this._addListener(this.activateEvent);\n },\n detached: function detached() {\n if (this._observer) {\n dom(this).unobserveNodes(this._observer);\n }\n\n this._removeListener(this.activateEvent);\n },\n\n /**\n * Returns the index of the given item.\n *\n * @method indexOf\n * @param {Object} item\n * @returns Returns the index of the item\n */\n indexOf: function indexOf(item) {\n return this.items ? this.items.indexOf(item) : -1;\n },\n\n /**\n * Selects the given value.\n *\n * @method select\n * @param {string|number} value the value to select.\n */\n select: function select(value) {\n this.selected = value;\n },\n\n /**\n * Selects the previous item.\n *\n * @method selectPrevious\n */\n selectPrevious: function selectPrevious() {\n var length = this.items.length;\n var index = length - 1;\n\n if (this.selected !== undefined) {\n index = (Number(this._valueToIndex(this.selected)) - 1 + length) % length;\n }\n\n this.selected = this._indexToValue(index);\n },\n\n /**\n * Selects the next item.\n *\n * @method selectNext\n */\n selectNext: function selectNext() {\n var index = 0;\n\n if (this.selected !== undefined) {\n index = (Number(this._valueToIndex(this.selected)) + 1) % this.items.length;\n }\n\n this.selected = this._indexToValue(index);\n },\n\n /**\n * Selects the item at the given index.\n *\n * @method selectIndex\n */\n selectIndex: function selectIndex(index) {\n this.select(this._indexToValue(index));\n },\n\n /**\n * Force a synchronous update of the `items` property.\n *\n * NOTE: Consider listening for the `iron-items-changed` event to respond to\n * updates to the set of selectable items after updates to the DOM list and\n * selection state have been made.\n *\n * WARNING: If you are using this method, you should probably consider an\n * alternate approach. Synchronously querying for items is potentially\n * slow for many use cases. The `items` property will update asynchronously\n * on its own to reflect selectable items in the DOM.\n */\n forceSynchronousItemUpdate: function forceSynchronousItemUpdate() {\n if (this._observer && typeof this._observer.flush === 'function') {\n // NOTE(bicknellr): `dom.flush` above is no longer sufficient to trigger\n // `observeNodes` callbacks. Polymer 2.x returns an object from\n // `observeNodes` with a `flush` that synchronously gives the callback any\n // pending MutationRecords (retrieved with `takeRecords`). Any case where\n // ShadyDOM flushes were expected to synchronously trigger item updates\n // will now require calling `forceSynchronousItemUpdate`.\n this._observer.flush();\n } else {\n this._updateItems();\n }\n },\n\n // UNUSED, FOR API COMPATIBILITY\n get _shouldUpdateSelection() {\n return this.selected != null;\n },\n\n _checkFallback: function _checkFallback() {\n this._updateSelected();\n },\n _addListener: function _addListener(eventName) {\n this.listen(this, eventName, '_activateHandler');\n },\n _removeListener: function _removeListener(eventName) {\n this.unlisten(this, eventName, '_activateHandler');\n },\n _activateEventChanged: function _activateEventChanged(eventName, old) {\n this._removeListener(old);\n\n this._addListener(eventName);\n },\n _updateItems: function _updateItems() {\n var nodes = dom(this).queryDistributedElements(this.selectable || '*');\n nodes = Array.prototype.filter.call(nodes, this._bindFilterItem);\n\n this._setItems(nodes);\n },\n _updateAttrForSelected: function _updateAttrForSelected() {\n if (this.selectedItem) {\n this.selected = this._valueForItem(this.selectedItem);\n }\n },\n _updateSelected: function _updateSelected() {\n this._selectSelected(this.selected);\n },\n _selectSelected: function _selectSelected(selected) {\n if (!this.items) {\n return;\n }\n\n var item = this._valueToItem(this.selected);\n\n if (item) {\n this._selection.select(item);\n } else {\n this._selection.clear();\n } // Check for items, since this array is populated only when attached\n // Since Number(0) is falsy, explicitly check for undefined\n\n\n if (this.fallbackSelection && this.items.length && this._selection.get() === undefined) {\n this.selected = this.fallbackSelection;\n }\n },\n _filterItem: function _filterItem(node) {\n return !this._excludedLocalNames[node.localName];\n },\n _valueToItem: function _valueToItem(value) {\n return value == null ? null : this.items[this._valueToIndex(value)];\n },\n _valueToIndex: function _valueToIndex(value) {\n if (this.attrForSelected) {\n for (var i = 0, item; item = this.items[i]; i++) {\n if (this._valueForItem(item) == value) {\n return i;\n }\n }\n } else {\n return Number(value);\n }\n },\n _indexToValue: function _indexToValue(index) {\n if (this.attrForSelected) {\n var item = this.items[index];\n\n if (item) {\n return this._valueForItem(item);\n }\n } else {\n return index;\n }\n },\n _valueForItem: function _valueForItem(item) {\n if (!item) {\n return null;\n }\n\n if (!this.attrForSelected) {\n var i = this.indexOf(item);\n return i === -1 ? null : i;\n }\n\n var propValue = item[dashToCamelCase(this.attrForSelected)];\n return propValue != undefined ? propValue : item.getAttribute(this.attrForSelected);\n },\n _applySelection: function _applySelection(item, isSelected) {\n if (this.selectedClass) {\n this.toggleClass(this.selectedClass, isSelected, item);\n }\n\n if (this.selectedAttribute) {\n this.toggleAttribute(this.selectedAttribute, isSelected, item);\n }\n\n this._selectionChange();\n\n this.fire('iron-' + (isSelected ? 'select' : 'deselect'), {\n item: item\n });\n },\n _selectionChange: function _selectionChange() {\n this._setSelectedItem(this._selection.get());\n },\n // observe items change under the given node.\n _observeItems: function _observeItems(node) {\n return dom(node).observeNodes(function (mutation) {\n this._updateItems();\n\n this._updateSelected(); // Let other interested parties know about the change so that\n // we don't have to recreate mutation observers everywhere.\n\n\n this.fire('iron-items-changed', mutation, {\n bubbles: false,\n cancelable: false\n });\n });\n },\n _activateHandler: function _activateHandler(e) {\n var t = e.target;\n var items = this.items;\n\n while (t && t != this) {\n var i = items.indexOf(t);\n\n if (i >= 0) {\n var value = this._indexToValue(i);\n\n this._itemActivate(value, t);\n\n return;\n }\n\n t = t.parentNode;\n }\n },\n _itemActivate: function _itemActivate(value, item) {\n if (!this.fire('iron-activate', {\n selected: value,\n item: item\n }, {\n cancelable: true\n }).defaultPrevented) {\n this.select(value);\n }\n }\n};","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nexport class IronSelection {\n /**\n * @param {!Function} selectCallback\n * @suppress {missingProvide}\n */\n constructor(selectCallback) {\n this.selection = [];\n this.selectCallback = selectCallback;\n }\n /**\n * Retrieves the selected item(s).\n *\n * @returns Returns the selected item(s). If the multi property is true,\n * `get` will return an array, otherwise it will return\n * the selected item or undefined if there is no selection.\n */\n\n\n get() {\n return this.multi ? this.selection.slice() : this.selection[0];\n }\n /**\n * Clears all the selection except the ones indicated.\n *\n * @param {Array} excludes items to be excluded.\n */\n\n\n clear(excludes) {\n this.selection.slice().forEach(function (item) {\n if (!excludes || excludes.indexOf(item) < 0) {\n this.setItemSelected(item, false);\n }\n }, this);\n }\n /**\n * Indicates if a given item is selected.\n *\n * @param {*} item The item whose selection state should be checked.\n * @return {boolean} Returns true if `item` is selected.\n */\n\n\n isSelected(item) {\n return this.selection.indexOf(item) >= 0;\n }\n /**\n * Sets the selection state for a given item to either selected or deselected.\n *\n * @param {*} item The item to select.\n * @param {boolean} isSelected True for selected, false for deselected.\n */\n\n\n setItemSelected(item, isSelected) {\n if (item != null) {\n if (isSelected !== this.isSelected(item)) {\n // proceed to update selection only if requested state differs from\n // current\n if (isSelected) {\n this.selection.push(item);\n } else {\n var i = this.selection.indexOf(item);\n\n if (i >= 0) {\n this.selection.splice(i, 1);\n }\n }\n\n if (this.selectCallback) {\n this.selectCallback(item, isSelected);\n }\n }\n }\n }\n /**\n * Sets the selection state for a given item. If the `multi` property\n * is true, then the selected state of `item` will be toggled; otherwise\n * the `item` will be selected.\n *\n * @param {*} item The item to select.\n */\n\n\n select(item) {\n if (this.multi) {\n this.toggle(item);\n } else if (this.get() !== item) {\n this.setItemSelected(this.get(), false);\n this.setItemSelected(item, true);\n }\n }\n /**\n * Toggles the selection state for `item`.\n *\n * @param {*} item The item to toggle.\n */\n\n\n toggle(item) {\n this.setItemSelected(item, !this.isSelected(item));\n }\n\n}\n;","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { IronMeta } from '@polymer/iron-meta/iron-meta.js';\n/**\n * Singleton IronMeta instance.\n */\n\nexport let IronValidatableBehaviorMeta = null;\n/**\n * `Use IronValidatableBehavior` to implement an element that validates\n * user input. Use the related `IronValidatorBehavior` to add custom\n * validation logic to an iron-input.\n *\n * By default, an `` element validates its fields when the user\n * presses the submit button. To validate a form imperatively, call the form's\n * `validate()` method, which in turn will call `validate()` on all its\n * children. By using `IronValidatableBehavior`, your custom element\n * will get a public `validate()`, which will return the validity of the\n * element, and a corresponding `invalid` attribute, which can be used for\n * styling.\n *\n * To implement the custom validation logic of your element, you must override\n * the protected `_getValidity()` method of this behaviour, rather than\n * `validate()`. See\n * [this](https://github.com/PolymerElements/iron-form/blob/master/demo/simple-element.html)\n * for an example.\n *\n * ### Accessibility\n *\n * Changing the `invalid` property, either manually or by calling `validate()`\n * will update the `aria-invalid` attribute.\n *\n * @demo demo/index.html\n * @polymerBehavior\n */\n\nexport const IronValidatableBehavior = {\n properties: {\n /**\n * Name of the validator to use.\n */\n validator: {\n type: String\n },\n\n /**\n * True if the last call to `validate` is invalid.\n */\n invalid: {\n notify: true,\n reflectToAttribute: true,\n type: Boolean,\n value: false,\n observer: '_invalidChanged'\n }\n },\n registered: function registered() {\n IronValidatableBehaviorMeta = new IronMeta({\n type: 'validator'\n });\n },\n _invalidChanged: function _invalidChanged() {\n if (this.invalid) {\n this.setAttribute('aria-invalid', 'true');\n } else {\n this.removeAttribute('aria-invalid');\n }\n },\n\n /* Recompute this every time it's needed, because we don't know if the\n * underlying IronValidatableBehaviorMeta has changed. */\n get _validator() {\n return IronValidatableBehaviorMeta && IronValidatableBehaviorMeta.byKey(this.validator);\n },\n\n /**\n * @return {boolean} True if the validator `validator` exists.\n */\n hasValidator: function hasValidator() {\n return this._validator != null;\n },\n\n /**\n * Returns true if the `value` is valid, and updates `invalid`. If you want\n * your element to have custom validation logic, do not override this method;\n * override `_getValidity(value)` instead.\n * @param {Object} value Deprecated: The value to be validated. By default,\n * it is passed to the validator's `validate()` function, if a validator is\n set.\n * If this argument is not specified, then the element's `value` property\n * is used, if it exists.\n * @return {boolean} True if `value` is valid.\n */\n validate: function validate(value) {\n // If this is an element that also has a value property, and there was\n // no explicit value argument passed, use the element's property instead.\n if (value === undefined && this.value !== undefined) this.invalid = !this._getValidity(this.value);else this.invalid = !this._getValidity(value);\n return !this.invalid;\n },\n\n /**\n * Returns true if `value` is valid. By default, it is passed\n * to the validator's `validate()` function, if a validator is set. You\n * should override this method if you want to implement custom validity\n * logic for your element.\n *\n * @param {Object} value The value to be validated.\n * @return {boolean} True if `value` is valid.\n */\n _getValidity: function _getValidity(value) {\n if (this.hasValidator()) {\n return this._validator.validate(value);\n }\n\n return true;\n }\n};","/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n\n/**\n * Class decorator factory that defines the decorated class as a custom element.\n *\n * @param tagName the name of the custom element to define\n *\n * In TypeScript, the `tagName` passed to `customElement` should be a key of the\n * `HTMLElementTagNameMap` interface. To add your element to the interface,\n * declare the interface in this module:\n *\n * @customElement('my-element')\n * export class MyElement extends LitElement {}\n *\n * declare global {\n * interface HTMLElementTagNameMap {\n * 'my-element': MyElement;\n * }\n * }\n *\n */\nexport const customElement = tagName => clazz => {\n window.customElements.define(tagName, clazz); // Cast as any because TS doesn't recognize the return type as being a\n // subtype of the decorated class when clazz is typed as\n // `Constructor` for some reason. `Constructor`\n // is helpful to make sure the decorator is applied to elements however.\n\n return clazz;\n};\n/**\n * A property decorator which creates a LitElement property which reflects a\n * corresponding attribute value. A `PropertyDeclaration` may optionally be\n * supplied to configure property features.\n */\n\nexport const property = options => (proto, name) => {\n proto.constructor.createProperty(name, options);\n};\n/**\n * A property decorator that converts a class property into a getter that\n * executes a querySelector on the element's renderRoot.\n */\n\nexport const query = _query((target, selector) => target.querySelector(selector));\n/**\n * A property decorator that converts a class property into a getter\n * that executes a querySelectorAll on the element's renderRoot.\n */\n\nexport const queryAll = _query((target, selector) => target.querySelectorAll(selector));\n/**\n * Base-implementation of `@query` and `@queryAll` decorators.\n *\n * @param queryFn exectute a `selector` (ie, querySelector or querySelectorAll)\n * against `target`.\n */\n\nfunction _query(queryFn) {\n return selector => (proto, propName) => {\n Object.defineProperty(proto, propName, {\n get() {\n return queryFn(this.renderRoot, selector);\n },\n\n enumerable: true,\n configurable: true\n });\n };\n}\n/**\n * Adds event listener options to a method used as an event listener in a\n * lit-html template.\n *\n * @param options An object that specifis event listener options as accepted by\n * `EventTarget#addEventListener` and `EventTarget#removeEventListener`.\n *\n * Current browsers support the `capture`, `passive`, and `once` options. See:\n * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Parameters\n *\n * @example\n *\n * class MyElement {\n *\n * clicked = false;\n *\n * render() {\n * return html`
`;\n * }\n *\n * @eventOptions({capture: true})\n * _onClick(e) {\n * this.clicked = true;\n * }\n * }\n */\n\n\nexport const eventOptions = options => (proto, name) => {\n // This comment is here to fix a disagreement between formatter and linter\n Object.assign(proto[name], options);\n};","function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }\n\nfunction _nonIterableRest() { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); }\n\nfunction _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"] != null) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; }\n\nfunction _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }\n\n/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n// serializer/deserializers for boolean attribute\nconst fromBooleanAttribute = value => value !== null;\n\nconst toBooleanAttribute = value => value ? '' : null;\n/**\n * Change function that returns true if `value` is different from `oldValue`.\n * This method is used as the default for a property's `hasChanged` function.\n */\n\n\nexport const notEqual = (value, old) => {\n // This ensures (old==NaN, value==NaN) always returns false\n return old !== value && (old === old || value === value);\n};\nconst defaultPropertyDeclaration = {\n attribute: true,\n type: String,\n reflect: false,\n hasChanged: notEqual\n};\nconst microtaskPromise = new Promise(resolve => resolve(true));\nconst STATE_HAS_UPDATED = 1;\nconst STATE_UPDATE_REQUESTED = 1 << 2;\nconst STATE_IS_REFLECTING = 1 << 3;\n/**\n * Base element class which manages element properties and attributes. When\n * properties change, the `update` method is asynchronously called. This method\n * should be supplied by subclassers to render updates as desired.\n */\n\nexport class UpdatingElement extends HTMLElement {\n constructor() {\n super();\n this._updateState = 0;\n this._instanceProperties = undefined;\n this._updatePromise = microtaskPromise;\n /**\n * Map with keys for any properties that have changed since the last\n * update cycle with previous values.\n */\n\n this._changedProperties = new Map();\n /**\n * Map with keys of properties that should be reflected when updated.\n */\n\n this._reflectingProperties = undefined;\n this.initialize();\n }\n /**\n * Returns a list of attributes corresponding to the registered properties.\n */\n\n\n static get observedAttributes() {\n // note: piggy backing on this to ensure we're _finalized.\n this._finalize();\n\n const attributes = [];\n\n for (const _ref of this._classProperties) {\n var _ref2 = _slicedToArray(_ref, 2);\n\n const p = _ref2[0];\n const v = _ref2[1];\n\n const attr = this._attributeNameForProperty(p, v);\n\n if (attr !== undefined) {\n this._attributeToPropertyMap.set(attr, p);\n\n attributes.push(attr);\n }\n }\n\n return attributes;\n }\n /**\n * Creates a property accessor on the element prototype if one does not exist.\n * The property setter calls the property's `hasChanged` property option\n * or uses a strict identity check to determine whether or not to request\n * an update.\n */\n\n\n static createProperty(name) {\n let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultPropertyDeclaration;\n\n // ensure private storage for property declarations.\n if (!this.hasOwnProperty('_classProperties')) {\n this._classProperties = new Map(); // NOTE: Workaround IE11 not supporting Map constructor argument.\n\n const superProperties = Object.getPrototypeOf(this)._classProperties;\n\n if (superProperties !== undefined) {\n superProperties.forEach((v, k) => this._classProperties.set(k, v));\n }\n }\n\n this._classProperties.set(name, options); // Allow user defined accessors by not replacing an existing own-property\n // accessor.\n\n\n if (this.prototype.hasOwnProperty(name)) {\n return;\n }\n\n const key = typeof name === 'symbol' ? Symbol() : `__${name}`;\n Object.defineProperty(this.prototype, name, {\n get() {\n return this[key];\n },\n\n set(value) {\n const oldValue = this[name];\n this[key] = value;\n\n this._requestPropertyUpdate(name, oldValue, options);\n },\n\n configurable: true,\n enumerable: true\n });\n }\n /**\n * Creates property accessors for registered properties and ensures\n * any superclasses are also finalized.\n */\n\n\n static _finalize() {\n if (this.hasOwnProperty('_finalized') && this._finalized) {\n return;\n } // finalize any superclasses\n\n\n const superCtor = Object.getPrototypeOf(this);\n\n if (typeof superCtor._finalize === 'function') {\n superCtor._finalize();\n }\n\n this._finalized = true; // initialize Map populated in observedAttributes\n\n this._attributeToPropertyMap = new Map(); // make any properties\n\n const props = this.properties; // support symbols in properties (IE11 does not support this)\n\n const propKeys = [...Object.getOwnPropertyNames(props), ...(typeof Object.getOwnPropertySymbols === 'function' ? Object.getOwnPropertySymbols(props) : [])];\n\n for (const p of propKeys) {\n // note, use of `any` is due to TypeSript lack of support for symbol in\n // index types\n this.createProperty(p, props[p]);\n }\n }\n /**\n * Returns the property name for the given attribute `name`.\n */\n\n\n static _attributeNameForProperty(name, options) {\n const attribute = options !== undefined && options.attribute;\n return attribute === false ? undefined : typeof attribute === 'string' ? attribute : typeof name === 'string' ? name.toLowerCase() : undefined;\n }\n /**\n * Returns true if a property should request an update.\n * Called when a property value is set and uses the `hasChanged`\n * option for the property if present or a strict identity check.\n */\n\n\n static _valueHasChanged(value, old) {\n let hasChanged = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : notEqual;\n return hasChanged(value, old);\n }\n /**\n * Returns the property value for the given attribute value.\n * Called via the `attributeChangedCallback` and uses the property's `type`\n * or `type.fromAttribute` property option.\n */\n\n\n static _propertyValueFromAttribute(value, options) {\n const type = options && options.type;\n\n if (type === undefined) {\n return value;\n } // Note: special case `Boolean` so users can use it as a `type`.\n\n\n const fromAttribute = type === Boolean ? fromBooleanAttribute : typeof type === 'function' ? type : type.fromAttribute;\n return fromAttribute ? fromAttribute(value) : value;\n }\n /**\n * Returns the attribute value for the given property value. If this\n * returns undefined, the property will *not* be reflected to an attribute.\n * If this returns null, the attribute will be removed, otherwise the\n * attribute will be set to the value.\n * This uses the property's `reflect` and `type.toAttribute` property options.\n */\n\n\n static _propertyValueToAttribute(value, options) {\n if (options === undefined || options.reflect === undefined) {\n return;\n } // Note: special case `Boolean` so users can use it as a `type`.\n\n\n const toAttribute = options.type === Boolean ? toBooleanAttribute : options.type && options.type.toAttribute || String;\n return toAttribute(value);\n }\n /**\n * Performs element initialization. By default this calls `createRenderRoot`\n * to create the element `renderRoot` node and captures any pre-set values for\n * registered properties.\n */\n\n\n initialize() {\n this.renderRoot = this.createRenderRoot();\n\n this._saveInstanceProperties();\n }\n /**\n * Fixes any properties set on the instance before upgrade time.\n * Otherwise these would shadow the accessor and break these properties.\n * The properties are stored in a Map which is played back after the\n * constructor runs. Note, on very old versions of Safari (<=9) or Chrome\n * (<=41), properties created for native platform properties like (`id` or\n * `name`) may not have default values set in the element constructor. On\n * these browsers native properties appear on instances and therefore their\n * default value will overwrite any element default (e.g. if the element sets\n * this.id = 'id' in the constructor, the 'id' will become '' since this is\n * the native platform default).\n */\n\n\n _saveInstanceProperties() {\n for (const _ref3 of this.constructor._classProperties) {\n var _ref4 = _slicedToArray(_ref3, 1);\n\n const p = _ref4[0];\n\n if (this.hasOwnProperty(p)) {\n const value = this[p];\n delete this[p];\n\n if (!this._instanceProperties) {\n this._instanceProperties = new Map();\n }\n\n this._instanceProperties.set(p, value);\n }\n }\n }\n /**\n * Applies previously saved instance properties.\n */\n\n\n _applyInstanceProperties() {\n for (const _ref5 of this._instanceProperties) {\n var _ref6 = _slicedToArray(_ref5, 2);\n\n const p = _ref6[0];\n const v = _ref6[1];\n this[p] = v;\n }\n\n this._instanceProperties = undefined;\n }\n /**\n * Returns the node into which the element should render and by default\n * creates and returns an open shadowRoot. Implement to customize where the\n * element's DOM is rendered. For example, to render into the element's\n * childNodes, return `this`.\n * @returns {Element|DocumentFragment} Returns a node into which to render.\n */\n\n\n createRenderRoot() {\n return this.attachShadow({\n mode: 'open'\n });\n }\n /**\n * Uses ShadyCSS to keep element DOM updated.\n */\n\n\n connectedCallback() {\n if (this._updateState & STATE_HAS_UPDATED) {\n if (window.ShadyCSS !== undefined) {\n window.ShadyCSS.styleElement(this);\n }\n } else {\n this.requestUpdate();\n }\n }\n /**\n * Allows for `super.disconnectedCallback()` in extensions while\n * reserving the possibility of making non-breaking feature additions\n * when disconnecting at some point in the future.\n */\n\n\n disconnectedCallback() {}\n /**\n * Synchronizes property values when attributes change.\n */\n\n\n attributeChangedCallback(name, old, value) {\n if (old !== value) {\n this._attributeToProperty(name, value);\n }\n }\n\n _propertyToAttribute(name, value) {\n let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultPropertyDeclaration;\n const ctor = this.constructor;\n\n const attrValue = ctor._propertyValueToAttribute(value, options);\n\n if (attrValue !== undefined) {\n const attr = ctor._attributeNameForProperty(name, options);\n\n if (attr !== undefined) {\n // Track if the property is being reflected to avoid\n // setting the property again via `attributeChangedCallback`. Note:\n // 1. this takes advantage of the fact that the callback is synchronous.\n // 2. will behave incorrectly if multiple attributes are in the reaction\n // stack at time of calling. However, since we process attributes\n // in `update` this should not be possible (or an extreme corner case\n // that we'd like to discover).\n // mark state reflecting\n this._updateState = this._updateState | STATE_IS_REFLECTING;\n\n if (attrValue === null) {\n this.removeAttribute(attr);\n } else {\n this.setAttribute(attr, attrValue);\n } // mark state not reflecting\n\n\n this._updateState = this._updateState & ~STATE_IS_REFLECTING;\n }\n }\n }\n\n _attributeToProperty(name, value) {\n // Use tracking info to avoid deserializing attribute value if it was\n // just set from a property setter.\n if (!(this._updateState & STATE_IS_REFLECTING)) {\n const ctor = this.constructor;\n\n const propName = ctor._attributeToPropertyMap.get(name);\n\n if (propName !== undefined) {\n const options = ctor._classProperties.get(propName);\n\n this[propName] = ctor._propertyValueFromAttribute(value, options);\n }\n }\n }\n /**\n * Requests an update which is processed asynchronously. This should\n * be called when an element should update based on some state not triggered\n * by setting a property. In this case, pass no arguments. It should also be\n * called when manually implementing a property setter. In this case, pass the\n * property `name` and `oldValue` to ensure that any configured property\n * options are honored. Returns the `updateComplete` Promise which is resolved\n * when the update completes.\n *\n * @param name {PropertyKey} (optional) name of requesting property\n * @param oldValue {any} (optional) old value of requesting property\n * @returns {Promise} A Promise that is resolved when the update completes.\n */\n\n\n requestUpdate(name, oldValue) {\n if (name !== undefined) {\n const options = this.constructor._classProperties.get(name) || defaultPropertyDeclaration;\n return this._requestPropertyUpdate(name, oldValue, options);\n }\n\n return this._invalidate();\n }\n /**\n * Requests an update for a specific property and records change information.\n * @param name {PropertyKey} name of requesting property\n * @param oldValue {any} old value of requesting property\n * @param options {PropertyDeclaration}\n */\n\n\n _requestPropertyUpdate(name, oldValue, options) {\n if (!this.constructor._valueHasChanged(this[name], oldValue, options.hasChanged)) {\n return this.updateComplete;\n } // track old value when changing.\n\n\n if (!this._changedProperties.has(name)) {\n this._changedProperties.set(name, oldValue);\n } // add to reflecting properties set\n\n\n if (options.reflect === true) {\n if (this._reflectingProperties === undefined) {\n this._reflectingProperties = new Map();\n }\n\n this._reflectingProperties.set(name, options);\n }\n\n return this._invalidate();\n }\n /**\n * Invalidates the element causing it to asynchronously update regardless\n * of whether or not any property changes are pending. This method is\n * automatically called when any registered property changes.\n */\n\n\n async _invalidate() {\n if (!this._hasRequestedUpdate) {\n // mark state updating...\n this._updateState = this._updateState | STATE_UPDATE_REQUESTED;\n let resolver;\n const previousValidatePromise = this._updatePromise;\n this._updatePromise = new Promise(r => resolver = r);\n await previousValidatePromise;\n\n this._validate();\n\n resolver(!this._hasRequestedUpdate);\n }\n\n return this.updateComplete;\n }\n\n get _hasRequestedUpdate() {\n return this._updateState & STATE_UPDATE_REQUESTED;\n }\n /**\n * Validates the element by updating it.\n */\n\n\n _validate() {\n // Mixin instance properties once, if they exist.\n if (this._instanceProperties) {\n this._applyInstanceProperties();\n }\n\n if (this.shouldUpdate(this._changedProperties)) {\n const changedProperties = this._changedProperties;\n this.update(changedProperties);\n\n this._markUpdated();\n\n if (!(this._updateState & STATE_HAS_UPDATED)) {\n this._updateState = this._updateState | STATE_HAS_UPDATED;\n this.firstUpdated(changedProperties);\n }\n\n this.updated(changedProperties);\n } else {\n this._markUpdated();\n }\n }\n\n _markUpdated() {\n this._changedProperties = new Map();\n this._updateState = this._updateState & ~STATE_UPDATE_REQUESTED;\n }\n /**\n * Returns a Promise that resolves when the element has completed updating.\n * The Promise value is a boolean that is `true` if the element completed the\n * update without triggering another update. The Promise result is `false` if\n * a property was set inside `updated()`. This getter can be implemented to\n * await additional state. For example, it is sometimes useful to await a\n * rendered element before fulfilling this Promise. To do this, first await\n * `super.updateComplete` then any subsequent state.\n *\n * @returns {Promise} The Promise returns a boolean that indicates if the\n * update resolved without triggering another update.\n */\n\n\n get updateComplete() {\n return this._updatePromise;\n }\n /**\n * Controls whether or not `update` should be called when the element requests\n * an update. By default, this method always returns `true`, but this can be\n * customized to control when to update.\n *\n * * @param _changedProperties Map of changed properties with old values\n */\n\n\n shouldUpdate(_changedProperties) {\n return true;\n }\n /**\n * Updates the element. This method reflects property values to attributes.\n * It can be overridden to render and keep updated DOM in the element's\n * `renderRoot`. Setting properties inside this method will *not* trigger\n * another update.\n *\n * * @param _changedProperties Map of changed properties with old values\n */\n\n\n update(_changedProperties) {\n if (this._reflectingProperties !== undefined && this._reflectingProperties.size > 0) {\n for (const _ref7 of this._reflectingProperties) {\n var _ref8 = _slicedToArray(_ref7, 2);\n\n const k = _ref8[0];\n const v = _ref8[1];\n\n this._propertyToAttribute(k, this[k], v);\n }\n\n this._reflectingProperties = undefined;\n }\n }\n /**\n * Invoked whenever the element is updated. Implement to perform\n * post-updating tasks via DOM APIs, for example, focusing an element.\n *\n * Setting properties inside this method will trigger the element to update\n * again after this update cycle completes.\n *\n * * @param _changedProperties Map of changed properties with old values\n */\n\n\n updated(_changedProperties) {}\n /**\n * Invoked when the element is first updated. Implement to perform one time\n * work on the element after update.\n *\n * Setting properties inside this method will trigger the element to update\n * again after this update cycle completes.\n *\n * * @param _changedProperties Map of changed properties with old values\n */\n\n\n firstUpdated(_changedProperties) {}\n\n}\n/**\n * Maps attribute names to properties; for example `foobar` attribute\n * to `fooBar` property.\n */\n\nUpdatingElement._attributeToPropertyMap = new Map();\n/**\n * Marks class as having finished creating properties.\n */\n\nUpdatingElement._finalized = true;\n/**\n * Memoized list of all class properties, including any superclass properties.\n */\n\nUpdatingElement._classProperties = new Map();\nUpdatingElement.properties = {};","/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\nimport { TemplateResult } from 'lit-html';\nimport { render } from 'lit-html/lib/shady-render';\nimport { UpdatingElement } from './lib/updating-element.js';\nexport * from './lib/updating-element.js';\nexport * from './lib/decorators.js';\nexport { html, svg } from 'lit-html/lit-html';\nexport class LitElement extends UpdatingElement {\n /**\n * Updates the element. This method reflects property values to attributes\n * and calls `render` to render DOM via lit-html. Setting properties inside\n * this method will *not* trigger another update.\n * * @param _changedProperties Map of changed properties with old values\n */\n update(changedProperties) {\n super.update(changedProperties);\n const templateResult = this.render();\n\n if (templateResult instanceof TemplateResult) {\n this.constructor.render(templateResult, this.renderRoot, {\n scopeName: this.localName,\n eventContext: this\n });\n }\n }\n /**\n * Invoked on each update to perform rendering tasks. This method must return\n * a lit-html TemplateResult. Setting properties inside this method will *not*\n * trigger the element to update.\n */\n\n\n render() {}\n\n}\n/**\n * Render method used to render the lit-html TemplateResult to the element's\n * DOM.\n * @param {TemplateResult} Template to render.\n * @param {Element|DocumentFragment} Node into which to render.\n * @param {String} Element name.\n */\n\nLitElement.render = render;","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { IronButtonState, IronButtonStateImpl } from '@polymer/iron-behaviors/iron-button-state.js';\nimport { IronControlState } from '@polymer/iron-behaviors/iron-control-state.js';\nimport { PaperRippleBehavior } from './paper-ripple-behavior.js';\n/** @polymerBehavior PaperButtonBehavior */\n\nexport const PaperButtonBehaviorImpl = {\n properties: {\n /**\n * The z-depth of this element, from 0-5. Setting to 0 will remove the\n * shadow, and each increasing number greater than 0 will be \"deeper\"\n * than the last.\n *\n * @attribute elevation\n * @type number\n * @default 1\n */\n elevation: {\n type: Number,\n reflectToAttribute: true,\n readOnly: true\n }\n },\n observers: ['_calculateElevation(focused, disabled, active, pressed, receivedFocusFromKeyboard)', '_computeKeyboardClass(receivedFocusFromKeyboard)'],\n hostAttributes: {\n role: 'button',\n tabindex: '0',\n animated: true\n },\n _calculateElevation: function _calculateElevation() {\n var e = 1;\n\n if (this.disabled) {\n e = 0;\n } else if (this.active || this.pressed) {\n e = 4;\n } else if (this.receivedFocusFromKeyboard) {\n e = 3;\n }\n\n this._setElevation(e);\n },\n _computeKeyboardClass: function _computeKeyboardClass(receivedFocusFromKeyboard) {\n this.toggleClass('keyboard-focus', receivedFocusFromKeyboard);\n },\n\n /**\n * In addition to `IronButtonState` behavior, when space key goes down,\n * create a ripple down effect.\n *\n * @param {!KeyboardEvent} event .\n */\n _spaceKeyDownHandler: function _spaceKeyDownHandler(event) {\n IronButtonStateImpl._spaceKeyDownHandler.call(this, event); // Ensure that there is at most one ripple when the space key is held down.\n\n\n if (this.hasRipple() && this.getRipple().ripples.length < 1) {\n this._ripple.uiDownAction();\n }\n },\n\n /**\n * In addition to `IronButtonState` behavior, when space key goes up,\n * create a ripple up effect.\n *\n * @param {!KeyboardEvent} event .\n */\n _spaceKeyUpHandler: function _spaceKeyUpHandler(event) {\n IronButtonStateImpl._spaceKeyUpHandler.call(this, event);\n\n if (this.hasRipple()) {\n this._ripple.uiUpAction();\n }\n }\n};\n/** @polymerBehavior */\n\nexport const PaperButtonBehavior = [IronButtonState, IronControlState, PaperRippleBehavior, PaperButtonBehaviorImpl];","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { IronCheckedElementBehavior, IronCheckedElementBehaviorImpl } from '@polymer/iron-checked-element-behavior/iron-checked-element-behavior.js';\nimport { PaperInkyFocusBehavior } from './paper-inky-focus-behavior.js';\nimport { PaperRippleBehavior } from './paper-ripple-behavior.js';\n/**\n * Use `PaperCheckedElementBehavior` to implement a custom element that has a\n * `checked` property similar to `IronCheckedElementBehavior` and is compatible\n * with having a ripple effect.\n * @polymerBehavior PaperCheckedElementBehavior\n */\n\nexport const PaperCheckedElementBehaviorImpl = {\n /**\n * Synchronizes the element's checked state with its ripple effect.\n */\n _checkedChanged: function _checkedChanged() {\n IronCheckedElementBehaviorImpl._checkedChanged.call(this);\n\n if (this.hasRipple()) {\n if (this.checked) {\n this._ripple.setAttribute('checked', '');\n } else {\n this._ripple.removeAttribute('checked');\n }\n }\n },\n\n /**\n * Synchronizes the element's `active` and `checked` state.\n */\n _buttonStateChanged: function _buttonStateChanged() {\n PaperRippleBehavior._buttonStateChanged.call(this);\n\n if (this.disabled) {\n return;\n }\n\n if (this.isAttached) {\n this.checked = this.active;\n }\n }\n};\n/** @polymerBehavior */\n\nexport const PaperCheckedElementBehavior = [PaperInkyFocusBehavior, IronCheckedElementBehavior, PaperCheckedElementBehaviorImpl];","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { IronButtonState } from '@polymer/iron-behaviors/iron-button-state.js';\nimport { IronControlState } from '@polymer/iron-behaviors/iron-control-state.js';\nimport { PaperRippleBehavior } from './paper-ripple-behavior.js';\n/**\n * `PaperInkyFocusBehavior` implements a ripple when the element has keyboard\n * focus.\n *\n * @polymerBehavior PaperInkyFocusBehavior\n */\n\nexport const PaperInkyFocusBehaviorImpl = {\n observers: ['_focusedChanged(receivedFocusFromKeyboard)'],\n _focusedChanged: function _focusedChanged(receivedFocusFromKeyboard) {\n if (receivedFocusFromKeyboard) {\n this.ensureRipple();\n }\n\n if (this.hasRipple()) {\n this._ripple.holdDown = receivedFocusFromKeyboard;\n }\n },\n _createRipple: function _createRipple() {\n var ripple = PaperRippleBehavior._createRipple();\n\n ripple.id = 'ink';\n ripple.setAttribute('center', '');\n ripple.classList.add('circle');\n return ripple;\n }\n};\n/** @polymerBehavior */\n\nexport const PaperInkyFocusBehavior = [IronButtonState, IronControlState, PaperRippleBehavior, PaperInkyFocusBehaviorImpl];","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport '@polymer/paper-ripple/paper-ripple.js';\nimport { IronButtonStateImpl } from '@polymer/iron-behaviors/iron-button-state.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\n/**\n * `PaperRippleBehavior` dynamically implements a ripple when the element has\n * focus via pointer or keyboard.\n *\n * NOTE: This behavior is intended to be used in conjunction with and after\n * `IronButtonState` and `IronControlState`.\n *\n * @polymerBehavior PaperRippleBehavior\n */\n\nexport const PaperRippleBehavior = {\n properties: {\n /**\n * If true, the element will not produce a ripple effect when interacted\n * with via the pointer.\n */\n noink: {\n type: Boolean,\n observer: '_noinkChanged'\n },\n\n /**\n * @type {Element|undefined}\n */\n _rippleContainer: {\n type: Object\n }\n },\n\n /**\n * Ensures a `` element is available when the element is\n * focused.\n */\n _buttonStateChanged: function _buttonStateChanged() {\n if (this.focused) {\n this.ensureRipple();\n }\n },\n\n /**\n * In addition to the functionality provided in `IronButtonState`, ensures\n * a ripple effect is created when the element is in a `pressed` state.\n */\n _downHandler: function _downHandler(event) {\n IronButtonStateImpl._downHandler.call(this, event);\n\n if (this.pressed) {\n this.ensureRipple(event);\n }\n },\n\n /**\n * Ensures this element contains a ripple effect. For startup efficiency\n * the ripple effect is dynamically on demand when needed.\n * @param {!Event=} optTriggeringEvent (optional) event that triggered the\n * ripple.\n */\n ensureRipple: function ensureRipple(optTriggeringEvent) {\n if (!this.hasRipple()) {\n this._ripple = this._createRipple();\n this._ripple.noink = this.noink;\n var rippleContainer = this._rippleContainer || this.root;\n\n if (rippleContainer) {\n dom(rippleContainer).appendChild(this._ripple);\n }\n\n if (optTriggeringEvent) {\n // Check if the event happened inside of the ripple container\n // Fall back to host instead of the root because distributed text\n // nodes are not valid event targets\n var domContainer = dom(this._rippleContainer || this);\n var target = dom(optTriggeringEvent).rootTarget;\n\n if (domContainer.deepContains(\n /** @type {Node} */\n target)) {\n this._ripple.uiDownAction(optTriggeringEvent);\n }\n }\n }\n },\n\n /**\n * Returns the `` element used by this element to create\n * ripple effects. The element's ripple is created on demand, when\n * necessary, and calling this method will force the\n * ripple to be created.\n */\n getRipple: function getRipple() {\n this.ensureRipple();\n return this._ripple;\n },\n\n /**\n * Returns true if this element currently contains a ripple effect.\n * @return {boolean}\n */\n hasRipple: function hasRipple() {\n return Boolean(this._ripple);\n },\n\n /**\n * Create the element's ripple effect via creating a ``.\n * Override this method to customize the ripple element.\n * @return {!PaperRippleElement} Returns a `` element.\n */\n _createRipple: function _createRipple() {\n var element =\n /** @type {!PaperRippleElement} */\n document.createElement('paper-ripple');\n return element;\n },\n _noinkChanged: function _noinkChanged(noink) {\n if (this.hasRipple()) {\n this._ripple.noink = noink;\n }\n }\n};","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport '@polymer/iron-flex-layout/iron-flex-layout.js';\nimport '@polymer/iron-icon/iron-icon.js';\nimport '@polymer/paper-styles/element-styles/paper-material-styles.js';\nimport '@polymer/paper-styles/color.js';\nimport '@polymer/paper-styles/default-theme.js';\nimport { PaperButtonBehavior } from '@polymer/paper-behaviors/paper-button-behavior.js';\nimport { Polymer } from '@polymer/polymer/lib/legacy/polymer-fn.js';\nimport { html } from '@polymer/polymer/lib/utils/html-tag.js';\nconst template = html`\n \n\n \n {{label}}\n`;\ntemplate.setAttribute('strip-whitespace', '');\n/**\nMaterial design: [Floating Action\nButton](https://www.google.com/design/spec/components/buttons-floating-action-button.html)\n\n`paper-fab` is a floating action button. It contains an image placed in the\ncenter and comes in two sizes: regular size and a smaller size by applying the\nattribute `mini`. When the user touches the button, a ripple effect emanates\nfrom the center of the button.\n\nYou may import `iron-icons` to use with this element, or provide a URL to a\ncustom icon. See `iron-iconset` for more information about how to use a custom\nicon set.\n\nExample:\n\n \n\n \n \n \n\n\n### Styling\n\nThe following custom properties and mixins are available for styling:\n\nCustom property | Description | Default\n----------------|-------------|----------\n`--paper-fab-background` | The background color of the button | `--accent-color`\n`--paper-fab-keyboard-focus-background` | The background color of the button when focused | `--paper-pink-900`\n`--paper-fab-disabled-background` | The background color of the button when it's disabled | `--paper-grey-300`\n`--paper-fab-disabled-text` | The text color of the button when it's disabled | `--paper-grey-500`\n`--paper-fab` | Mixin applied to the button | `{}`\n`--paper-fab-mini` | Mixin applied to a mini button | `{}`\n`--paper-fab-disabled` | Mixin applied to a disabled button | `{}`\n`--paper-fab-iron-icon` | Mixin applied to the iron-icon within the button | `{}`\n`--paper-fab-label` | Mixin applied to the label within the button | `{}`\n\n@group Paper Elements\n@demo demo/index.html\n*/\n\nPolymer({\n _template: template,\n is: 'paper-fab',\n behaviors: [PaperButtonBehavior],\n properties: {\n /**\n * The URL of an image for the icon. If the src property is specified,\n * the icon property should not be.\n */\n src: {\n type: String,\n value: ''\n },\n\n /**\n * Specifies the icon name or index in the set of icons available in\n * the icon's icon set. If the icon property is specified,\n * the src property should not be.\n */\n icon: {\n type: String,\n value: ''\n },\n\n /**\n * Set this to true to style this is a \"mini\" FAB.\n */\n mini: {\n type: Boolean,\n value: false,\n reflectToAttribute: true\n },\n\n /**\n * The label displayed in the badge. The label is centered, and ideally\n * should have very few characters.\n */\n label: {\n type: String,\n observer: '_labelChanged'\n }\n },\n _labelChanged: function _labelChanged() {\n this.setAttribute('aria-label', this.label);\n },\n _computeIsIconFab: function _computeIsIconFab(icon, src) {\n return icon.length > 0 || src.length > 0;\n }\n});","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\n/**\n * Use `Polymer.PaperInputAddonBehavior` to implement an add-on for\n * ``. A add-on appears below the input, and may display\n * information based on the input value and validity such as a character counter\n * or an error message.\n * @polymerBehavior\n */\n\nexport const PaperInputAddonBehavior = {\n attached: function attached() {\n this.fire('addon-attached');\n },\n\n /**\n * The function called by `` when the input value or\n * validity changes.\n * @param {{\n * invalid: boolean,\n * inputElement: (Element|undefined),\n * value: (string|undefined)\n * }} state -\n * inputElement: The input element.\n * value: The input value.\n * invalid: True if the input value is invalid.\n */\n update: function update(state) {}\n};","/**\n@license\nCopyright (c) 2015 The Polymer Project Authors. All rights reserved.\nThis code may only be used under the BSD style license found at\nhttp://polymer.github.io/LICENSE.txt The complete set of authors may be found at\nhttp://polymer.github.io/AUTHORS.txt The complete set of contributors may be\nfound at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as\npart of the polymer project is also subject to an additional IP rights grant\nfound at http://polymer.github.io/PATENTS.txt\n*/\nimport '@polymer/polymer/polymer-legacy.js';\nimport { IronA11yKeysBehavior } from '@polymer/iron-a11y-keys-behavior/iron-a11y-keys-behavior.js';\nimport { IronControlState } from '@polymer/iron-behaviors/iron-control-state.js';\nimport { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js';\nimport { PolymerElement } from '@polymer/polymer/polymer-element.js'; // Generate unique, monotonically increasing IDs for labels (needed by\n// aria-labelledby) and add-ons.\n\nexport const PaperInputHelper = {};\nPaperInputHelper.NextLabelID = 1;\nPaperInputHelper.NextAddonID = 1;\nPaperInputHelper.NextInputID = 1;\n/**\n * Use `PaperInputBehavior` to implement inputs with ``.\n * This behavior is implemented by ``. It exposes a number of\n * properties from `` and `` and\n * they should be bound in your template.\n *\n * The input element can be accessed by the `inputElement` property if you need\n * to access properties or methods that are not exposed.\n * @polymerBehavior PaperInputBehavior\n */\n\nexport const PaperInputBehaviorImpl = {\n properties: {\n /**\n * Fired when the input changes due to user interaction.\n *\n * @event change\n */\n\n /**\n * The label for this input. If you're using PaperInputBehavior to\n * implement your own paper-input-like element, bind this to\n * `