From 70fe9b63676e21439ba77d5ddbdbc5b243ba829f Mon Sep 17 00:00:00 2001 From: Salem Ghoweri Date: Tue, 16 Apr 2019 15:17:13 -0400 Subject: [PATCH] refactor: porting over virtually all of the remaining UIKit component refactor work that builds off of the updates from #960 and #973 --- .eslintrc.json | 2 +- packages/uikit-workshop/dist/index.html | 538 +--- .../dist/styleguide/css/pattern-lab.css | 2 +- .../images/pattern-lab-logo--on-dark.svg | 16 + .../images/pattern-lab-logo--on-light.svg | 12 + .../js/0-chunk-bfab2102075df63da231.js | 15 - .../js/1-chunk-861f2bf3817d7850085a.js | 15 - .../js/2-chunk-e309c72e0e8f5783df94.js | 15 - .../dist/styleguide/js/patternlab-pattern.js | 229 +- .../dist/styleguide/js/patternlab-viewer.js | 2440 +---------------- ...modal-viewer-chunk-28648a3aa047d1ce4010.js | 1 + ...modal-viewer-chunk-99a2492aaa20cb1957bf.js | 16 - .../pl-search-chunk-add12f33c938b18d410b.js | 1 + ...l-styleguide-chunk-85e03ab5a5e04e29c9b7.js | 16 - ...modal-viewer-chunk-b738f9e2bcc0982ef3cc.js | 1 + ...rs~pl-search-chunk-f25169a359311f4ca0b5.js | 1 + packages/uikit-workshop/package.json | 50 +- packages/uikit-workshop/src/html/index.html | 105 +- .../src/html/partials/controls.html | 87 - .../src/html/partials/header.html | 25 - .../src/html/partials/iframe-loader.html | 15 - .../src/html/partials/iframe.html | 20 - .../src/html/partials/modal.html | 20 - .../src/html/partials/pattern-nav.html | 59 - .../uikit-workshop/src/icons/arrow-down.svg | 5 + packages/uikit-workshop/src/icons/close.svg | 5 + packages/uikit-workshop/src/icons/desktop.svg | 5 + .../uikit-workshop/src/icons/disco-ball.svg | 15 + packages/uikit-workshop/src/icons/help.svg | 5 + packages/uikit-workshop/src/icons/hide.svg | 5 + packages/uikit-workshop/src/icons/laptop.svg | 5 + packages/uikit-workshop/src/icons/menu.svg | 5 + packages/uikit-workshop/src/icons/new-tab.svg | 5 + packages/uikit-workshop/src/icons/phone.svg | 5 + packages/uikit-workshop/src/icons/random.svg | 11 + .../uikit-workshop/src/icons/settings.svg | 5 + packages/uikit-workshop/src/icons/show.svg | 5 + packages/uikit-workshop/src/icons/tablet.svg | 5 + .../src/images/pattern-lab-logo--on-dark.svg | 16 + .../src/images/pattern-lab-logo--on-light.svg | 12 + .../uikit-workshop/src/sass/pattern-lab.scss | 43 +- .../src/sass/scss/01-abstracts/_mixins.scss | 31 +- .../sass/scss/01-abstracts/_variables.scss | 6 +- .../src/sass/scss/02-base/_body.scss | 20 + .../src/sass/scss/03-vendor/_prism.scss | 332 ++- .../src/sass/scss/04-components/_header.scss | 1 - .../scss/04-components/_pattern-info.scss | 106 +- .../src/sass/scss/04-components/_tabs.scss | 55 +- .../src/sass/scss/05-themes/_light-theme.scss | 9 +- .../sass/scss/05-themes/_sidebar-theme.scss | 66 +- .../uikit-workshop/src/scripts/actions/app.js | 83 + .../src/scripts/components/base-component.js | 73 +- .../scripts/components/modal-styleguide.js | 2 +- .../src/scripts/components/modal-viewer.js | 322 ++- .../src/scripts/components/panels-viewer.js | 68 +- .../src/scripts/components/panels.js | 102 +- .../components/pl-controls/pl-controls.js | 56 + .../components/pl-controls/pl-controls.scss | 62 + .../pl-copy-to-clipboard.js | 14 + .../scripts/components/pl-drawer/pl-drawer.js | 144 + .../components/pl-drawer/pl-drawer.scss} | 90 +- .../scripts/components/pl-header/pl-header.js | 74 + .../components/pl-header/pl-header.scss | 93 + .../scripts/components/pl-layout/pl-layout.js | 76 +- .../components/pl-layout/pl-layout.scss | 8 +- .../src/scripts/components/pl-logo/pl-logo.js | 44 + .../scripts/components/pl-logo/pl-logo.scss | 65 + .../src/scripts/components/pl-nav/pl-nav.js | 596 ++++ .../src/scripts/components/pl-nav/pl-nav.scss | 503 ++++ .../scripts/components/pl-search/pl-search.js | 69 +- .../components/pl-search/pl-search.scss | 45 +- .../pl-toggle-info/pl-toggle-info.js | 52 + .../pl-toggle-info/pl-toggle-info.scss | 16 + .../pl-toggle-layout/pl-toggle-layout.js | 12 +- .../pl-toggle-theme/pl-toggle-theme.js | 19 +- .../pl-toggle-theme/pl-toggle-theme.scss | 1 - .../components/pl-tools-menu/pl-tools-menu.js | 114 + .../pl-tools-menu/pl-tools-menu.scss | 163 ++ .../components/pl-tooltip/pl-tooltip.js | 38 + .../components/pl-tooltip/pl-tooltip.scss | 5 + .../pl-viewport-size-list.js | 289 ++ .../pl-viewport-size-list.scss | 50 + .../pl-viewport-size/pl-viewport-size.js | 28 + .../pl-viewport-size/pl-viewport-size.scss | 66 + .../components/pl-viewport/pl-viewport.js | 488 ++++ .../components/pl-viewport/pl-viewport.scss | 194 ++ .../src/scripts/components/styleguide.js | 689 ----- .../src/scripts/patternlab-pattern.js | 6 +- .../src/scripts/patternlab-viewer.js | 43 +- .../src/scripts/reducers/app.js | 53 +- .../src/scripts/utils/data-saver.js | 74 - .../src/scripts/utils/get-random.js | 4 + .../uikit-workshop/src/scripts/utils/index.js | 4 +- .../src/scripts/utils/pattern-name.js | 21 + .../src/scripts/utils/polyfills/index.js | 1 + .../polyfill-loader.js} | 9 +- .../utils/polyfills/polyfills-shared.js | 12 + .../src/scripts/utils/polyfills/polyfills.js | 8 + .../utils/polyfills/symbol-polyfill.js | 49 + .../src/scripts/utils/postmessage.js | 27 - .../src/scripts/utils/preact-compat.js | 61 + .../scripts/utils/share-inner-iframe-data.js | 37 + .../src/scripts/utils/url-handler.js | 36 +- .../src/scripts/utils/viewport-sizes.js | 28 + packages/uikit-workshop/webpack.config.js | 129 +- 105 files changed, 4888 insertions(+), 5011 deletions(-) create mode 100644 packages/uikit-workshop/dist/styleguide/images/pattern-lab-logo--on-dark.svg create mode 100644 packages/uikit-workshop/dist/styleguide/images/pattern-lab-logo--on-light.svg delete mode 100644 packages/uikit-workshop/dist/styleguide/js/0-chunk-bfab2102075df63da231.js delete mode 100644 packages/uikit-workshop/dist/styleguide/js/1-chunk-861f2bf3817d7850085a.js delete mode 100644 packages/uikit-workshop/dist/styleguide/js/2-chunk-e309c72e0e8f5783df94.js create mode 100644 packages/uikit-workshop/dist/styleguide/js/pl-modal-viewer-chunk-28648a3aa047d1ce4010.js delete mode 100644 packages/uikit-workshop/dist/styleguide/js/pl-modal-viewer-chunk-99a2492aaa20cb1957bf.js create mode 100644 packages/uikit-workshop/dist/styleguide/js/pl-search-chunk-add12f33c938b18d410b.js delete mode 100644 packages/uikit-workshop/dist/styleguide/js/pl-styleguide-chunk-85e03ab5a5e04e29c9b7.js create mode 100644 packages/uikit-workshop/dist/styleguide/js/vendors~pl-modal-viewer-chunk-b738f9e2bcc0982ef3cc.js create mode 100644 packages/uikit-workshop/dist/styleguide/js/vendors~pl-search-chunk-f25169a359311f4ca0b5.js mode change 100644 => 100755 packages/uikit-workshop/package.json delete mode 100644 packages/uikit-workshop/src/html/partials/controls.html delete mode 100644 packages/uikit-workshop/src/html/partials/header.html delete mode 100644 packages/uikit-workshop/src/html/partials/iframe-loader.html delete mode 100644 packages/uikit-workshop/src/html/partials/iframe.html delete mode 100644 packages/uikit-workshop/src/html/partials/modal.html delete mode 100644 packages/uikit-workshop/src/html/partials/pattern-nav.html create mode 100755 packages/uikit-workshop/src/icons/arrow-down.svg create mode 100755 packages/uikit-workshop/src/icons/close.svg create mode 100755 packages/uikit-workshop/src/icons/desktop.svg create mode 100755 packages/uikit-workshop/src/icons/disco-ball.svg create mode 100755 packages/uikit-workshop/src/icons/help.svg create mode 100755 packages/uikit-workshop/src/icons/hide.svg create mode 100755 packages/uikit-workshop/src/icons/laptop.svg create mode 100755 packages/uikit-workshop/src/icons/menu.svg create mode 100755 packages/uikit-workshop/src/icons/new-tab.svg create mode 100755 packages/uikit-workshop/src/icons/phone.svg create mode 100755 packages/uikit-workshop/src/icons/random.svg create mode 100755 packages/uikit-workshop/src/icons/settings.svg create mode 100755 packages/uikit-workshop/src/icons/show.svg create mode 100755 packages/uikit-workshop/src/icons/tablet.svg create mode 100644 packages/uikit-workshop/src/images/pattern-lab-logo--on-dark.svg create mode 100644 packages/uikit-workshop/src/images/pattern-lab-logo--on-light.svg mode change 100644 => 100755 packages/uikit-workshop/src/scripts/actions/app.js mode change 100644 => 100755 packages/uikit-workshop/src/scripts/components/base-component.js mode change 100644 => 100755 packages/uikit-workshop/src/scripts/components/modal-styleguide.js mode change 100644 => 100755 packages/uikit-workshop/src/scripts/components/panels-viewer.js create mode 100755 packages/uikit-workshop/src/scripts/components/pl-controls/pl-controls.js create mode 100755 packages/uikit-workshop/src/scripts/components/pl-controls/pl-controls.scss create mode 100755 packages/uikit-workshop/src/scripts/components/pl-copy-to-clipboard/pl-copy-to-clipboard.js create mode 100755 packages/uikit-workshop/src/scripts/components/pl-drawer/pl-drawer.js rename packages/uikit-workshop/src/{sass/scss/04-components/_modal.scss => scripts/components/pl-drawer/pl-drawer.scss} (70%) mode change 100644 => 100755 create mode 100755 packages/uikit-workshop/src/scripts/components/pl-header/pl-header.js create mode 100755 packages/uikit-workshop/src/scripts/components/pl-header/pl-header.scss mode change 100644 => 100755 packages/uikit-workshop/src/scripts/components/pl-layout/pl-layout.js mode change 100644 => 100755 packages/uikit-workshop/src/scripts/components/pl-layout/pl-layout.scss create mode 100755 packages/uikit-workshop/src/scripts/components/pl-logo/pl-logo.js create mode 100755 packages/uikit-workshop/src/scripts/components/pl-logo/pl-logo.scss create mode 100755 packages/uikit-workshop/src/scripts/components/pl-nav/pl-nav.js create mode 100755 packages/uikit-workshop/src/scripts/components/pl-nav/pl-nav.scss mode change 100644 => 100755 packages/uikit-workshop/src/scripts/components/pl-search/pl-search.js mode change 100644 => 100755 packages/uikit-workshop/src/scripts/components/pl-search/pl-search.scss create mode 100755 packages/uikit-workshop/src/scripts/components/pl-toggle-info/pl-toggle-info.js create mode 100644 packages/uikit-workshop/src/scripts/components/pl-toggle-info/pl-toggle-info.scss mode change 100644 => 100755 packages/uikit-workshop/src/scripts/components/pl-toggle-layout/pl-toggle-layout.js mode change 100644 => 100755 packages/uikit-workshop/src/scripts/components/pl-toggle-theme/pl-toggle-theme.js create mode 100755 packages/uikit-workshop/src/scripts/components/pl-tools-menu/pl-tools-menu.js create mode 100755 packages/uikit-workshop/src/scripts/components/pl-tools-menu/pl-tools-menu.scss create mode 100755 packages/uikit-workshop/src/scripts/components/pl-tooltip/pl-tooltip.js create mode 100755 packages/uikit-workshop/src/scripts/components/pl-tooltip/pl-tooltip.scss create mode 100755 packages/uikit-workshop/src/scripts/components/pl-viewport-size-list/pl-viewport-size-list.js create mode 100755 packages/uikit-workshop/src/scripts/components/pl-viewport-size-list/pl-viewport-size-list.scss create mode 100755 packages/uikit-workshop/src/scripts/components/pl-viewport-size/pl-viewport-size.js create mode 100755 packages/uikit-workshop/src/scripts/components/pl-viewport-size/pl-viewport-size.scss create mode 100755 packages/uikit-workshop/src/scripts/components/pl-viewport/pl-viewport.js create mode 100755 packages/uikit-workshop/src/scripts/components/pl-viewport/pl-viewport.scss delete mode 100644 packages/uikit-workshop/src/scripts/components/styleguide.js mode change 100644 => 100755 packages/uikit-workshop/src/scripts/reducers/app.js delete mode 100644 packages/uikit-workshop/src/scripts/utils/data-saver.js create mode 100644 packages/uikit-workshop/src/scripts/utils/get-random.js create mode 100755 packages/uikit-workshop/src/scripts/utils/pattern-name.js create mode 100644 packages/uikit-workshop/src/scripts/utils/polyfills/index.js rename packages/uikit-workshop/src/scripts/utils/{polyfills.js => polyfills/polyfill-loader.js} (89%) create mode 100644 packages/uikit-workshop/src/scripts/utils/polyfills/polyfills-shared.js create mode 100644 packages/uikit-workshop/src/scripts/utils/polyfills/polyfills.js create mode 100644 packages/uikit-workshop/src/scripts/utils/polyfills/symbol-polyfill.js create mode 100755 packages/uikit-workshop/src/scripts/utils/preact-compat.js create mode 100644 packages/uikit-workshop/src/scripts/utils/share-inner-iframe-data.js create mode 100644 packages/uikit-workshop/src/scripts/utils/viewport-sizes.js mode change 100644 => 100755 packages/uikit-workshop/webpack.config.js diff --git a/.eslintrc.json b/.eslintrc.json index d5dd0f115..777cc3c69 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,7 +5,7 @@ "es6": true }, "parserOptions": { - "ecmaVersion": 6, + "ecmaVersion": 2017, "sourceType": "module" }, "globals": {}, diff --git a/packages/uikit-workshop/dist/index.html b/packages/uikit-workshop/dist/index.html index 908d91800..accafe15b 100644 --- a/packages/uikit-workshop/dist/index.html +++ b/packages/uikit-workshop/dist/index.html @@ -1,411 +1,129 @@ - - - - - Pattern Lab - - - - - - - - - - - - - - -
-
- -
- -
- - - -
- -
- -
- - -
- - -
- -
-
-
-
-
- - - - -
-
-
-
-
-
- -
-
- - - - - - - - - - - + +
+ +
+
+
- - - - - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/packages/uikit-workshop/dist/styleguide/css/pattern-lab.css b/packages/uikit-workshop/dist/styleguide/css/pattern-lab.css index cf3e50682..a1be81c1b 100644 --- a/packages/uikit-workshop/dist/styleguide/css/pattern-lab.css +++ b/packages/uikit-workshop/dist/styleguide/css/pattern-lab.css @@ -1 +1 @@ -.pl-c-body *{-webkit-box-sizing:border-box;box-sizing:border-box}button{font-size:inherit;background-color:transparent}.pl-c-html{min-height:100%}.pl-c-body{margin:0;padding:0;-webkit-text-size-adjust:100%;display:-webkit-box;display:-ms-flexbox;display:flex}code[class*=language-],pre[class*=language-]{color:#000;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono',monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background-color:#b3d4fc}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background-color:#f5f2f0}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#708090}.token.punctuation{color:#999}.namespace{opacity:.7}.token.boolean,.token.constant,.token.deleted,.token.number,.token.property,.token.symbol,.token.tag{color:#905}.token.attr-name,.token.builtin,.token.char,.token.inserted,.token.selector,.token.string{color:#690}.language-css .token.string,.style .token.string,.token.entity,.token.operator,.token.url{color:#a67f59;background-color:rgba(255,255,255,.5)}.token.atrule,.token.attr-value,.token.keyword{color:#07a}.token.function{color:#dd4a68}.token.important,.token.regex,.token.variable{color:#e90}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}pre.line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}pre.line-numbers>code{position:relative}.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:0;font-size:100%;left:-3.8em;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.line-numbers-rows>span{pointer-events:none;display:block;counter-increment:linenumber}.line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}.token a{color:inherit}pl-search{background-color:inherit;-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2;top:0;z-index:10;-ms-flex-negative:0;flex-shrink:0;padding:.3rem .5rem;display:inline-block}@media screen and (min-width:42em){pl-search{margin-left:1rem;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-negative:1;flex-shrink:1}.pl-c-body--theme-sidebar pl-search{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin-left:0;padding-left:0;padding-right:0;width:100%}}.pl-c-typeahead{width:100%;background-color:inherit;-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2;display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;z-index:10;text-transform:capitalize;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;color:#fafafa;position:relative}.pl-c-body--theme-light .pl-c-typeahead{color:#222}@media screen and (min-width:42em){.pl-c-typeahead{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.pl-c-body--theme-sidebar .pl-c-typeahead{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}.pl-c-typeahead__hint{top:0;left:0;right:0;width:100%}.pl-c-typeahead__hint,.pl-c-typeahead__input{text-transform:capitalize;background-color:#222;color:#fff;border-color:#090909;text-overflow:ellipsis;border-width:1px;border-style:solid;-webkit-transition:all .1s ease;transition:all .1s ease;max-width:100%;padding:.31rem .5rem;font-size:16px;width:100%;outline-offset:-3px;outline-width:2px;-webkit-appearance:none}@media all and (min-width:900px){.pl-c-typeahead__hint,.pl-c-typeahead__input{font-size:inherit}}.pl-c-typeahead__hint::-ms-clear,.pl-c-typeahead__input::-ms-clear{display:none}.pl-c-body--theme-sidebar .pl-c-typeahead__hint,.pl-c-body--theme-sidebar .pl-c-typeahead__input{border-radius:0}.pl-c-typeahead__input-wrapper--with-clear-button .pl-c-typeahead__hint,.pl-c-typeahead__input-wrapper--with-clear-button .pl-c-typeahead__input{padding-right:1.7rem}@media all and (min-width:42em){.pl-c-typeahead__input-wrapper--with-clear-button .pl-c-typeahead__hint,.pl-c-typeahead__input-wrapper--with-clear-button .pl-c-typeahead__input{padding-right:1.4rem}}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-typeahead__hint,.pl-c-body--theme-sidebar .pl-c-typeahead__input{max-width:none}}.pl-c-body--theme-light .pl-c-typeahead__hint,.pl-c-body--theme-light .pl-c-typeahead__input{background-color:#eee;color:#4d4c4c!important;border-color:#ddd!important}.pl-c-typeahead__hint::-moz-input-placeholder,.pl-c-typeahead__hint::-webkit-input-placeholder,.pl-c-typeahead__input::-moz-input-placeholder,.pl-c-typeahead__input::-webkit-input-placeholder{color:#fff!important;-webkit-transition:all .1s ease;transition:all .1s ease}.pl-c-typeahead__hint:focus,.pl-c-typeahead__hint:hover,.pl-c-typeahead__input:focus,.pl-c-typeahead__input:hover{color:#fff;background-color:#1d1d1d!important}.pl-c-body--theme-light .pl-c-typeahead__hint:focus,.pl-c-body--theme-light .pl-c-typeahead__hint:hover,.pl-c-body--theme-light .pl-c-typeahead__input:focus,.pl-c-body--theme-light .pl-c-typeahead__input:hover{color:#222!important;background-color:#ddd!important;border-color:#ccc!important}.pl-c-typeahead__hint:focus::-moz-input-placeholder,.pl-c-typeahead__hint:focus::-webkit-input-placeholder,.pl-c-typeahead__hint:hover::-moz-input-placeholder,.pl-c-typeahead__hint:hover::-webkit-input-placeholder,.pl-c-typeahead__input:focus::-moz-input-placeholder,.pl-c-typeahead__input:focus::-webkit-input-placeholder,.pl-c-typeahead__input:hover::-moz-input-placeholder,.pl-c-typeahead__input:hover::-webkit-input-placeholder{color:#fff!important}.pl-c-body--theme-light .pl-c-typeahead__hint:focus::-moz-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__hint:focus::-webkit-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__hint:hover::-moz-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__hint:hover::-webkit-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__input:focus::-moz-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__input:focus::-webkit-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__input:hover::-moz-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__input:hover::-webkit-input-placeholder{color:#222!important}.pl-c-typeahead__menu{overflow:hidden;max-height:0;-webkit-transition:max-height .1s ease-out;transition:max-height .1s ease-out;background-color:#222;text-transform:capitalize;position:absolute;min-width:100%;width:100%;overflow:hidden;top:100%;right:0;max-height:0;display:block!important;-webkit-transition:max-height .3s ease,opacity .3s ease;transition:max-height .3s ease,opacity .3s ease;opacity:0}.pl-c-typeahead__menu.pl-is-active{max-height:calc(100vh - 2rem - 1rem);max-height:calc(var(--pl-viewport-height,calc(100vh - 2rem)) - 1rem);overflow:auto;-webkit-overflow-scrolling:touch}@media all and (min-width:42em){.pl-c-typeahead__menu{border-bottom-right-radius:6px;border-bottom-left-radius:6px}}.pl-c-body--theme-light .pl-c-typeahead__menu{background-color:#fafafa}.pl-c-typeahead__menu.pl-is-open{max-height:120rem;max-height:calc(var(--viewport-height) - 4rem);opacity:1}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-typeahead__menu{position:relative!important;border-radius:0}}@media all and (max-width:41em){.pl-c-typeahead__menu{position:relative!important}}.pl-c-typeahead__results{list-style:none;margin:0;padding:0;background-color:inherit;border-color:transparent;border-width:1px;border-style:solid;overflow:hidden;border-color:#151515}@media all and (min-width:42em){.pl-c-typeahead__results{border-bottom-right-radius:6px;border-bottom-left-radius:6px}}.pl-c-typeahead__results:empty{border-width:0;max-height:0}.pl-c-body--theme-light .pl-c-typeahead__results{border-color:#ccc}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-typeahead__results{border-radius:0}}.pl-c-typeahead__result{-webkit-transition:all .3s ease;transition:all .3s ease;background-color:inherit;padding:.8em;cursor:pointer;overflow:hidden}.pl-c-typeahead__result:last-child{border-bottom-right-radius:6px;border-bottom-left-radius:6px}.pl-c-body--theme-sidebar .pl-c-typeahead__result:last-child{border-radius:0}.pl-c-typeahead__result:hover{background-color:rgba(255,255,255,.15)}.pl-c-body--theme-light .pl-c-typeahead__result:hover{background-color:#eee}.pl-c-typeahead__result:active,.pl-c-typeahead__result:focus{background-color:rgba(255,255,255,.18)}.pl-c-body--theme-light .pl-c-typeahead__result:active,.pl-c-body--theme-light .pl-c-typeahead__result:focus{background-color:#ddd}.pl-c-typeahead__result.pl-has-cursor{color:#fff;background-color:rgba(255,255,255,.25)}.pl-c-body--theme-light .pl-c-typeahead__result.pl-has-cursor{color:#000;background-color:#ddd}.pl-c-typeahead__input-wrapper{position:relative}.pl-c-typeahead__clear-button{background-color:#000;color:grey;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline-offset:-3px;outline-width:2px;height:1.7rem;width:1.7rem;background-color:transparent;border-radius:20rem;overflow:hidden;position:absolute;right:0;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);z-index:100;cursor:pointer;border:0;-webkit-transition:opacity .1s ease;transition:opacity .1s ease;opacity:0;visibility:hidden}.pl-c-typeahead__clear-button:hover{color:#fff;background-color:#222}.pl-c-typeahead__clear-button.pl-is-active,.pl-c-typeahead__clear-button:active{color:#fff;background-color:#222;outline:1px dotted grey;outline-offset:-1px}.pl-c-body--theme-light .pl-c-typeahead__clear-button{background-color:#fff;color:#4d4c4c}.pl-c-body--theme-light .pl-c-typeahead__clear-button:hover{background-color:#eee}.pl-c-body--theme-light .pl-c-typeahead__clear-button:active,.pl-c-body--theme-light .pl-c-typeahead__clear-button:focus{background-color:#ddd}.pl-c-body--theme-density-cozy .pl-c-typeahead__clear-button{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-typeahead__clear-button{font-size:.85rem;padding:1.5rem 1rem}.pl-c-typeahead__clear-button:active,.pl-c-typeahead__clear-button:hover{background-color:transparent}@media all and (min-width:42em){.pl-c-typeahead__clear-button{height:1.4rem;width:1.4rem}}.pl-c-body--theme-light .pl-c-typeahead__clear-button{background-color:transparent}.pl-c-body--theme-light .pl-c-typeahead__clear-button:active,.pl-c-body--theme-light .pl-c-typeahead__clear-button:hover{background-color:transparent}.pl-c-typeahead__clear-button.pl-is-visible{opacity:1;visibility:visible}.pl-c-typeahead__clear-button-icon{fill:currentColor;line-height:0;font-size:0;position:absolute;top:50%;left:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}pl-layout{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%;min-height:100vh;max-width:100vw;background-color:#ddd}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){pl-layout{overflow:hidden}}@media all and (min-width:42em){pl-layout.pl-c-body--theme-sidebar{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}}pl-layout.pl-c-body--theme-light{background-color:#fff}.pl-c-header{position:fixed;position:-webkit-sticky;position:sticky;top:0;left:0;z-index:4;display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;background-color:#000;color:grey;font-family:HelveticaNeue,Helvetica,Arial,sans-serif;font-size:.7rem;min-height:30px}@supports (padding:0px){.pl-c-header{padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right)}}.pl-c-header__nav-toggle{background-color:#000;color:grey;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline-offset:-3px;outline-width:2px;border:0}.pl-c-header__nav-toggle:hover{color:#fff;background-color:#222}.pl-c-header__nav-toggle.pl-is-active,.pl-c-header__nav-toggle:active{color:#fff;background-color:#222;outline:1px dotted grey;outline-offset:-1px}.pl-c-body--theme-light .pl-c-header__nav-toggle{background-color:#fff;color:#4d4c4c}.pl-c-body--theme-light .pl-c-header__nav-toggle:hover{background-color:#eee}.pl-c-body--theme-light .pl-c-header__nav-toggle:active,.pl-c-body--theme-light .pl-c-header__nav-toggle:focus{background-color:#ddd}.pl-c-body--theme-density-cozy .pl-c-header__nav-toggle{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-header__nav-toggle{font-size:.85rem;padding:1.5rem 1rem}@media all and (min-width:42em){.pl-c-header__nav-toggle{display:none}}.pl-c-logo{max-width:2rem;margin:0 1rem;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.pl-c-logo:focus{outline:1px dotted grey;outline-offset:-1px}.pl-c-logo__img{display:block;max-width:100%;height:auto}.pl-c-nav{overflow:hidden;max-height:0;-webkit-transition:max-height .1s ease-out;transition:max-height .1s ease-out;background-color:inherit;position:absolute;left:0;top:100%;width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;transition:max-height .1s ease-out}.pl-c-nav.pl-is-active{max-height:calc(100vh - 2rem - 1rem);max-height:calc(var(--pl-viewport-height,calc(100vh - 2rem)) - 1rem);overflow:auto;-webkit-overflow-scrolling:touch}@media all and (min-width:42em){.pl-c-nav{overflow:visible;max-height:none}}.pl-c-nav.pl-is-active{-webkit-box-shadow:0 1px 1px #000;box-shadow:0 1px 1px #000}.pl-c-body--theme-light .pl-c-nav.pl-is-active{-webkit-box-shadow:0 1px 1px #a6a6a6;box-shadow:0 1px 1px #a6a6a6}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-nav.pl-is-active{-webkit-box-shadow:none;box-shadow:none}}@media all and (min-width:42em){.pl-c-nav.pl-is-active{overflow:visible;max-height:none}}@media all and (min-width:42em){.pl-c-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;position:relative;top:auto;width:auto;-webkit-box-shadow:none;box-shadow:none}}.pl-c-nav__list{z-index:1;margin:0;padding:0;list-style:none;-ms-flex-negative:0;flex-shrink:0;-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2;background-color:inherit}@media all and (min-width:42em){.pl-c-nav__list{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.pl-c-body--theme-sidebar .pl-c-nav__list{display:block}}.pl-c-nav__item{background-color:inherit;-webkit-transform:translateZ(0);transform:translateZ(0);cursor:pointer;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.pl-c-body--theme-sidebar .pl-c-nav__item{display:block}@media all and (min-width:42em){.pl-c-nav__sublist>.pl-c-nav__item:last-child{overflow:hidden;border-bottom-left-radius:6px;border-bottom-right-radius:6px}}.pl-c-nav__link{background-color:#000;color:grey;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline-offset:-3px;outline-width:2px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0}.pl-c-nav__link:hover{color:#fff;background-color:#222}.pl-c-nav__link.pl-is-active,.pl-c-nav__link:active{color:#fff;background-color:#222;outline:1px dotted grey;outline-offset:-1px}.pl-c-body--theme-light .pl-c-nav__link{background-color:#fff;color:#4d4c4c}.pl-c-body--theme-light .pl-c-nav__link:hover{background-color:#eee}.pl-c-body--theme-light .pl-c-nav__link:active,.pl-c-body--theme-light .pl-c-nav__link:focus{background-color:#ddd}.pl-c-body--theme-density-cozy .pl-c-nav__link{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-nav__link{font-size:.85rem;padding:1.5rem 1rem}.pl-c-body--theme-sidebar .pl-c-nav__link{width:100%}.pl-c-nav__link--sublink{text-transform:none;padding-left:.5rem}.pl-c-nav__link--dropdown{-webkit-appearance:none;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.pl-c-nav__link--dropdown:after{content:'\25BC';color:rgba(255,255,255,.25);display:inline-block;font-size:7px;position:relative;top:1px;right:-2px;-webkit-transition:all .1s ease-out;transition:all .1s ease-out}.pl-c-nav__link--dropdown:focus:after,.pl-c-nav__link--dropdown:hover:after{color:grey}.pl-c-nav__link--dropdown.pl-is-active{color:#fff;background-color:#222}.pl-c-nav__link--dropdown.pl-is-active:after{color:grey;-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.pl-c-nav__sublist{background-color:inherit;list-style:none;margin:0;padding:0}@media all and (min-width:42em){.pl-c-nav__sublist{position:absolute;top:100%;left:0;min-width:10rem;border-bottom-left-radius:6px;border-bottom-right-radius:6px}}.pl-c-nav__sublist--dropdown,.pl-c-nav__subsublist--dropdown{list-style:none;margin:0;padding:0;overflow:hidden;max-height:0;-webkit-transition:max-height .1s ease-out;transition:max-height .1s ease-out;visibility:hidden}.pl-c-nav__sublist--dropdown.pl-is-active,.pl-c-nav__subsublist--dropdown.pl-is-active{max-height:calc(100vh - 2rem - 1rem);max-height:calc(var(--pl-viewport-height,calc(100vh - 2rem)) - 1rem);overflow:auto;-webkit-overflow-scrolling:touch}.pl-c-nav__sublist--dropdown.pl-is-active,.pl-c-nav__subsublist--dropdown.pl-is-active{margin-left:.5rem;visibility:visible;max-height:none}@media all and (min-width:42em){.pl-c-nav__sublist--dropdown.pl-is-active,.pl-c-nav__subsublist--dropdown.pl-is-active{height:auto;max-height:calc(100vh - 2rem - 1rem)}}.pl-c-body--theme-sidebar .pl-c-nav__sublist--dropdown.pl-is-active,.pl-c-body--theme-sidebar .pl-c-nav__subsublist--dropdown.pl-is-active{max-height:none}@media all and (min-width:42em){.pl-c-nav__sublist--dropdown.pl-is-active{margin-left:0;border-width:1px;border-style:solid;border-color:#000}.pl-c-body--theme-light .pl-c-nav__sublist--dropdown.pl-is-active{border-color:#ccc}}.pl-c-nav__subsublist{list-style:none;margin:0;padding:0}.pl-c-viewport-size{margin:0;border:0;padding:.3rem .5rem .4rem;line-height:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.pl-c-viewport-size__input{padding:.1rem;margin:0;border:0;border-radius:3px;background-color:transparent;font-size:inherit;color:grey;width:35px;text-align:right;-webkit-transition:all .1s ease-out;transition:all .1s ease-out}.pl-c-viewport-size__input::-moz-focus-inner{padding:0;border:0}.pl-c-viewport-size__input:hover{color:#fff;background-color:#222}.pl-c-viewport-size__input:active,.pl-c-viewport-size__input:focus{color:#fff;background-color:#222;outline:1px dotted grey;outline-offset:-1px}.pl-c-viewport-size__label{display:block;margin:0;padding:0}.pl-c-size-list{display:none;list-style:none;margin:0;padding:0;overflow-x:auto;padding:0 .25rem}@media all and (min-width:42em){.pl-c-size-list{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-overflow-scrolling:touch}}@media all and (min-width:53em){.pl-c-size-list{display:block;display:-webkit-box;display:-ms-flexbox;display:flex}}.pl-c-size-list__action{background-color:#000;color:grey;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline-offset:-3px;outline-width:2px}.pl-c-size-list__action:hover{color:#fff;background-color:#222}.pl-c-size-list__action.pl-is-active,.pl-c-size-list__action:active{color:#fff;background-color:#222;outline:1px dotted grey;outline-offset:-1px}.pl-c-body--theme-light .pl-c-size-list__action{background-color:#fff;color:#4d4c4c}.pl-c-body--theme-light .pl-c-size-list__action:hover{background-color:#eee}.pl-c-body--theme-light .pl-c-size-list__action:active,.pl-c-body--theme-light .pl-c-size-list__action:focus{background-color:#ddd}.pl-c-body--theme-density-cozy .pl-c-size-list__action{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-size-list__action{font-size:.85rem;padding:1.5rem 1rem}.pl-c-size-list__item:first-child{margin-left:auto}.pl-c-size-list__item:last-child{margin-right:auto}.pl-c-controls{margin-left:auto;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-controls{display:block}}.pl-c-controls__list{list-style:none;margin:0;padding:0;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.pl-c-tools{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex}.pl-c-tools__toggle{background-color:#000;color:grey;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline-offset:-3px;outline-width:2px;margin:0;padding-top:.6rem;padding-bottom:.5rem;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;position:relative;min-width:30px}.pl-c-tools__toggle:hover{color:#fff;background-color:#222}.pl-c-tools__toggle.pl-is-active,.pl-c-tools__toggle:active{color:#fff;background-color:#222;outline:1px dotted grey;outline-offset:-1px}.pl-c-body--theme-light .pl-c-tools__toggle{background-color:#fff;color:#4d4c4c}.pl-c-body--theme-light .pl-c-tools__toggle:hover{background-color:#eee}.pl-c-body--theme-light .pl-c-tools__toggle:active,.pl-c-body--theme-light .pl-c-tools__toggle:focus{background-color:#ddd}.pl-c-body--theme-density-cozy .pl-c-tools__toggle{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-tools__toggle{font-size:.85rem;padding:1.5rem 1rem}.pl-c-tools__toggle-icon{-webkit-transition:inherit;transition:inherit}.pl-c-tools__list{list-style:none;margin:0;padding:0;overflow:hidden;max-height:0;-webkit-transition:max-height .1s ease-out;transition:max-height .1s ease-out;position:absolute;top:100%;right:0;z-index:10;width:10rem;border-bottom-left-radius:6px;border-bottom-right-radius:6px}.pl-c-tools__list.pl-is-active{max-height:calc(100vh - 2rem - 1rem);max-height:calc(var(--pl-viewport-height,calc(100vh - 2rem)) - 1rem);overflow:auto;-webkit-overflow-scrolling:touch}.pl-c-tools__action{background-color:#000;color:grey;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline-offset:-3px;outline-width:2px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;margin:0}.pl-c-tools__action:hover{color:#fff;background-color:#222}.pl-c-tools__action.pl-is-active,.pl-c-tools__action:active{color:#fff;background-color:#222;outline:1px dotted grey;outline-offset:-1px}.pl-c-body--theme-light .pl-c-tools__action{background-color:#fff;color:#4d4c4c}.pl-c-body--theme-light .pl-c-tools__action:hover{background-color:#eee}.pl-c-body--theme-light .pl-c-tools__action:active,.pl-c-body--theme-light .pl-c-tools__action:focus{background-color:#ddd}.pl-c-body--theme-density-cozy .pl-c-tools__action{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-tools__action{font-size:.85rem;padding:1.5rem 1rem}.pl-c-tools__action-icon{margin-left:auto}.pl-c-viewport{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%;position:relative;top:2rem;bottom:0;left:0;right:0;z-index:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-transition:height .3s ease;transition:height .3s ease}@supports ((position: -webkit-sticky) or (position: sticky)){.pl-c-viewport{top:0}}.pl-c-body--theme-sidebar .pl-c-viewport{top:0}.pl-c-viewport__cover{width:100%;height:100%;display:none;position:fixed;top:0;left:0;z-index:200;cursor:move;pointer-events:auto}.pl-c-viewport__iframe-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-width:100vw;width:100%;position:relative;margin:0 auto;-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-overflow-scrolling:touch;width:100%}.pl-c-viewport__iframe-wrapper.hay-mode{-webkit-transition:all 40s linear;transition:all 40s linear}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-viewport__iframe-wrapper{max-width:calc(100vw - 14rem)}}.pl-c-viewport__iframe{min-height:calc(100vh - 35.5px);-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;width:100%;border:0;padding:0;margin:0;top:0;bottom:0;left:0;right:0;background-color:#fff;max-width:100vw}.pl-c-viewport__iframe.is-ready{min-height:0}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-viewport__iframe{max-width:calc(100vw - 14rem)}}.pl-c-viewport__iframe.hay-mode{-webkit-transition:all 40s linear;transition:all 40s linear}.pl-c-viewport__resizer{position:absolute;right:0;top:0;bottom:0;width:14px;margin:0;height:100%;cursor:ew-resize}.pl-c-viewport__resizer-handle{margin:0;width:100%;height:100%;background-color:#ccc;-webkit-transition:background-color .1s ease-out;transition:background-color .1s ease-out}.pl-c-viewport__resizer-handle:hover{background-color:grey}.pl-c-viewport__resizer-handle:active{cursor:move;background-color:#4d4c4c}.vp-animate{-webkit-transition:width .8s ease-out;transition:width .8s ease-out}.pl-c-viewport-modal-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-width:100vw;position:relative}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-viewport-modal-wrapper{max-width:calc(100vw - 14rem)}}@media all and (min-width:42em) and (-ms-high-contrast:none),all and (min-width:42em) and (-ms-high-contrast:active){.pl-c-body--theme-sidebar .pl-c-viewport-modal-wrapper{margin-left:14rem}}.pl-c-pattern{margin-bottom:2rem;position:relative;clear:both}.pl-c-pattern__header{position:relative;padding:.5rem 0 0;line-height:1.3;font-size:90%;color:grey}.pl-c-pattern__header:empty{padding:0}.pl-c-pattern__title{font-family:HelveticaNeue,Helvetica,Arial,sans-serif!important;font-size:.85rem!important;line-height:1!important;font-weight:400!important;margin:0!important;padding:0!important;text-transform:capitalize!important}.pl-c-pattern__title-link{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;padding:1rem 0 .3rem;color:grey!important;text-decoration:none;cursor:pointer}.pl-c-pattern__title-link:focus,.pl-c-pattern__title-link:hover{color:#000!important}.pl-c-pattern__extra-toggle{font-size:9px;position:absolute;bottom:-1px;right:0;z-index:1;padding:.65em .65em .5em;line-height:1;color:grey;background-color:transparent;font-weight:400;border:1px solid #ddd;border-top-left-radius:6px;border-top-right-radius:6px;-webkit-transition:background-color .1s ease-out;transition:background-color .1s ease-out}.pl-c-pattern__extra-toggle .pl-c-pattern__toggle-icon{display:inline-block}.pl-c-pattern__extra-toggle.pl-is-active,.pl-c-pattern__extra-toggle:focus,.pl-c-pattern__extra-toggle:hover{background-color:#fafafa;color:#000}.pl-c-pattern__extra-toggle:focus{outline:1px dotted #4d4c4c}.pl-c-pattern__extra-toggle.pl-is-active{border-bottom-color:#fafafa}.pl-c-pattern__extra-toggle.pl-is-active .pl-c-pattern__toggle-icon{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.pl-c-pattern__extra{background-color:#fafafa;border-top:1px solid #ddd;margin-bottom:1rem;overflow:hidden;max-height:1px;position:relative;-webkit-transition:all .1s ease-out;transition:all .1s ease-out}.pl-c-pattern__extra.pl-is-active{border:1px solid #ddd;border-radius:6px;border-top-right-radius:0;max-height:150rem}.pl-c-category{margin-top:6rem;font:HelveticaNeue,Helvetica,Arial,sans-serif!important}.pl-c-category:first-of-type{margin-top:2rem}.pl-c-category__title{font-size:1.4rem!important;color:#222!important;margin:0 0 .2rem;text-transform:capitalize}.pl-c-category__title-link{-webkit-transition:color .1s ease-out;transition:color .1s ease-out}.pl-c-category__description{font-size:.85rem;line-height:1.5;max-width:30rem}.pl-c-category__description:empty{display:none}.pl-c-pattern-info{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-flow:row wrap;flex-flow:row wrap;width:100%;overflow:auto;-webkit-overflow-scrolling:touch}.pl-c-pattern .pl-c-pattern-info{max-height:20rem;min-height:18rem;overflow:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-overflow-scrolling:touch}.pl-c-pattern .pl-c-pattern-info::-webkit-scrollbar{width:0!important}@media all and (min-width:53em){.pl-c-pattern .pl-c-pattern-info{max-height:none;height:18rem;overflow:visible}}.pl-c-pattern-info__panel{-ms-flex-preferred-size:40%;flex-basis:40%;padding-top:1rem;padding-right:1rem;padding-bottom:0;padding-left:1rem;margin-bottom:1rem;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%;min-width:300px;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;overflow:auto;-webkit-overflow-scrolling:touch}.pl-c-pattern-info__header{margin-bottom:.5rem}.pl-c-pattern-info__title{font-size:1.4rem!important;font-weight:400;margin-top:0;margin-bottom:0;color:inherit;text-transform:capitalize;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.pl-c-pattern-info__description{border-bottom-color:grey}.pl-c-annotations{border-top-color:grey}.pl-c-pattern-state{display:inline-block;width:5px;height:5px;margin-left:10px;position:relative;top:5px;left:0;border-radius:50%;background-color:#02a4d5;line-height:4px;text-indent:10px}.pl-c-pattern-state--complete{background-color:#03790f}.pl-c-pattern-state--inreview{background-color:#c7a118}.pl-c-pattern-state--deprecated{background-color:#b00b02}.complete:before{color:#03790f!important}.pl-c-lineage{font-size:.85rem;line-height:1.7;margin-top:0}.pl-c-lineage__link{font-style:italic;color:grey;text-decoration:underline;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.pl-c-lineage__link:focus,.pl-c-lineage__link:hover{opacity:.8}.pl-c-breadcrumb{list-style:none;margin:0;padding:0;margin-bottom:.5rem;display:-webkit-box;display:-ms-flexbox;display:flex;font-size:.7rem;color:grey;text-transform:capitalize}.pl-c-breadcrumb__item:after{content:'\25B6';opacity:.4;font-size:6px;display:inline-block;margin:0 .2rem;position:relative;top:-1px}.pl-c-tabs{padding:0 .5rem .5rem;background-color:#fff;border:1px solid #ddd;border-radius:6px;font-family:HelveticaNeue,Helvetica,Arial,sans-serif;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;overflow:hidden;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.pl-c-tabs__list{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;list-style:none;margin:0;padding:.5rem 0;background-color:#fff}.pl-c-tabs__link{display:block;line-height:1;padding:.2rem .4rem;border:1px solid transparent;border-radius:6px;color:grey;background-color:#fff;cursor:pointer;text-decoration:none;text-transform:lowercase;-webkit-transition:all .1s ease-out;transition:all .1s ease-out}.pl-c-tabs__link:hover{color:#222}.pl-c-tabs__link.pl-is-active-tab{color:#222;background-color:#eee;border:1px solid #ddd}.pl-c-tabs__content{overflow:auto;-webkit-overflow-scrolling:touch;padding-top:.5rem}.pl-c-tabs__panel{display:none}.pl-c-tabs__panel.pl-is-active-tab{display:block}.pl-c-tabs__panel :not(pre)>code[class*=language-],.pl-c-tabs__panel pre[class*=language-]{background-color:transparent;margin:0;padding:0;border:0;display:block}.pl-c-tabs__panel code[class*=language-]{background-color:transparent;margin:0}.pl-c-tools{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex}.pl-c-tools__toggle{background-color:#000;color:grey;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline-offset:-3px;outline-width:2px;margin:0;padding-top:.6rem;padding-bottom:.5rem;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;position:relative;min-width:30px}.pl-c-tools__toggle:hover{color:#fff;background-color:#222}.pl-c-tools__toggle.pl-is-active,.pl-c-tools__toggle:active{color:#fff;background-color:#222;outline:1px dotted grey;outline-offset:-1px}.pl-c-body--theme-light .pl-c-tools__toggle{background-color:#fff;color:#4d4c4c}.pl-c-body--theme-light .pl-c-tools__toggle:hover{background-color:#eee}.pl-c-body--theme-light .pl-c-tools__toggle:active,.pl-c-body--theme-light .pl-c-tools__toggle:focus{background-color:#ddd}.pl-c-body--theme-density-cozy .pl-c-tools__toggle{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-tools__toggle{font-size:.85rem;padding:1.5rem 1rem}.pl-c-tools__toggle-icon{-webkit-transition:inherit;transition:inherit}.pl-c-tools__list{list-style:none;margin:0;padding:0;overflow:hidden;max-height:0;-webkit-transition:max-height .1s ease-out;transition:max-height .1s ease-out;position:absolute;top:100%;right:0;z-index:10;width:10rem;border-bottom-left-radius:6px;border-bottom-right-radius:6px}.pl-c-tools__list.pl-is-active{max-height:calc(100vh - 2rem - 1rem);max-height:calc(var(--pl-viewport-height,calc(100vh - 2rem)) - 1rem);overflow:auto;-webkit-overflow-scrolling:touch}.pl-c-tools__action{background-color:#000;color:grey;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline-offset:-3px;outline-width:2px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;margin:0}.pl-c-tools__action:hover{color:#fff;background-color:#222}.pl-c-tools__action.pl-is-active,.pl-c-tools__action:active{color:#fff;background-color:#222;outline:1px dotted grey;outline-offset:-1px}.pl-c-body--theme-light .pl-c-tools__action{background-color:#fff;color:#4d4c4c}.pl-c-body--theme-light .pl-c-tools__action:hover{background-color:#eee}.pl-c-body--theme-light .pl-c-tools__action:active,.pl-c-body--theme-light .pl-c-tools__action:focus{background-color:#ddd}.pl-c-body--theme-density-cozy .pl-c-tools__action{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-tools__action{font-size:.85rem;padding:1.5rem 1rem}.pl-c-tools__action-icon{margin-left:auto}.pl-has-annotation{cursor:help!important;outline:1px dotted grey;outline-offset:-4px;-webkit-transition:-webkit-box-shadow .1s ease;transition:-webkit-box-shadow .1s ease;transition:box-shadow .1s ease;transition:box-shadow .1s ease, -webkit-box-shadow .1s ease}.pl-has-annotation a,.pl-has-annotation input{cursor:help!important}.pl-has-annotation:hover{-webkit-box-shadow:0 0 3px grey;box-shadow:0 0 3px grey}.pl-has-annotation.active{-webkit-box-shadow:inset 0 0 6px #4d4c4c;box-shadow:inset 0 0 6px #4d4c4c;outline:1px dotted grey;outline-offset:-1px}.pl-c-annotation-tip{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:24px!important;height:24px!important;margin-top:6px!important;margin-left:6px!important;border-radius:50%!important;background-color:#222!important;color:#fff!important;font-size:16px!important;position:absolute;z-index:100}.pl-c-annotations{margin:1rem 0}.pl-c-annotations__title{font-size:1.2rem!important;margin:0 0 .5rem}.pl-c-annotations .pl-c-annotations__list{counter-reset:the-count;padding:0;margin:0;list-style:none}.pl-c-annotations__item{position:relative;padding-left:1.5rem;margin-bottom:1rem;border-radius:6px;-webkit-transition:background-color .1s ease;transition:background-color .1s ease}.pl-c-annotations__item:before{content:counter(the-count);counter-increment:the-count;font-size:85%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:14px;height:14px;border-radius:50%;padding:2px;text-align:center;background-color:grey;color:#fff;position:absolute;top:4px;left:0}.pl-c-annotations__item.pl-is-active{outline:1px dotted grey;outline-offset:-1px}.pl-c-annotations .pl-c-annotations__item-title{margin-bottom:0}pl-modal{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;position:relative;position:-webkit-sticky;position:sticky;z-index:20;max-height:100vh;-webkit-box-shadow:0 0 2px 0 #4d4c4c;box-shadow:0 0 2px 0 #4d4c4c;overflow:visible}.pl-c-modal{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;font-family:HelveticaNeue,Helvetica,Arial,sans-serif;background-color:#222;color:#ccc;position:-webkit-sticky;position:sticky;top:auto;bottom:0;left:0;right:0;z-index:5;width:100%;height:0;-webkit-transition:height .3s ease,-webkit-transform .3s ease;transition:height .3s ease,-webkit-transform .3s ease;transition:transform .3s ease,height .3s ease;transition:transform .3s ease,height .3s ease,-webkit-transform .3s ease;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);pointer-events:none;will-change:height,transform;overflow:hidden;max-width:100vw;-webkit-box-shadow:0 -1px 2px rgba(77,76,76,.1);box-shadow:0 -1px 2px rgba(77,76,76,.1)}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-modal{max-width:calc(100vw - 14rem)}}.pl-c-modal.pl-is-active{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);height:40vh;-webkit-transition:-webkit-transform .3s ease;transition:-webkit-transform .3s ease;transition:transform .3s ease;transition:transform .3s ease, -webkit-transform .3s ease;pointer-events:auto}.pl-c-modal__wrapper{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.pl-c-modal__wrapper>*{height:100%}.pl-c-modal__content{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;overflow:hidden}.pl-c-modal__toolbar{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-ms-flex-negative:0;flex-shrink:0}.pl-c-modal__content-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;overflow:hidden}.pl-c-modal__toolbar-controls{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-item-align:end;align-self:flex-end;position:relative;z-index:10;-ms-flex-negative:0;flex-shrink:0}.pl-c-modal__close-btn{background-color:#000;color:grey;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline-offset:-3px;outline-width:2px;margin:0;-webkit-appearance:none;-ms-flex-negative:0;flex-shrink:0;z-index:2;opacity:.85;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.pl-c-modal__close-btn:hover{color:#fff;background-color:#222}.pl-c-modal__close-btn.pl-is-active,.pl-c-modal__close-btn:active{color:#fff;background-color:#222;outline:1px dotted grey;outline-offset:-1px}.pl-c-body--theme-light .pl-c-modal__close-btn{background-color:#fff;color:#4d4c4c}.pl-c-body--theme-light .pl-c-modal__close-btn:hover{background-color:#eee}.pl-c-body--theme-light .pl-c-modal__close-btn:active,.pl-c-body--theme-light .pl-c-modal__close-btn:focus{background-color:#ddd}.pl-c-body--theme-density-cozy .pl-c-modal__close-btn{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-modal__close-btn{font-size:.85rem;padding:1.5rem 1rem}@media all and (max-width:41em){.pl-c-modal__close-btn{border-radius:20rem;padding-top:.5rem;padding-bottom:.5rem}}.pl-c-modal__close-btn:focus,.pl-c-modal__close-btn:hover{opacity:1}.pl-c-modal__close-btn:active,.pl-c-modal__close-btn:focus{opacity:1}.pl-c-modal__cover{width:100%;height:100%;display:none;position:absolute;z-index:20;cursor:move}.pl-c-modal__resizer{display:-webkit-box;display:-ms-flexbox;display:flex;position:absolute;top:0;left:0;right:0;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;left:0;height:14px;width:100%;background-color:inherit;z-index:2;cursor:ns-resize}.pl-c-modal__resizer:after{content:'';height:3px;width:50px;border-top:1px solid currentColor;border-bottom:1px solid currentColor;-webkit-transition:opacity .3s ease-out;transition:opacity .3s ease-out;opacity:.5;background-color:currentColor;border-radius:3px;display:block}.pl-c-modal__resizer:hover:after{opacity:.8}.pl-c-modal__resizer:active:after,.pl-c-modal__resizer:focus:after{opacity:.95}.pl-c-modal__close-btn-icon{width:12px;height:12px;color:currentColor;fill:currentColor;-webkit-transition:fill .1s ease-out;transition:fill .1s ease-out;-ms-flex-negative:0;flex-shrink:0;-ms-flex-item-align:center;align-self:center}.pl-c-code-copy-btn{display:inline-block;position:absolute;top:.5rem;right:.5rem;padding:.2rem .4rem;background-color:#eee;color:#222;border:1px solid #ddd;border-radius:6px;font-family:HelveticaNeue,Helvetica,Arial,sans-serif;font-size:1rem;text-transform:lowercase;line-height:1;cursor:pointer;z-index:2;-webkit-transition:background-color .1s ease-out;transition:background-color .1s ease-out}.pl-c-code-copy-btn:focus,.pl-c-code-copy-btn:hover{background-color:#ccc}.pl-c-text-passage{font-size:.85rem;line-height:1.7}.pl-c-text-passage p{margin-top:0;margin-bottom:1rem}.pl-c-text-passage a{color:grey;text-decoration:underline;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.pl-c-text-passage a:focus,.pl-c-text-passage a:hover{opacity:.8}.pl-c-text-passage code[class*=language-],.pl-c-text-passage pre[class*=language-]{color:inherit}.pl-c-text-passage blockquote{padding-left:.8rem;border-left:3px solid inherit}.pl-c-text-passage hr{height:1px;background-color:grey;margin:2rem 0;border:0}.pl-c-text-passage h1{margin-bottom:1rem;font-weight:400}.pl-c-text-passage h2{margin:1rem 0 1rem;font-weight:400}.pl-c-text-passage h3{margin:1rem 0 1rem;font-weight:400}.pl-c-text-passage h4{margin:1rem 0 1rem;font-weight:400}.pl-c-text-passage h5{margin:1rem 0 1rem;font-weight:400}.pl-c-text-passage h6{margin:1rem 0 1rem;font-weight:400}.pl-c-text-passage ul{list-style:square;margin-left:.9rem;margin-bottom:1rem}.pl-c-text-passage ul li:last-child{margin-bottom:0}.pl-c-text-passage ol{list-style:decimal;margin-left:.9rem;margin-bottom:1rem}.pl-c-text-passage ol li:last-child{margin-bottom:0}.pl-c-text-passage li{margin-bottom:.5rem}.pl-c-body--theme-light .pl-c-header{background-color:#fff;border-bottom:1px solid #ccc}@media all and (max-width:41em){.pl-c-body--theme-light .pl-c-tools__list.pl-is-active{border-bottom:1px solid #ccc;border-left:1px solid #ccc}}.pl-c-body--theme-light:not(.pl-c-body--theme-sidebar) .pl-c-tools__list.pl-is-active{border-bottom:1px solid #ccc;border-left:1px solid #ccc}.pl-c-body--theme-light .pl-c-nav__link--dropdown{color:#4d4c4c;background-color:#fff}.pl-c-body--theme-light .pl-c-nav__link--dropdown:after{color:#ccc}@media all and (min-width:42em){.pl-c-body--theme-light .pl-c-nav__sublist>.pl-c-nav__item:last-child .pl-c-nav__link{border-bottom-left-radius:6px;border-bottom-right-radius:6px}}.pl-c-body--theme-light .pl-c-viewport-size__input{color:#4d4c4c}.pl-c-body--theme-light .pl-c-viewport-size__input:focus,.pl-c-body--theme-light .pl-c-viewport-size__input:hover{background-color:#ddd}.pl-c-body--theme-light .typeahead{background-color:#ddd!important}.pl-c-body--theme-light .tt-input{background-color:#eee!important;color:#4d4c4c!important}.pl-c-body--theme-light .tt-input:hover{color:#222;background-color:#ddd!important}.pl-c-body--theme-light .tt-input:hover::-webkit-input-placeholder{color:#222}.pl-c-body--theme-light .tt-input:hover::-moz-input-placeholder{color:#222}.pl-c-body--theme-light .pl-c-modal{background-color:#fff;color:#4d4c4c;border-top:1px solid #ccc}.pl-c-body--theme-light .pl-c-modal__close-btn,.pl-c-body--theme-light .pl-c-tools__action{background-color:#fff}.pl-c-body--theme-light .pl-c-modal__close-btn:focus,.pl-c-body--theme-light .pl-c-modal__close-btn:hover,.pl-c-body--theme-light .pl-c-tools__action:focus,.pl-c-body--theme-light .pl-c-tools__action:hover{background-color:#eee;color:#4d4c4c}.pl-c-body--theme-density-cozy .pl-c-header{font-size:.85rem}.pl-c-body--theme-density-cozy .pl-c-viewport-size__input{width:44px}.pl-c-body--theme-density-cozy .pl-c-typeahead{padding:.9rem .8rem}@media all and (max-width:78em){.pl-c-body--theme-density-cozy .pl-c-size-list{display:none}}@media all and (max-width:78em){.pl-c-body--theme-density-cozy .pl-c-viewport-size{display:none}}.pl-c-body--theme-density-cozy .pl-c-tools__toggle{min-width:44px}.pl-c-body--theme-density-cozy .pl-c-viewport{top:3.28rem}.pl-c-body--theme-density-comfortable .pl-c-header{font-size:.85rem}.pl-c-body--theme-density-comfortable .pl-c-logo{max-width:4rem}.pl-c-body--theme-density-comfortable .pl-c-header .tt-suggestion{padding:1.5rem 1rem}.pl-c-body--theme-density-comfortable .pl-c-viewport-size__input{width:44px}.pl-c-body--theme-density-comfortable .pl-c-typeahead{padding:.9rem 1rem}@media all and (max-width:78em){.pl-c-body--theme-density-comfortable .pl-c-size-list{display:none}}@media all and (max-width:78em){.pl-c-body--theme-density-comfortable .pl-c-viewport-size{display:none}}.pl-c-body--theme-density-comfortable .pl-c-tools__toggle{min-width:44px}.pl-c-body--theme-density-comfortable .pl-c-viewport{top:3.8rem}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-header{width:14rem;height:100vh;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;border-bottom:0;padding:1rem;overflow:auto;-webkit-overflow-scrolling:touch;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.pl-c-body--theme-sidebar.pl-c-body--theme-light .pl-c-header{border-right:1px solid #ccc}.pl-c-body--theme-sidebar .pl-c-logo{max-width:7rem;margin:0 auto 1rem}.pl-c-body--theme-sidebar .pl-c-nav{display:block;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.pl-c-body--theme-sidebar .pl-c-nav__list{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.pl-c-body--theme-sidebar .pl-c-nav__sublist{position:relative;border-radius:0}.pl-c-body--theme-sidebar .pl-c-nav__sublist .pl-c-nav__link{padding-left:1rem}.pl-c-body--theme-sidebar .pl-c-nav__sublist--dropdown.pl-is-active{border:0;border-left:1px solid #4d4c4c}.pl-c-body--theme-sidebar.pl-c-body--theme-light .pl-c-nav__sublist--dropdown.pl-is-active{border-left-color:#eee}.pl-c-body--theme-sidebar .pl-c-nav__subsublist{border-left:1px solid #4d4c4c;margin-left:1rem}.pl-c-body--theme-sidebar.pl-c-body--theme-light .pl-c-nav__subsublist{border-left-color:#eee}.pl-c-body--theme-sidebar .pl-c-nav__sublist .pl-c-nav__link{border-left:0;border-right:0}}@media all and (min-width:42em) and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-nav__sublist>.pl-c-nav__item:last-child .pl-c-nav__link{border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom:0}}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-controls{display:block;justify-self:flex-end;margin-left:0}.pl-c-body--theme-sidebar .pl-c-viewport-size{display:none}.pl-c-body--theme-sidebar .pl-c-tools__toggle{display:none}.pl-c-body--theme-sidebar .pl-c-tools__list{max-height:none;overflow:visible;position:relative;border-radius:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%}.pl-c-body--theme-sidebar .pl-c-modal{right:0;width:auto}}.is-vishidden{position:absolute!important;overflow:hidden;width:1px;height:1px;padding:0;border:0;clip:rect(1px,1px,1px,1px)} +.pl-c-body *{-webkit-box-sizing:border-box;box-sizing:border-box}button{font-size:inherit;background-color:transparent}.pl-c-html{min-height:100%}.pl-c-body{margin:0;padding:0;-webkit-text-size-adjust:100%;display:-webkit-box;display:-ms-flexbox;display:flex}.pl-c-body--theme-dark,:root{--theme-bg:#161b3c;--theme-primary:#464a6d;--theme-secondary:#161f50;--theme-text:white;--theme-text-rgb:255,255,255;--theme-border:rgba(255, 255, 255, 0.2)}.pl-c-body--theme-light{--theme-bg:white;--theme-secondary:white;--theme-text:#262829;--theme-text-rgb:38,40,41;--theme-primary:white;--theme-border:#ddd}.pl-c-tabs__panel pre[class*=language-]{background-image:-webkit-gradient(linear,left top, right top,from(#fff),to(rgba(255,255,255,0))),-webkit-gradient(linear,right top, left top,from(#fff),to(rgba(255,255,255,0))),-webkit-gradient(linear,left top, right top,from(#eaf0f6),to(rgba(238,238,238,0))),-webkit-gradient(linear,right top, left top,from(#eaf0f6),to(rgba(238,238,238,0))),-webkit-gradient(linear,left top, left bottom,from(#fff),to(rgba(255,255,255,0))),-webkit-gradient(linear,left bottom, left top,from(#fff),to(rgba(255,255,255,0))),-webkit-gradient(linear,left top, left bottom,from(#eaf0f6),to(rgba(238,238,238,0))),-webkit-gradient(linear,left bottom, left top,from(#eaf0f6),to(rgba(238,238,238,0)));background-image:-webkit-linear-gradient(left,#fff,rgba(255,255,255,0)),-webkit-linear-gradient(right,#fff,rgba(255,255,255,0)),-webkit-linear-gradient(left,#eaf0f6,rgba(238,238,238,0)),-webkit-linear-gradient(right,#eaf0f6,rgba(238,238,238,0)),-webkit-linear-gradient(top,#fff,rgba(255,255,255,0)),-webkit-linear-gradient(bottom,#fff,rgba(255,255,255,0)),-webkit-linear-gradient(top,#eaf0f6,rgba(238,238,238,0)),-webkit-linear-gradient(bottom,#eaf0f6,rgba(238,238,238,0));background-image:linear-gradient(to right,#fff,rgba(255,255,255,0)),linear-gradient(to left,#fff,rgba(255,255,255,0)),linear-gradient(to right,#eaf0f6,rgba(238,238,238,0)),linear-gradient(to left,#eaf0f6,rgba(238,238,238,0)),linear-gradient(to bottom,#fff,rgba(255,255,255,0)),linear-gradient(to top,#fff,rgba(255,255,255,0)),linear-gradient(to bottom,#eaf0f6,rgba(238,238,238,0)),linear-gradient(to top,#eaf0f6,rgba(238,238,238,0));background-color:#fff;background-attachment:local,local,scroll,scroll,local,local,scroll,scroll;background-position:0 0,100% 0,0 0,100% 0,0 0,0 100%,0 0,0 100%;background-size:4em 100%,4em 100%,1em 100%,1em 100%,100% 4em,100% 4em,100% 1em,100% 1em;background-repeat:no-repeat;-ms-overflow-style:-ms-autohiding-scrollbar;-webkit-overflow-scrolling:touch;overflow:auto}.pl-c-tabs__panel code[class*=language-],.pl-c-tabs__panel pre[class*=language-]{color:#000;text-shadow:0 1px #fff;font-family:Consolas,Monaco,'Andale Mono',monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;word-wrap:normal;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none}.pl-c-tabs__panel code[class*=language-] ::-moz-selection,.pl-c-tabs__panel code[class*=language-]::-moz-selection,.pl-c-tabs__panel pre[class*=language-] ::-moz-selection,.pl-c-tabs__panel pre[class*=language-]::-moz-selection{text-shadow:none;background-color:#b3d4fc}.pl-c-tabs__panel code[class*=language-] ::selection,.pl-c-tabs__panel code[class*=language-]::selection,.pl-c-tabs__panel pre[class*=language-] ::selection,.pl-c-tabs__panel pre[class*=language-]::selection{text-shadow:none;background-color:#b3d4fc}@media print{.pl-c-tabs__panel code[class*=language-],.pl-c-tabs__panel pre[class*=language-]{text-shadow:none}}.pl-c-tabs__panel pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}.pl-c-tabs__panel :not(pre)>code[class*=language-],.pl-c-tabs__panel pre[class*=language-]{background-color:#f5f2f0}.pl-c-tabs__panel :not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em}.pl-c-tabs__panel .token.cdata,.pl-c-tabs__panel .token.comment,.pl-c-tabs__panel .token.doctype,.pl-c-tabs__panel .token.prolog{color:#708090}.pl-c-tabs__panel .token.punctuation{color:#999}.pl-c-tabs__panel .namespace{opacity:.7}.pl-c-tabs__panel .token.boolean,.pl-c-tabs__panel .token.constant,.pl-c-tabs__panel .token.deleted,.pl-c-tabs__panel .token.number,.pl-c-tabs__panel .token.property,.pl-c-tabs__panel .token.symbol,.pl-c-tabs__panel .token.tag{color:#905}.pl-c-tabs__panel .token.attr-name,.pl-c-tabs__panel .token.builtin,.pl-c-tabs__panel .token.char,.pl-c-tabs__panel .token.inserted,.pl-c-tabs__panel .token.selector,.pl-c-tabs__panel .token.string{color:#690}.pl-c-tabs__panel .language-css .token.string,.pl-c-tabs__panel .style .token.string,.pl-c-tabs__panel .token.entity,.pl-c-tabs__panel .token.operator,.pl-c-tabs__panel .token.url{color:#a67f59;background-color:rgba(255,255,255,.5)}.pl-c-tabs__panel .token.atrule,.pl-c-tabs__panel .token.attr-value,.pl-c-tabs__panel .token.keyword{color:#07a}.pl-c-tabs__panel .token.function{color:#dd4a68}.pl-c-tabs__panel .token.important,.pl-c-tabs__panel .token.regex,.pl-c-tabs__panel .token.variable{color:#e90}.pl-c-tabs__panel .token.bold,.pl-c-tabs__panel .token.important{font-weight:700}.pl-c-tabs__panel .token.italic{font-style:italic}.pl-c-tabs__panel .token.entity{cursor:help}.pl-c-tabs__panel pre.line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}.pl-c-tabs__panel pre.line-numbers>code{position:relative}.pl-c-tabs__panel .line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:0;font-size:100%;left:-3.8em;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pl-c-tabs__panel .line-numbers-rows>span{pointer-events:none;display:block;counter-increment:linenumber}.pl-c-tabs__panel .line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}.pl-c-tabs__panel .token a{color:inherit}pl-controls{margin-left:auto;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-ms-flex-item-align:center;align-self:center;padding:0 .5rem}.pl-c-body--theme-sidebar pl-controls{display:block}@media all and (min-width:42em){.pl-c-body--theme-sidebar pl-controls{width:100%;position:relative;padding-top:.5rem;padding-bottom:.5rem;-webkit-box-shadow:0 -2px 5px rgba(0,0,0,.1);box-shadow:0 -2px 5px rgba(0,0,0,.1)}.pl-c-body--theme-sidebar pl-controls:before{position:absolute;left:0;right:0;top:0;border-top:1px solid;border-top-color:#ccc;border-top-color:var(--theme-border,#ccc);height:1px;content:'';width:auto}}.pl-c-controls{margin-left:auto;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-controls{display:block}}.pl-c-controls__list{list-style:none;margin:0;padding:0;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:nowrap;flex-wrap:nowrap}pl-drawer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;position:relative;position:-webkit-sticky;position:sticky;top:auto;bottom:0;left:0;right:0;z-index:20;overflow:visible;border-top:1.1px solid #ccc;border-top-color:#ccc;border-top-color:var(--theme-border,#ccc)}.pl-c-drawer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;font-family:"Open Sans",HelveticaNeue,Helvetica,Arial,sans-serif;background-color:#222;background-color:var(--theme-secondary,#222);color:#ccc;width:100%;height:100%;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);pointer-events:none;overflow:hidden;max-width:100vw}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-drawer{max-width:calc(100vw - 16rem)}}.pl-c-body--theme-light .pl-c-drawer{background-color:#fff;color:#4d4c4c}.pl-c-drawer.pl-is-active{pointer-events:auto}.pl-c-drawer__wrapper{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.pl-c-drawer__wrapper>*{height:100%}.pl-c-drawer__content{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;overflow:hidden}.pl-c-drawer__toolbar{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-ms-flex-negative:0;flex-shrink:0}.pl-c-drawer__content-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;overflow:hidden}@supports (padding:env(safe-area-inset-top)){.pl-c-drawer__content-wrapper{padding-right:calc(env(safe-area-inset-right) - .9rem)}}.pl-c-drawer__toolbar-controls{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-item-align:end;align-self:flex-end;position:relative;z-index:10;-ms-flex-negative:0;flex-shrink:0}.pl-c-drawer__close-btn{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:inherit;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline:0;margin:0;padding:.2rem;-webkit-appearance:none;-ms-flex-negative:0;flex-shrink:0;z-index:2;opacity:.85;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.pl-c-drawer__close-btn.pl-is-active:hover,.pl-c-drawer__close-btn:hover{background-color:rgba(0,0,0,.1)}.pl-c-body--theme-density-cozy .pl-c-drawer__close-btn{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-drawer__close-btn{font-size:.85rem;padding:1.5rem 1rem}@media all and (max-width:41em){.pl-c-drawer__close-btn{border-radius:20rem;padding-top:.5rem;padding-bottom:.5rem}}.pl-c-drawer__close-btn:focus,.pl-c-drawer__close-btn:hover{opacity:1}.pl-c-drawer__close-btn:active,.pl-c-drawer__close-btn:focus{opacity:1}.pl-c-drawer__cover{width:100%;height:100%;top:0;left:0;display:none;position:fixed;z-index:20;cursor:move}.pl-c-drawer__resizer{display:-webkit-box;display:-ms-flexbox;display:flex;position:absolute;top:0;left:0;right:0;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;height:14px;width:100%;background-color:inherit;z-index:2;cursor:ns-resize}.pl-c-drawer__resizer:after{content:'';height:3px;width:50px;border-top:1px solid currentColor;border-bottom:1px solid currentColor;-webkit-transition:opacity .3s ease-out;transition:opacity .3s ease-out;opacity:.5;background-color:currentColor;border-radius:3px;display:block}.pl-c-drawer__resizer:hover:after{opacity:.8}.pl-c-drawer__resizer:active:after,.pl-c-drawer__resizer:focus:after{opacity:.95}.pl-c-drawer__close-btn-icon{width:20px;height:20px;color:currentColor;fill:currentColor;-webkit-transition:fill .1s ease-out;transition:fill .1s ease-out;-ms-flex-negative:0;flex-shrink:0;-ms-flex-item-align:center;align-self:center}.pl-c-code-copy-btn{display:inline-block;position:absolute;top:.5rem;right:.5rem;padding:.2rem .4rem;background-color:#eee;color:#222;border:1px solid #ddd;border-radius:6px;font-family:"Open Sans",HelveticaNeue,Helvetica,Arial,sans-serif;font-size:1rem;text-transform:lowercase;line-height:1;cursor:pointer;z-index:2;-webkit-transition:background-color .1s ease-out;transition:background-color .1s ease-out}.pl-c-code-copy-btn:focus,.pl-c-code-copy-btn:hover{background-color:#ccc}pl-header{position:relative;position:-webkit-sticky;position:sticky;top:0;left:0;z-index:4;display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;background-color:#000;background-color:var(--theme-secondary,#000);max-height:100vh;color:#ccc;color:var(--theme-text,#ccc);border-right:1px solid;border-bottom:1px solid;border-right-color:#ccc;border-right-color:var(--theme-border,#ccc);border-bottom-color:#ccc;border-bottom-color:var(--theme-border,#ccc)}.pl-c-body--theme-light pl-header{color:#000;background-color:#fff;border-bottom:1px solid #ccc}@media all and (min-width:42em){.pl-c-body--theme-sidebar pl-header{position:fixed;position:-webkit-sticky;position:sticky;width:16rem;border-bottom:0}}.pl-c-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;width:100%;font-family:"Open Sans",HelveticaNeue,Helvetica,Arial,sans-serif;font-size:.9rem;min-height:30px;background-color:inherit}@supports (padding:0px){.pl-c-header{padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right)}}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-header{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}}.pl-c-header__nav-toggle{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:inherit;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline:0;border:0}.pl-c-header__nav-toggle.pl-is-active:hover,.pl-c-header__nav-toggle:hover{background-color:rgba(0,0,0,.1)}.pl-c-body--theme-density-cozy .pl-c-header__nav-toggle{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-header__nav-toggle{font-size:.85rem;padding:1.5rem 1rem}@media all and (min-width:42em){.pl-c-header__nav-toggle{display:none}}pl-layout{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%;min-height:100vh;max-width:100vw;background-color:#fff}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){pl-layout{overflow:hidden}}pl-layout .pl-c-layout{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}@media all and (min-width:42em){pl-layout.pl-c-body--theme-sidebar{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}}pl-layout.pl-c-body--theme-light{background-color:#fff}pl-nav{background-color:inherit;display:block;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-box-align:center;-ms-flex-align:center;align-items:center}@media all and (min-width:42em){pl-nav{padding:0;display:-webkit-box;display:-ms-flexbox;display:flex}}@media all and (min-width:42em){.pl-c-body--theme-sidebar pl-nav{display:block}}.pl-c-nav{overflow:hidden;max-height:0;-webkit-transition:max-height .1s ease-out;transition:max-height .1s ease-out;background-color:inherit;position:absolute;left:0;top:100%;width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;transition:max-height .1s ease-out;-ms-flex-negative:0;flex-shrink:0;padding-left:.25rem;padding-right:.25rem}.pl-c-nav.pl-is-active{max-height:calc(100vh - 2rem - 1rem);max-height:calc(var(--pl-viewport-height,calc(100vh - 2rem)) - 1rem);overflow:auto;-webkit-overflow-scrolling:touch}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-nav{padding-bottom:.5rem;display:block;overflow:auto;-webkit-overflow-scrolling:touch;-ms-flex-negative:1;flex-shrink:1}}@media all and (min-width:42em){.pl-c-nav{overflow:visible;max-height:none}.pl-c-nav.pl-is-active{overflow:visible}}@media all and (max-width:41em){.pl-c-nav.pl-is-active{-webkit-box-shadow:0 1px 1px #000;box-shadow:0 1px 1px #000}.pl-c-body--theme-light .pl-c-nav.pl-is-active{-webkit-box-shadow:0 1px 1px #a6a6a6;box-shadow:0 1px 1px #a6a6a6}}@media all and (min-width:42em){.pl-c-nav.pl-is-active{max-height:none}}@media all and (min-width:42em){.pl-c-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;position:relative;top:auto;width:auto;-webkit-box-shadow:none;box-shadow:none}}.pl-c-nav__list{z-index:1;margin:0;padding:0;list-style:none;-ms-flex-negative:0;flex-shrink:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%;-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2;background-color:inherit}@media all and (min-width:42em){.pl-c-nav__list{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.pl-c-body--theme-sidebar .pl-c-nav__list{display:block}}.pl-c-nav__item{background-color:inherit;cursor:pointer;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.pl-c-body--theme-sidebar .pl-c-nav__item{display:block}.pl-c-nav__item-inner{position:relative}.pl-c-nav__link{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:inherit;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline:0;color:inherit;line-height:1.5;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0;color:inherit;padding:.7rem .5rem}.pl-c-nav__link.pl-is-active:hover,.pl-c-nav__link:hover{background-color:rgba(0,0,0,.1)}.pl-c-body--theme-density-cozy .pl-c-nav__link{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-nav__link{font-size:.85rem;padding:1.5rem 1rem}.pl-c-body--theme-sidebar .pl-c-nav__link{width:100%}.pl-c-nav__link,.pl-c-nav__link--overview,.pl-c-nav__link--section-dropdown,.pl-c-nav__link--sublink{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:inherit;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline:0;position:relative;color:inherit}.pl-c-nav__link--overview.pl-is-active:hover,.pl-c-nav__link--overview:hover,.pl-c-nav__link--section-dropdown.pl-is-active:hover,.pl-c-nav__link--section-dropdown:hover,.pl-c-nav__link--sublink.pl-is-active:hover,.pl-c-nav__link--sublink:hover,.pl-c-nav__link.pl-is-active:hover,.pl-c-nav__link:hover{background-color:rgba(0,0,0,.1)}.pl-c-body--theme-density-cozy .pl-c-nav__link,.pl-c-body--theme-density-cozy .pl-c-nav__link--overview,.pl-c-body--theme-density-cozy .pl-c-nav__link--section-dropdown,.pl-c-body--theme-density-cozy .pl-c-nav__link--sublink{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-nav__link,.pl-c-body--theme-density-comfortable .pl-c-nav__link--overview,.pl-c-body--theme-density-comfortable .pl-c-nav__link--section-dropdown,.pl-c-body--theme-density-comfortable .pl-c-nav__link--sublink{font-size:.85rem;padding:1.5rem 1rem}.pl-c-nav__link--overview:after,.pl-c-nav__link--section-dropdown:after,.pl-c-nav__link--sublink:after,.pl-c-nav__link:after{content:'';pointer-events:none;opacity:0;background-color:currentColor;-webkit-transition:opacity .1s ease-out;transition:opacity .1s ease-out;position:absolute;top:0;left:0;bottom:0;right:0;display:block}.pl-c-nav__link--overview:hover:after,.pl-c-nav__link--section-dropdown:hover:after,.pl-c-nav__link--sublink:hover:after,.pl-c-nav__link:hover:after{opacity:.1}.pl-c-nav__link--overview:focus:after,.pl-c-nav__link--section-dropdown:focus:after,.pl-c-nav__link--sublink:focus:after,.pl-c-nav__link:focus:after{opacity:.1}.pl-c-nav__link--sublink{text-transform:none;font-size:.8rem;line-height:1.45;padding-left:1.5rem;padding-right:1.5rem}.pl-c-nav__link--sublink.pl-is-active{-webkit-box-shadow:inset 4px 0 0 #6c79d9;box-shadow:inset 4px 0 0 #6c79d9;font-weight:700}.pl-c-nav__link--dropdown{-webkit-appearance:none;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.pl-c-nav__link--pattern{padding-left:.75rem;padding-right:.75rem;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.pl-c-nav__link-text{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;pointer-events:none}.pl-c-nav__link-icon{pointer-events:none;color:currentColor;display:inline;-webkit-transition:all .1s ease-out;transition:all .1s ease-out;-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0;line-height:1}.pl-c-nav__link--overview-wrapper.pl-is-active>.pl-c-nav__link--section-dropdown>.pl-c-nav__link-icon,.pl-is-active>.pl-c-nav__link-icon{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}.pl-c-nav__sublist{background-color:inherit;list-style:none;margin:0;padding:0}@media all and (min-width:42em){.pl-c-nav__sublist{position:absolute;top:100%;left:0;min-width:12rem;border-bottom-left-radius:6px;border-bottom-right-radius:6px}}.pl-c-nav__sublist--dropdown,.pl-c-nav__subsublist--dropdown{list-style:none;margin:0;padding:0;overflow:hidden;max-height:0;-webkit-transition:max-height .1s ease-out;transition:max-height .1s ease-out;visibility:hidden}.pl-c-nav__sublist--dropdown.pl-is-active,.pl-c-nav__subsublist--dropdown.pl-is-active{max-height:calc(100vh - 2rem - 1rem);max-height:calc(var(--pl-viewport-height,calc(100vh - 2rem)) - 1rem);overflow:auto;-webkit-overflow-scrolling:touch}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-nav__sublist--dropdown,.pl-c-body--theme-sidebar .pl-c-nav__subsublist--dropdown{position:relative}}.pl-c-nav__sublist--dropdown .pl-c-nav__link,.pl-c-nav__subsublist--dropdown .pl-c-nav__link{padding-left:1.5rem}.pl-c-nav__sublist--dropdown .pl-c-nav__link--sublink,.pl-c-nav__subsublist--dropdown .pl-c-nav__link--sublink{padding-left:2.25rem}@media all and (max-width:41em){.pl-c-nav__sublist--dropdown .pl-c-nav__link,.pl-c-nav__subsublist--dropdown .pl-c-nav__link{padding-left:1.5rem}.pl-c-nav__sublist--dropdown .pl-c-nav__link--sublink,.pl-c-nav__subsublist--dropdown .pl-c-nav__link--sublink{padding-left:2.25rem}}.pl-c-nav__sublist--dropdown.pl-is-active,.pl-c-nav__subsublist--dropdown.pl-is-active{visibility:visible;max-height:none}@media all and (min-width:42em){.pl-c-nav__sublist--dropdown.pl-is-active,.pl-c-nav__subsublist--dropdown.pl-is-active{height:auto;max-height:calc(100vh - 2rem - 2rem)}}.pl-c-body--theme-sidebar .pl-c-nav__sublist--dropdown.pl-is-active,.pl-c-body--theme-sidebar .pl-c-nav__subsublist--dropdown.pl-is-active{max-height:none}@media all and (min-width:42em){.pl-c-nav__sublist--dropdown.pl-is-active{-webkit-box-shadow:0 1px 3px rgba(0,0,0,.1);box-shadow:0 1px 3px rgba(0,0,0,.1);border-left:1px solid #222;border-right:1px solid #222;border-left-color:#222;border-right-color:#222;border-left-color:rgba(var(--theme-text-rgb),.1);border-right-color:rgba(var(--theme-text-rgb),.1)}}.pl-c-body--theme-sidebar .pl-c-nav__sublist--dropdown.pl-is-active{-webkit-box-shadow:none;box-shadow:none;border:none}.pl-c-nav__link--overview.pl-is-active:hover:before{opacity:.1}.pl-c-nav__link--overview-wrapper:before,.pl-c-nav__link--overview:before,.pl-c-nav__subsublist--dropdown:before{content:'';position:absolute;left:0;right:0;-webkit-transition:opacity .1s ease-out;transition:opacity .1s ease-out;opacity:0;top:0;bottom:0;background-color:currentColor;z-index:1;pointer-events:none}.pl-c-nav__link--overview-wrapper:after,.pl-c-nav__link--overview:after,.pl-c-nav__subsublist--dropdown:after{content:'';position:absolute;left:0;right:0;-webkit-transition:opacity .1s ease-out;transition:opacity .1s ease-out;opacity:0;top:0;bottom:0;border-top:1px solid rgba(0,0,0,.1);border-bottom:1px solid rgba(0,0,0,.1);z-index:1;pointer-events:none}.pl-c-nav__link--overview-wrapper.pl-is-active:after,.pl-c-nav__link--overview-wrapper.pl-is-active:before,.pl-c-nav__link--overview.pl-is-active:after,.pl-c-nav__link--overview.pl-is-active:before,.pl-c-nav__subsublist--dropdown.pl-is-active:after,.pl-c-nav__subsublist--dropdown.pl-is-active:before{opacity:.025}.pl-c-body--theme-dark .pl-c-nav__link--overview-wrapper:after,.pl-c-body--theme-dark .pl-c-nav__link--overview:after,.pl-c-body--theme-dark .pl-c-nav__subsublist--dropdown:after{border-bottom:1px solid rgba(255,255,255,.1)}.pl-c-nav__subsublist{list-style:none;margin:0;padding:0}.pl-c-nav__link--overview.pl-c-nav__link--overview.pl-c-nav__link--overview{font-size:.9rem;padding-right:.5rem;padding-left:1.5rem;position:relative;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.pl-c-nav__link--overview.pl-c-nav__link--overview.pl-c-nav__link--overview:not(:only-child){margin-right:2.5rem}.pl-c-nav__link--title{font-size:.9rem;color:#ccc;color:var(--theme-text,#ccc)}.pl-c-nav__link--title.pl-is-active{font-weight:700}.pl-c-body--theme-light .pl-c-nav__link--title{color:#000;color:var(--theme-text)}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-nav__list>.pl-c-nav__item:not(:last-child){margin-bottom:.5rem;margin-top:.5rem}}.pl-c-nav__link--section-dropdown{width:2.5rem!important;height:2.5rem!important;padding:0!important;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;font-size:0;position:absolute;right:0;top:50%;border:2px solid transparent!important;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:currentColor}.pl-c-nav__link--section-dropdown:before{opacity:.1;right:2.4rem;width:1px;left:auto;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.pl-c-nav__link--section-dropdown:after{opacity:0;width:2.5rem;left:50%;-webkit-transform:translateY(-50%) translateX(-50%);-ms-transform:translateY(-50%) translateX(-50%);transform:translateY(-50%) translateX(-50%)}.pl-c-nav__link--section-dropdown:after,.pl-c-nav__link--section-dropdown:before{height:2.5rem;-webkit-transition:opacity .1s ease-out;transition:opacity .1s ease-out;content:'';display:block;position:absolute;top:50%;background-color:currentColor}.pl-c-nav__link--section-dropdown:hover:after,.pl-c-nav__link--section-dropdown:hover:focus:after{opacity:.1}.pl-c-nav__link--section-dropdown:active:not(:hover):after,.pl-c-nav__link--section-dropdown:focus:not(:hover):after{opacity:0}.pl-c-nav__link--overview-wrapper{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex}pl-logo{max-width:12rem;-ms-flex-item-align:center;align-self:center;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-ms-flex-negative:0;flex-shrink:0;position:relative;z-index:100}@media all and (min-width:42em){.pl-c-body--theme-sidebar pl-logo{max-width:none;width:12rem;padding:.5rem}}.pl-c-logo{width:12rem;padding:.5rem;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;color:inherit;text-decoration:none;outline:0;text-transform:lowercase;font-size:1.4rem;font-weight:700;line-height:1;margin:0;-webkit-transition:color .2s ease;transition:color .2s ease}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-logo{width:12rem}}.pl-c-logo:focus{outline:1px dotted grey;outline-offset:-1px}.pl-c-logo__img{display:block;height:auto;max-height:2.5rem}.pl-c-logo__text{margin-left:.5rem}.tooltip-container{color:#222}pl-search{background-color:inherit;top:0;z-index:10;-ms-flex-negative:0;flex-shrink:0;padding:.4rem .5rem;display:inline-block;-ms-flex-item-align:stretch;align-self:stretch}@media screen and (min-width:42em){pl-search{margin-left:1rem;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-negative:1;flex-shrink:1;-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2;-ms-flex-item-align:center;align-self:center}.pl-c-body--theme-sidebar pl-search{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin-left:0;width:100%;padding-top:1rem}}.pl-c-typeahead{width:100%;background-color:inherit;-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2;display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;z-index:10;text-transform:capitalize;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;color:#fafafa;position:relative}.pl-c-body--theme-light .pl-c-typeahead{color:#222}@media screen and (min-width:42em){.pl-c-typeahead{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.pl-c-body--theme-sidebar .pl-c-typeahead{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}}.pl-c-typeahead__hint{top:0;left:0;right:0;width:100%}.pl-c-typeahead__hint,.pl-c-typeahead__input{text-transform:capitalize;background-color:#222;color:#fff;background-color:rgba(var(--theme-text-rgb),.1);color:rgba(var(--theme-text-rgb),.67);border-color:rgba(0,0,0,.1);text-overflow:ellipsis;border-width:1px;border-style:solid;-webkit-transition:all .1s ease;transition:all .1s ease;max-width:100%;padding:.4rem .5rem;font-size:16px;width:100%;outline-offset:-3px;outline-width:2px;-webkit-appearance:none}@media all and (min-width:900px){.pl-c-typeahead__hint,.pl-c-typeahead__input{font-size:inherit}}.pl-c-typeahead__hint::-ms-clear,.pl-c-typeahead__input::-ms-clear{display:none}.pl-c-body--theme-sidebar .pl-c-typeahead__hint,.pl-c-body--theme-sidebar .pl-c-typeahead__input{border-radius:0}.pl-c-typeahead__input-wrapper--with-clear-button .pl-c-typeahead__hint,.pl-c-typeahead__input-wrapper--with-clear-button .pl-c-typeahead__input{padding-right:1.7rem}@media all and (min-width:42em){.pl-c-typeahead__input-wrapper--with-clear-button .pl-c-typeahead__hint,.pl-c-typeahead__input-wrapper--with-clear-button .pl-c-typeahead__input{padding-right:1.4rem}}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-typeahead__hint,.pl-c-body--theme-sidebar .pl-c-typeahead__input{max-width:none}}.pl-c-body--theme-light .pl-c-typeahead__hint,.pl-c-body--theme-light .pl-c-typeahead__input{background-color:#eee;background-color:rgba(var(--theme-text-rgb),.1);color:#4d4c4c;color:rgba(var(--theme-text-rgb),.67)}.pl-c-typeahead__hint::-moz-input-placeholder,.pl-c-typeahead__hint::-webkit-input-placeholder,.pl-c-typeahead__input::-moz-input-placeholder,.pl-c-typeahead__input::-webkit-input-placeholder{color:#fff!important;-webkit-transition:all .1s ease;transition:all .1s ease}.pl-c-typeahead__hint:focus,.pl-c-typeahead__hint:hover,.pl-c-typeahead__input:focus,.pl-c-typeahead__input:hover{color:#fff}.pl-c-body--theme-light .pl-c-typeahead__hint:focus,.pl-c-body--theme-light .pl-c-typeahead__hint:hover,.pl-c-body--theme-light .pl-c-typeahead__input:focus,.pl-c-body--theme-light .pl-c-typeahead__input:hover{color:#222!important}.pl-c-typeahead__hint:focus::-moz-input-placeholder,.pl-c-typeahead__hint:focus::-webkit-input-placeholder,.pl-c-typeahead__hint:hover::-moz-input-placeholder,.pl-c-typeahead__hint:hover::-webkit-input-placeholder,.pl-c-typeahead__input:focus::-moz-input-placeholder,.pl-c-typeahead__input:focus::-webkit-input-placeholder,.pl-c-typeahead__input:hover::-moz-input-placeholder,.pl-c-typeahead__input:hover::-webkit-input-placeholder{color:#fff!important}.pl-c-body--theme-light .pl-c-typeahead__hint:focus::-moz-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__hint:focus::-webkit-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__hint:hover::-moz-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__hint:hover::-webkit-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__input:focus::-moz-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__input:focus::-webkit-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__input:hover::-moz-input-placeholder,.pl-c-body--theme-light .pl-c-typeahead__input:hover::-webkit-input-placeholder{color:#222!important}.pl-c-typeahead__menu{overflow:hidden;max-height:0;-webkit-transition:max-height .1s ease-out;transition:max-height .1s ease-out;background-color:#222;background-color:var(--theme-primary);color:var(--theme-text);text-transform:capitalize;position:absolute;min-width:100%;width:100%;overflow:hidden;top:100%;right:0;max-height:0;display:block!important;-webkit-transition:max-height .3s ease,opacity .3s ease;transition:max-height .3s ease,opacity .3s ease;opacity:0}.pl-c-typeahead__menu.pl-is-active{max-height:calc(100vh - 2rem - 1rem);max-height:calc(var(--pl-viewport-height,calc(100vh - 2rem)) - 1rem);overflow:auto;-webkit-overflow-scrolling:touch}@media all and (min-width:42em){.pl-c-typeahead__menu{border-bottom-right-radius:6px;border-bottom-left-radius:6px}}.pl-c-body--theme-light .pl-c-typeahead__menu{background-color:#fafafa}.pl-c-typeahead__menu.pl-is-open{max-height:120rem;max-height:calc(var(--viewport-height) - 4rem);opacity:1}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-typeahead__menu{position:relative!important;border-radius:0}}@media all and (max-width:41em){.pl-c-typeahead__menu{position:relative!important}}.pl-c-typeahead__results{list-style:none;margin:0;padding:0;background-color:inherit;border-color:transparent;border-width:1px;border-style:solid;overflow:hidden;border-color:#151515}@media all and (min-width:42em){.pl-c-typeahead__results{border-bottom-right-radius:6px;border-bottom-left-radius:6px}}.pl-c-typeahead__results:empty{border-width:0;max-height:0}.pl-c-body--theme-light .pl-c-typeahead__results{border-color:#ccc}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-typeahead__results{border-radius:0}}.pl-c-typeahead__result{-webkit-transition:all .3s ease;transition:all .3s ease;background-color:inherit;padding:.5rem .75rem;cursor:pointer;overflow:hidden;font-size:.8rem;color:inherit}.pl-c-typeahead__result:last-child{border-bottom-right-radius:6px;border-bottom-left-radius:6px}@media all and (max-width:41em){.pl-c-typeahead__result:last-child{border-radius:0}}.pl-c-body--theme-sidebar .pl-c-typeahead__result:last-child{border-radius:0}.pl-c-typeahead__result:hover{background-color:rgba(255,255,255,.15)}.pl-c-body--theme-light .pl-c-typeahead__result:hover{background-color:#eee}.pl-c-typeahead__result:active,.pl-c-typeahead__result:focus{background-color:rgba(255,255,255,.18)}.pl-c-body--theme-light .pl-c-typeahead__result:active,.pl-c-body--theme-light .pl-c-typeahead__result:focus{background-color:#ddd}.pl-c-typeahead__result.pl-has-cursor{color:#fff;background-color:rgba(255,255,255,.25)}.pl-c-body--theme-light .pl-c-typeahead__result.pl-has-cursor{color:#000;background-color:#ddd}.pl-c-typeahead__input-wrapper{position:relative;-ms-flex-negative:0;flex-shrink:0}.pl-c-typeahead__clear-button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:inherit;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline:0;height:1.7rem;width:1.7rem;background-color:transparent;border-radius:20rem;overflow:hidden;position:absolute;right:0;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);z-index:100;cursor:pointer;border:0;-webkit-transition:opacity .1s ease;transition:opacity .1s ease;opacity:0;visibility:hidden}.pl-c-typeahead__clear-button.pl-is-active:hover,.pl-c-typeahead__clear-button:hover{background-color:rgba(0,0,0,.1)}.pl-c-body--theme-density-cozy .pl-c-typeahead__clear-button{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-typeahead__clear-button{font-size:.85rem;padding:1.5rem 1rem}.pl-c-typeahead__clear-button:active,.pl-c-typeahead__clear-button:hover{background-color:transparent}@media all and (min-width:42em){.pl-c-typeahead__clear-button{height:1.4rem;width:1.4rem}}.pl-c-body--theme-light .pl-c-typeahead__clear-button{background-color:transparent}.pl-c-body--theme-light .pl-c-typeahead__clear-button:active,.pl-c-body--theme-light .pl-c-typeahead__clear-button:hover{background-color:transparent}.pl-c-typeahead__clear-button.pl-is-visible{opacity:1;visibility:visible}.pl-c-typeahead__clear-button-icon{fill:currentColor;line-height:0;font-size:0;position:absolute;top:50%;left:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0)}pl-toggle-info{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-item-align:center;align-self:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:10;width:100%;cursor:pointer}.pl-c-toggle-info,.pl-c-toggle-info__action{width:100%}pl-toggle-layout{display:none;-ms-flex-item-align:center;align-self:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:10;width:100%;cursor:pointer}@media all and (min-width:42em){pl-toggle-layout{display:-webkit-box;display:-ms-flexbox;display:flex}}.pl-c-toggle-layout,.pl-c-toggle-layout__action{width:100%}pl-toggle-theme{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-item-align:center;align-self:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:10;width:100%;cursor:pointer}.pl-c-toggle-theme,.pl-c-toggle-theme__action{width:100%}pl-tools-menu{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.pl-c-tools{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex}.pl-c-tools__toggle{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:inherit;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline:0;margin:0;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;position:relative;min-width:30px}.pl-c-tools__toggle.pl-is-active:hover,.pl-c-tools__toggle:hover{background-color:rgba(0,0,0,.1)}.pl-c-body--theme-density-cozy .pl-c-tools__toggle{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-tools__toggle{font-size:.85rem;padding:1.5rem 1rem}.pl-c-tools__toggle-icon{-webkit-transition:inherit;transition:inherit}.pl-c-tools__list{list-style:none;margin:0;padding:0;overflow:hidden;max-height:0;-webkit-transition:max-height .1s ease-out;transition:max-height .1s ease-out;-webkit-transform:translateY(-10px);-ms-transform:translateY(-10px);transform:translateY(-10px);position:absolute;right:3px;z-index:10;width:12rem;border-radius:6px;top:calc(100% + 4px);-webkit-box-shadow:0 0 5px rgba(0,0,0,.1);box-shadow:0 0 5px rgba(0,0,0,.1);background-color:#222;background-color:var(--theme-primary,#222)}.pl-c-tools__list.pl-is-active{max-height:calc(100vh - 2rem - 1rem);max-height:calc(var(--pl-viewport-height,calc(100vh - 2rem)) - 1rem);overflow:auto;-webkit-overflow-scrolling:touch}.pl-c-body--theme-light .pl-c-tools__list{background-color:#fff;background-color:var(--theme-primary,#fff)}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-tools__list{-webkit-box-shadow:none;box-shadow:none;top:0;-webkit-transform:none;-ms-transform:none;transform:none;border-radius:0;background-color:transparent}}.pl-c-tools__list.pl-is-active{overflow:visible}.pl-c-tools__list:before{content:'';height:14px;width:14px;background-color:#222;background-color:var(--theme-primary,#222);position:absolute;right:0;top:-10px;-webkit-transform:translateY(50%) translateX(-50%) rotate(45deg);-ms-transform:translateY(50%) translateX(-50%) rotate(45deg);transform:translateY(50%) translateX(-50%) rotate(45deg);-webkit-transition:opacity .1s ease-out;transition:opacity .1s ease-out;opacity:0;visibility:hidden;-webkit-box-shadow:0 0 5px rgba(0,0,0,.1);box-shadow:0 0 5px rgba(0,0,0,.1)}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-tools__list:before{display:none}}.pl-c-tools__list.pl-is-active:before{opacity:1;visibility:visible}.pl-c-tools__item{position:relative;overflow:hidden}.pl-c-tools__item:first-child{border-top-left-radius:6px;border-top-right-radius:6px}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-tools__item:first-child{border-radius:0}}.pl-c-tools__item:last-child{border-bottom-left-radius:6px;border-bottom-right-radius:6px}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-tools__item:last-child{border-radius:0}}.pl-c-tools__action{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:inherit;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline:0;padding-top:.4rem;padding-bottom:.4rem;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;margin:0;-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.pl-c-tools__action.pl-is-active:hover,.pl-c-tools__action:hover{background-color:rgba(0,0,0,.1)}.pl-c-body--theme-density-cozy .pl-c-tools__action{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-tools__action{font-size:.85rem;padding:1.5rem 1rem}.pl-c-tools__action-icon{margin-right:.5rem}.pl-c-tools__action-icon:first-child:last-child{margin-right:0}pl-iframe{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;background-color:#fff}.pl-c-viewport{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%;position:relative;top:2rem;bottom:0;left:0;right:0;z-index:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-transition:height .3s ease;transition:height .3s ease;background-color:#fff}@supports ((position: -webkit-sticky) or (position: sticky)){.pl-c-viewport{top:0}}.pl-c-body--theme-sidebar .pl-c-viewport{top:0}.pl-c-viewport__cover{width:100%;height:100%;display:none;position:fixed;top:0;left:0;z-index:200;cursor:move;pointer-events:auto}.pl-c-viewport__iframe-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-width:100vw;width:100%;position:relative;margin:0 auto;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-overflow-scrolling:touch;width:100%}.pl-c-viewport__iframe-wrapper.hay-mode{-webkit-transition:all 40s linear;transition:all 40s linear}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-viewport__iframe-wrapper{max-width:calc(100vw - 16rem)}}.pl-c-viewport__iframe{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;width:100%;border:0;padding:0;margin:0;top:0;bottom:0;left:0;right:0;background-color:#fff;max-width:100vw;width:100%}.pl-c-viewport__iframe.is-ready{min-height:0}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-viewport__iframe{max-width:calc(100vw - 16rem)}}.pl-c-viewport__iframe.hay-mode{-webkit-transition:all 40s linear;transition:all 40s linear}.pl-c-viewport__resizer{position:absolute;right:0;top:0;bottom:0;width:14px;margin:0;height:100%;cursor:ew-resize}.pl-c-viewport__resizer-handle{margin:0;width:100%;height:100%;background-color:grey;-webkit-transition:opacity .1s ease-out;transition:opacity .1s ease-out;opacity:.05}.pl-c-viewport__resizer-handle:hover{opacity:.2}.pl-c-viewport__resizer-handle:active{cursor:move;opacity:.2}.vp-animate{-webkit-transition:width .8s ease-out;transition:width .8s ease-out}.pl-c-viewport-modal-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-width:100vw;position:relative}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-viewport-modal-wrapper{max-width:calc(100vw - 16rem)}}@media all and (min-width:42em) and (-ms-high-contrast:none),all and (min-width:42em) and (-ms-high-contrast:active){.pl-c-body--theme-sidebar .pl-c-viewport-modal-wrapper{margin-left:16rem}}.pl-c-viewport-size{margin:0;border:0;padding:.3rem .5rem .4rem;line-height:1;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-ms-flex-negative:0;flex-shrink:0;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.pl-c-viewport-size__input{padding:.1rem;margin:0;border:0;border-radius:3px;background-color:transparent;font-size:.8rem;color:inherit;width:2.4rem;text-align:right;-webkit-transition:all .1s ease-out;transition:all .1s ease-out;pointer-events:none}.pl-c-viewport-size__input::-moz-focus-inner{padding:0;border:0}.pl-c-viewport-size__input:hover{color:#fff;background-color:#222}.pl-c-viewport-size__input:active,.pl-c-viewport-size__input:focus{color:#fff;background-color:#222;outline:1px dotted grey;outline-offset:-1px}.pl-c-viewport-size__label{display:block;margin:0;padding:0;font-size:.7rem;pointer-events:none}.pl-c-size-list{display:none;list-style:none;margin:0;padding:0;overflow-x:auto;padding:0 .25rem}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-size-list{padding-bottom:.5rem}}@media all and (min-width:42em){.pl-c-size-list{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-overflow-scrolling:touch}}@media all and (min-width:42em){.pl-c-size-list{display:block;display:-webkit-box;display:-ms-flexbox;display:flex}}.pl-c-size-list__action{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:inherit;text-decoration:none;line-height:1;padding:.7rem .5rem;border:0;text-align:left;-webkit-transition:background-color .1s ease-out,color .1s ease-out;transition:background-color .1s ease-out,color .1s ease-out;cursor:pointer;outline:0;padding-left:.3rem;padding-right:.3rem}.pl-c-size-list__action.pl-is-active:hover,.pl-c-size-list__action:hover{background-color:rgba(0,0,0,.1)}.pl-c-body--theme-density-cozy .pl-c-size-list__action{font-size:.85rem;padding:1.2rem .8rem}.pl-c-body--theme-density-comfortable .pl-c-size-list__action{font-size:.85rem;padding:1.5rem 1rem}.pl-c-size-list__item:first-child{margin-left:auto}.pl-c-size-list__item:last-child{margin-right:auto}.pl-has-annotation{cursor:help!important;outline:1px dotted grey;outline-offset:-4px;-webkit-transition:-webkit-box-shadow .1s ease;transition:-webkit-box-shadow .1s ease;transition:box-shadow .1s ease;transition:box-shadow .1s ease, -webkit-box-shadow .1s ease}.pl-has-annotation a,.pl-has-annotation input{cursor:help!important}.pl-has-annotation:hover{-webkit-box-shadow:0 0 3px grey;box-shadow:0 0 3px grey}.pl-has-annotation.active{-webkit-box-shadow:inset 0 0 6px #4d4c4c;box-shadow:inset 0 0 6px #4d4c4c;outline:1px dotted grey;outline-offset:-1px}.pl-c-annotation-tip{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:24px!important;height:24px!important;margin-top:6px!important;margin-left:6px!important;border-radius:50%!important;background-color:#222!important;color:#fff!important;font-size:16px!important;position:absolute;z-index:100}.pl-c-annotations{margin:1rem 0}.pl-c-annotations__title{font-size:1.2rem!important;margin:0 0 .5rem}.pl-c-annotations .pl-c-annotations__list{counter-reset:the-count;padding:0;margin:0;list-style:none}.pl-c-annotations__item{position:relative;padding-left:1.5rem;margin-bottom:1rem;border-radius:6px;-webkit-transition:background-color .1s ease;transition:background-color .1s ease}.pl-c-annotations__item:before{content:counter(the-count);counter-increment:the-count;font-size:85%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:14px;height:14px;border-radius:50%;padding:2px;text-align:center;background-color:grey;color:#fff;position:absolute;top:4px;left:0}.pl-c-annotations__item.pl-is-active{outline:1px dotted grey;outline-offset:-1px}.pl-c-annotations .pl-c-annotations__item-title{margin-bottom:0}.pl-c-breadcrumb{list-style:none;margin:0;padding:0;margin-bottom:.5rem;display:-webkit-box;display:-ms-flexbox;display:flex;font-size:.9rem;color:grey;text-transform:capitalize}.pl-c-breadcrumb__item:after{content:'\25B6';opacity:.4;font-size:6px;display:inline-block;margin:0 .2rem;position:relative;top:-1px}.pl-c-category{margin-top:6rem;font:"Open Sans",HelveticaNeue,Helvetica,Arial,sans-serif!important}.pl-c-category:first-of-type{margin-top:2rem}.pl-c-category__title{font-size:1.4rem!important;color:#222!important;margin:0 0 .2rem;text-transform:capitalize}.pl-c-category__title-link{-webkit-transition:color .1s ease-out;transition:color .1s ease-out}.pl-c-category__description{font-size:.85rem;line-height:1.5;max-width:30rem}.pl-c-category__description:empty{display:none}.pl-c-pattern-info{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}@media all and (min-width:53em){.pl-c-pattern-info{display:-webkit-box;display:-ms-flexbox;display:flex}}.pl-c-pattern .pl-c-pattern-info{max-height:20rem;min-height:18rem;overflow:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-overflow-scrolling:touch}.pl-c-pattern .pl-c-pattern-info::-webkit-scrollbar{width:0!important}@media all and (min-width:53em){.pl-c-pattern .pl-c-pattern-info{max-height:none;height:18rem;overflow:visible}}.pl-c-drawer .pl-c-pattern-info{position:absolute;top:0;right:.8rem;bottom:0;left:0;overflow:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;-webkit-overflow-scrolling:touch;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.pl-c-drawer .pl-c-pattern-info::-webkit-scrollbar{width:0!important}@supports (padding:env(safe-area-inset-right)){.pl-c-drawer .pl-c-pattern-info{right:calc(env(safe-area-inset-right) + .8rem)}}@media all and (min-width:53em){.pl-c-drawer .pl-c-pattern-info{position:static;overflow:visible}}.pl-c-pattern-info__panel{padding:1rem;width:100%}@media all and (min-width:53em){.pl-c-pattern-info__panel{-webkit-box-flex:1;-ms-flex:auto;flex:auto;position:absolute;top:0;bottom:0;left:0;right:0}}.pl-c-drawer .pl-c-pattern-info__panel{padding-right:1.3rem}@supports (padding:env(safe-area-inset-right)){.pl-c-drawer .pl-c-pattern-info__panel{padding-right:calc(env(safe-area-inset-right) + 1.3rem)}}.pl-c-pattern-info__panel--info{padding-top:2rem}@media all and (min-width:53em){.pl-c-pattern-info__panel--info{left:0;right:50%;overflow:auto;-ms-overflow-style:-ms-autohiding-scrollbar;-webkit-overflow-scrolling:touch}.pl-c-pattern-info__panel--info::-webkit-scrollbar{width:0!important}}@media all and (min-width:62em){.pl-c-pattern-info__panel--info{right:55%}}@media all and (min-width:53em){.pl-c-pattern-info__panel--info+.pl-c-pattern-info__panel--code{right:0;left:50%;top:1.2rem}}@media all and (min-width:62em){.pl-c-pattern-info__panel--info+.pl-c-pattern-info__panel--code{left:45%}}.pl-c-pattern-info__header{margin-bottom:.5rem}.pl-c-pattern-info__title{font-size:1.4rem!important;font-weight:400;margin-top:0;margin-bottom:0;color:inherit;text-transform:capitalize;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.pl-c-pattern-info__description{border-bottom-color:grey}.pl-c-annotations{border-top-color:grey}.pl-c-lineage{font-size:.85rem;line-height:1.7;margin-top:0}.pl-c-lineage__link{font-style:italic;color:grey;text-decoration:underline;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.pl-c-lineage__link:focus,.pl-c-lineage__link:hover{opacity:.8}.pl-c-pattern-state{display:inline-block;width:5px;height:5px;margin-left:10px;position:relative;top:5px;left:0;border-radius:50%;background-color:#02a4d5;line-height:4px;text-indent:10px}.pl-c-pattern-state--complete{background-color:#03790f}.pl-c-pattern-state--inreview{background-color:#c7a118}.pl-c-pattern-state--deprecated{background-color:#b00b02}.complete:before{color:#03790f!important}.pl-c-pattern{margin-bottom:2rem;position:relative;clear:both}.pl-c-pattern__header{position:relative;padding:.5rem 0 0;line-height:1.3;font-size:90%;color:grey}.pl-c-pattern__header:empty{padding:0}.pl-c-pattern__title{font-family:"Open Sans",HelveticaNeue,Helvetica,Arial,sans-serif!important;font-size:.85rem!important;line-height:1!important;font-weight:400!important;margin:0!important;padding:0!important;text-transform:capitalize!important}.pl-c-pattern__title-link{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;padding:1rem 0 .3rem;color:grey!important;text-decoration:none;cursor:pointer}.pl-c-pattern__title-link:focus,.pl-c-pattern__title-link:hover{color:#000!important}.pl-c-pattern__extra-toggle{font-size:9px;position:absolute;bottom:-1px;right:0;z-index:1;padding:.65em .65em .5em;line-height:1;color:grey;background-color:transparent;font-weight:400;border:1px solid #ddd;border-top-left-radius:6px;border-top-right-radius:6px;-webkit-transition:background-color .1s ease-out;transition:background-color .1s ease-out}.pl-c-pattern__extra-toggle .pl-c-pattern__toggle-icon{display:inline-block}.pl-c-pattern__extra-toggle.pl-is-active,.pl-c-pattern__extra-toggle:focus,.pl-c-pattern__extra-toggle:hover{background-color:#fafafa;color:#000}.pl-c-pattern__extra-toggle:focus{outline:1px dotted #4d4c4c}.pl-c-pattern__extra-toggle.pl-is-active{border-bottom-color:#fafafa}.pl-c-pattern__extra-toggle.pl-is-active .pl-c-pattern__toggle-icon{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.pl-c-pattern__extra{background-color:#fafafa;border-top:1px solid #ddd;margin-bottom:1rem;overflow:hidden;max-height:1px;position:relative;-webkit-transition:all .1s ease-out;transition:all .1s ease-out}.pl-c-pattern__extra.pl-is-active{border:1px solid #ddd;border-radius:6px;border-top-right-radius:0;max-height:150rem}.pl-c-tabs{padding:0 .5rem .5rem;background-color:#fff;border:1px solid #ddd;border-radius:6px;font-family:"Open Sans",HelveticaNeue,Helvetica,Arial,sans-serif;position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;overflow:hidden;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.pl-c-pattern-info__panel--code .pl-c-tabs{position:absolute;top:1rem;bottom:1rem;left:1rem;right:1rem}@media all and (min-width:42em){.pl-c-drawer .pl-c-tabs{right:1.5rem}@supports (padding:max(0px,env(safe-area-inset-right))){.pl-c-drawer .pl-c-tabs{right:max(1.5rem,env(safe-area-inset-right))}}}@media all and (min-width:848px){.pl-c-drawer .pl-c-tabs{right:2.3rem}@supports (padding:max(0px,env(safe-area-inset-right))){.pl-c-drawer .pl-c-tabs{right:max(2.3rem,calc(env(safe-area-inset-right) + 1.4rem))}}}@media all and (min-width:62em){.pl-c-drawer .pl-c-tabs{left:2rem}}.pl-c-tabs__list{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;list-style:none;margin:0;padding:.5rem 0;background-color:#fff}.pl-c-tabs__link{display:block;line-height:1;padding:.2rem .4rem;border:1px solid transparent;border-radius:6px;color:grey;background-color:#fff;cursor:pointer;text-decoration:none;text-transform:lowercase;-webkit-transition:all .1s ease-out;transition:all .1s ease-out}.pl-c-tabs__link:hover{color:#222}.pl-c-tabs__link.pl-is-active-tab{color:#222;background-color:#eee;border:1px solid #ddd}.pl-c-tabs__content{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-ms-flex-negative:1;flex-shrink:1;-ms-flex-preferred-size:0;flex-basis:0;overflow:hidden;-webkit-overflow-scrolling:touch;height:100%}.pl-c-drawer .pl-c-tabs__content{border:0}.pl-c-tabs__panel{display:none;min-height:12rem;height:100%}.pl-c-tabs__panel.pl-is-active-tab{display:block;display:-webkit-box;display:-ms-flexbox;display:flex}.pl-c-tabs__panel :not(pre)>code[class*=language-],.pl-c-tabs__panel pre[class*=language-]{background-color:transparent;margin:0;padding:0;border:0;display:block;width:100%}.pl-c-tabs__panel code[class*=language-]{background-color:transparent;margin:0}.pl-c-text-passage{font-size:.85rem;line-height:1.7}.pl-c-text-passage p{margin-top:0;margin-bottom:1rem}.pl-c-text-passage a{color:grey;text-decoration:underline;-webkit-transition:opacity .1s ease;transition:opacity .1s ease}.pl-c-text-passage a:focus,.pl-c-text-passage a:hover{opacity:.8}.pl-c-text-passage code[class*=language-],.pl-c-text-passage pre[class*=language-]{color:inherit}.pl-c-text-passage blockquote{padding-left:.8rem;border-left:3px solid inherit}.pl-c-text-passage hr{height:1px;background-color:grey;margin:2rem 0;border:0}.pl-c-text-passage h1{margin-bottom:1rem;font-weight:400}.pl-c-text-passage h2{margin:1rem 0 1rem;font-weight:400}.pl-c-text-passage h3{margin:1rem 0 1rem;font-weight:400}.pl-c-text-passage h4{margin:1rem 0 1rem;font-weight:400}.pl-c-text-passage h5{margin:1rem 0 1rem;font-weight:400}.pl-c-text-passage h6{margin:1rem 0 1rem;font-weight:400}.pl-c-text-passage ul{list-style:square;margin-left:.9rem;margin-bottom:1rem}.pl-c-text-passage ul li:last-child{margin-bottom:0}.pl-c-text-passage ol{list-style:decimal;margin-left:.9rem;margin-bottom:1rem}.pl-c-text-passage ol li:last-child{margin-bottom:0}.pl-c-text-passage li{margin-bottom:.5rem}.pl-c-body--theme-light .pl-c-header{background-color:#fff;border-bottom:1px solid #ccc}@media all and (max-width:41em){.pl-c-body--theme-light .pl-c-tools__list.pl-is-active{border-bottom:1px solid #ccc;border-left:1px solid #ccc}}.pl-c-body--theme-light:not(.pl-c-body--theme-sidebar) .pl-c-tools__list.pl-is-active{border-bottom:1px solid #ccc;border-left:1px solid #ccc}.pl-c-body--theme-light .pl-c-nav__link--dropdown{color:inherit}.pl-c-body--theme-light .pl-c-nav__link--dropdown:after{color:inherit}@media all and (min-width:42em){.pl-c-body--theme-light .pl-c-nav__sublist>.pl-c-nav__item:last-child .pl-c-nav__link{border-bottom-left-radius:6px;border-bottom-right-radius:6px}}.pl-c-body--theme-light .pl-c-viewport-size__input{color:#4d4c4c}.pl-c-body--theme-light .pl-c-viewport-size__input:focus,.pl-c-body--theme-light .pl-c-viewport-size__input:hover{background-color:#ddd}.pl-c-body--theme-light .typeahead{background-color:#ddd!important}.pl-c-body--theme-light .tt-input{background-color:#eee!important;color:#4d4c4c!important}.pl-c-body--theme-light .tt-input:hover{color:#222;background-color:#ddd!important}.pl-c-body--theme-light .tt-input:hover::-webkit-input-placeholder{color:#222}.pl-c-body--theme-light .tt-input:hover::-moz-input-placeholder{color:#222}.pl-c-body--theme-light .pl-c-drawer{background-color:#fff;color:#4d4c4c;border-top:1px solid #ccc}.pl-c-body--theme-light .pl-c-drawer__close-btn,.pl-c-body--theme-light .pl-c-tools__action{background-color:#fff}.pl-c-body--theme-light .pl-c-drawer__close-btn:focus,.pl-c-body--theme-light .pl-c-drawer__close-btn:hover,.pl-c-body--theme-light .pl-c-tools__action:focus,.pl-c-body--theme-light .pl-c-tools__action:hover{background-color:#eee;color:#4d4c4c}.pl-c-body--theme-density-cozy .pl-c-header{font-size:.85rem}.pl-c-body--theme-density-cozy .pl-c-viewport-size__input{width:44px}.pl-c-body--theme-density-cozy .pl-c-typeahead{padding:.9rem .8rem}@media all and (max-width:78em){.pl-c-body--theme-density-cozy .pl-c-size-list{display:none}}@media all and (max-width:78em){.pl-c-body--theme-density-cozy .pl-c-viewport-size{display:none}}.pl-c-body--theme-density-cozy .pl-c-tools__toggle{min-width:44px}.pl-c-body--theme-density-cozy .pl-c-viewport{top:3.28rem}.pl-c-body--theme-density-comfortable .pl-c-header{font-size:.85rem}.pl-c-body--theme-density-comfortable .pl-c-logo{max-width:4rem}.pl-c-body--theme-density-comfortable .pl-c-header .tt-suggestion{padding:1.5rem 1rem}.pl-c-body--theme-density-comfortable .pl-c-viewport-size__input{width:44px}.pl-c-body--theme-density-comfortable .pl-c-typeahead{padding:.9rem 1rem}@media all and (max-width:78em){.pl-c-body--theme-density-comfortable .pl-c-size-list{display:none}}@media all and (max-width:78em){.pl-c-body--theme-density-comfortable .pl-c-viewport-size{display:none}}.pl-c-body--theme-density-comfortable .pl-c-tools__toggle{min-width:44px}.pl-c-body--theme-density-comfortable .pl-c-viewport{top:3.8rem}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-header{width:16rem;height:100vh;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;border-bottom:0;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.pl-c-body--theme-sidebar .pl-c-nav{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-ms-flex-flow:column-reverse;flex-flow:column-reverse}.pl-c-body--theme-sidebar .pl-c-nav__list{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.pl-c-body--theme-sidebar .pl-c-nav__sublist{position:relative;border-radius:0}.pl-c-body--theme-sidebar.pl-c-body--theme-light .pl-c-nav__subsublist{border-left-color:#eee}.pl-c-body--theme-sidebar .pl-c-nav__sublist .pl-c-nav__link{border-left:0;border-right:0}}@media all and (min-width:42em) and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-nav__sublist>.pl-c-nav__item:last-child .pl-c-nav__link{border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom:0}}@media all and (min-width:42em){.pl-c-body--theme-sidebar .pl-c-controls{display:block;justify-self:flex-end;margin-left:0}.pl-c-body--theme-sidebar .pl-c-tools__toggle{display:none}.pl-c-body--theme-sidebar .pl-c-tools__list{max-height:none;overflow:visible;position:relative;border-radius:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%}.pl-c-body--theme-sidebar .pl-c-drawer{right:0;width:auto}}.is-vishidden{position:absolute!important;overflow:hidden;width:1px;height:1px;padding:0;border:0;clip:rect(1px,1px,1px,1px)} diff --git a/packages/uikit-workshop/dist/styleguide/images/pattern-lab-logo--on-dark.svg b/packages/uikit-workshop/dist/styleguide/images/pattern-lab-logo--on-dark.svg new file mode 100644 index 000000000..59cc46b0a --- /dev/null +++ b/packages/uikit-workshop/dist/styleguide/images/pattern-lab-logo--on-dark.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/uikit-workshop/dist/styleguide/images/pattern-lab-logo--on-light.svg b/packages/uikit-workshop/dist/styleguide/images/pattern-lab-logo--on-light.svg new file mode 100644 index 000000000..549f60c02 --- /dev/null +++ b/packages/uikit-workshop/dist/styleguide/images/pattern-lab-logo--on-light.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/uikit-workshop/dist/styleguide/js/0-chunk-bfab2102075df63da231.js b/packages/uikit-workshop/dist/styleguide/js/0-chunk-bfab2102075df63da231.js deleted file mode 100644 index 3b55ef3c4..000000000 --- a/packages/uikit-workshop/dist/styleguide/js/0-chunk-bfab2102075df63da231.js +++ /dev/null @@ -1,15 +0,0 @@ -(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[0],{ - -/***/ "./node_modules/@webcomponents/shadydom/src/shadydom.js": -/*!***************************************************************************!*\ - !*** ./node_modules/@webcomponents/shadydom/src/shadydom.js + 28 modules ***! - \***************************************************************************/ -/*! no exports provided */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/shady-data.js\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nvar ShadyData =\n/*#__PURE__*/\nfunction () {\n function ShadyData() {\n _classCallCheck(this, ShadyData);\n\n /** @type {ShadowRoot} */\n this.root = null;\n /** @type {ShadowRoot} */\n\n this.publicRoot = null;\n this.dirty = false;\n this.observer = null;\n /** @type {Array} */\n\n this.assignedNodes = null;\n /** @type {Element} */\n\n this.assignedSlot = null;\n /** @type {Array} */\n\n this._previouslyAssignedNodes = null;\n /** @type {Element} */\n\n this._prevAssignedSlot = null;\n /** @type {Array} */\n\n this.flattenedNodes = null;\n this.ownerShadyRoot = undefined;\n /** @type {Node|undefined} */\n\n this.parentNode = undefined;\n /** @type {Node|undefined} */\n\n this.firstChild = undefined;\n /** @type {Node|undefined} */\n\n this.lastChild = undefined;\n /** @type {Node|undefined} */\n\n this.previousSibling = undefined;\n /** @type {Node|undefined} */\n\n this.nextSibling = undefined;\n /** @type {Array|undefined} */\n\n this.childNodes = undefined;\n this.__outsideAccessors = false;\n this.__insideAccessors = false;\n this.__onCallbackListeners = {};\n }\n /** @override */\n\n\n _createClass(ShadyData, [{\n key: \"toJSON\",\n value: function toJSON() {\n return {};\n }\n }]);\n\n return ShadyData;\n}();\nfunction ensureShadyDataForNode(node) {\n if (!node.__shady) {\n node.__shady = new ShadyData();\n }\n\n return node.__shady;\n}\nfunction shadyDataForNode(node) {\n return node && node.__shady;\n}\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/utils.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n/** @type {!Object} */\n\nvar settings = window['ShadyDOM'] || {};\nsettings.hasNativeShadowDOM = Boolean(Element.prototype.attachShadow && Node.prototype.getRootNode);\nvar desc = Object.getOwnPropertyDescriptor(Node.prototype, 'firstChild');\nsettings.hasDescriptors = Boolean(desc && desc.configurable && desc.get);\nsettings.inUse = settings['force'] || !settings.hasNativeShadowDOM;\nsettings.noPatch = settings['noPatch'] || false;\nsettings.preferPerformance = settings['preferPerformance'];\nvar utils_isTrackingLogicalChildNodes = function isTrackingLogicalChildNodes(node) {\n var nodeData = shadyDataForNode(node);\n return nodeData && nodeData.firstChild !== undefined;\n};\nvar utils_isShadyRoot = function isShadyRoot(obj) {\n return Boolean(obj._localName === 'ShadyRoot');\n};\nvar utils_hasShadowRootWithSlot = function hasShadowRootWithSlot(node) {\n var nodeData = shadyDataForNode(node);\n var root = nodeData && nodeData.root;\n return root && root._hasInsertionPoint();\n};\nvar utils_p = Element.prototype;\nvar matches = utils_p.matches || utils_p.matchesSelector || utils_p.mozMatchesSelector || utils_p.msMatchesSelector || utils_p.oMatchesSelector || utils_p.webkitMatchesSelector;\nvar matchesSelector = function matchesSelector(element, selector) {\n return matches.call(element, selector);\n};\nvar mixin = function mixin(target, source) {\n for (var i in source) {\n target[i] = source[i];\n }\n\n return target;\n}; // NOTE, prefer MutationObserver over Promise for microtask timing\n// for consistency x-platform.\n\nvar twiddle = document.createTextNode('');\nvar utils_content = 0;\nvar queue = [];\nnew MutationObserver(function () {\n while (queue.length) {\n // catch errors in user code...\n try {\n queue.shift()();\n } catch (e) {\n // enqueue another record and throw\n twiddle.textContent = utils_content++;\n throw e;\n }\n }\n}).observe(twiddle, {\n characterData: true\n}); // use MutationObserver to get microtask async timing.\n\nvar microtask = function microtask(callback) {\n queue.push(callback);\n twiddle.textContent = utils_content++;\n};\nvar hasDocumentContains = Boolean(document.contains);\nvar utils_contains = function contains(container, node) {\n while (node) {\n if (node == container) {\n return true;\n }\n\n node = node[SHADY_PREFIX + 'parentNode'];\n }\n\n return false;\n};\n\nvar getNodeHTMLCollectionName = function getNodeHTMLCollectionName(node) {\n return node.getAttribute('id') || node.getAttribute('name');\n};\n\nvar isValidHTMLCollectionName = function isValidHTMLCollectionName(name) {\n return name !== 'length' && isNaN(name);\n};\n\nvar createPolyfilledHTMLCollection = function createPolyfilledHTMLCollection(nodes) {\n // Note: loop in reverse so that the first named item matches the named property\n for (var l = nodes.length - 1; l >= 0; l--) {\n var node = nodes[l];\n var name = getNodeHTMLCollectionName(node);\n\n if (name && isValidHTMLCollectionName(name)) {\n nodes[name] = node;\n }\n }\n\n nodes.item = function (index) {\n return nodes[index];\n };\n\n nodes.namedItem = function (name) {\n if (isValidHTMLCollectionName(name) && nodes[name]) {\n return nodes[name];\n }\n\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = nodes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var _node = _step.value;\n var nodeName = getNodeHTMLCollectionName(_node);\n\n if (nodeName == name) {\n return _node;\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return null;\n };\n\n return nodes;\n};\nvar NATIVE_PREFIX = '__shady_native_';\nvar SHADY_PREFIX = '__shady_';\n/**\n * Patch a group of accessors on an object only if it exists or if the `force`\n * argument is true.\n * @param {!Object} proto\n * @param {!Object} descriptors\n * @param {string=} prefix\n * @param {Array=} disallowedPatches\n */\n\nvar patchProperties = function patchProperties(proto, descriptors) {\n var prefix = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';\n var disallowedPatches = arguments.length > 3 ? arguments[3] : undefined;\n\n for (var _p in descriptors) {\n var newDescriptor = descriptors[_p];\n\n if (disallowedPatches && disallowedPatches.indexOf(_p) >= 0) {\n continue;\n }\n\n newDescriptor.configurable = true;\n var name = prefix + _p; // NOTE: we prefer writing directly because some browsers\n // have descriptors that are writable but not configurable (e.g.\n // `appendChild` on older browsers)\n\n if (newDescriptor.value) {\n proto[name] = newDescriptor.value;\n } else {\n // NOTE: this can throw if 'force' is used so catch the error.\n try {\n Object.defineProperty(proto, name, newDescriptor);\n } catch (e) {// this error is harmless so we just trap it.\n }\n }\n }\n};\n/** @type {!function(new:HTMLElement)} */\n\nvar NativeHTMLElement = window['customElements'] && window['customElements']['nativeHTMLElement'] || HTMLElement; // note, this is not a perfect polyfill since it doesn't include symbols\n\n/** @return {!Object} */\n\nvar getOwnPropertyDescriptors = function getOwnPropertyDescriptors(obj) {\n var descriptors = {};\n Object.getOwnPropertyNames(obj).forEach(function (name) {\n descriptors[name] = Object.getOwnPropertyDescriptor(obj, name);\n });\n return descriptors;\n};\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/flush.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n // render enqueuer/flusher\n\nvar flushList = [];\nvar scheduled;\nfunction enqueue(callback) {\n if (!scheduled) {\n scheduled = true;\n microtask(flush);\n }\n\n flushList.push(callback);\n}\nfunction flush() {\n scheduled = false;\n var didFlush = Boolean(flushList.length);\n\n while (flushList.length) {\n flushList.shift()();\n }\n\n return didFlush;\n}\nflush['list'] = flushList;\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/observe-changes.js\nfunction observe_changes_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction observe_changes_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction observe_changes_createClass(Constructor, protoProps, staticProps) { if (protoProps) observe_changes_defineProperties(Constructor.prototype, protoProps); if (staticProps) observe_changes_defineProperties(Constructor, staticProps); return Constructor; }\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n\nvar observe_changes_AsyncObserver =\n/*#__PURE__*/\nfunction () {\n function AsyncObserver() {\n observe_changes_classCallCheck(this, AsyncObserver);\n\n this._scheduled = false;\n this.addedNodes = [];\n this.removedNodes = [];\n this.callbacks = new Set();\n }\n\n observe_changes_createClass(AsyncObserver, [{\n key: \"schedule\",\n value: function schedule() {\n var _this = this;\n\n if (!this._scheduled) {\n this._scheduled = true;\n microtask(function () {\n _this.flush();\n });\n }\n }\n }, {\n key: \"flush\",\n value: function flush() {\n if (this._scheduled) {\n this._scheduled = false;\n var mutations = this.takeRecords();\n\n if (mutations.length) {\n this.callbacks.forEach(function (cb) {\n cb(mutations);\n });\n }\n }\n }\n }, {\n key: \"takeRecords\",\n value: function takeRecords() {\n if (this.addedNodes.length || this.removedNodes.length) {\n var mutations = [{\n addedNodes: this.addedNodes,\n removedNodes: this.removedNodes\n }];\n this.addedNodes = [];\n this.removedNodes = [];\n return mutations;\n }\n\n return [];\n }\n }]);\n\n return AsyncObserver;\n}(); // TODO(sorvell): consider instead polyfilling MutationObserver\n// directly so that users do not have to fork their code.\n// Supporting the entire api may be challenging: e.g. filtering out\n// removed nodes in the wrong scope and seeing non-distributing\n// subtree child mutations.\n\n\nvar observe_changes_observeChildren = function observeChildren(node, callback) {\n var sd = ensureShadyDataForNode(node);\n\n if (!sd.observer) {\n sd.observer = new observe_changes_AsyncObserver();\n }\n\n sd.observer.callbacks.add(callback);\n var observer = sd.observer;\n return {\n _callback: callback,\n _observer: observer,\n _node: node,\n takeRecords: function takeRecords() {\n return observer.takeRecords();\n }\n };\n};\nvar observe_changes_unobserveChildren = function unobserveChildren(handle) {\n var observer = handle && handle._observer;\n\n if (observer) {\n observer.callbacks.delete(handle._callback);\n\n if (!observer.callbacks.size) {\n ensureShadyDataForNode(handle._node).observer = null;\n }\n }\n};\nfunction filterMutations(mutations, target) {\n /** @const {Node} */\n var targetRootNode = target.getRootNode();\n return mutations.map(function (mutation) {\n /** @const {boolean} */\n var mutationInScope = targetRootNode === mutation.target.getRootNode();\n\n if (mutationInScope && mutation.addedNodes) {\n var nodes = Array.from(mutation.addedNodes).filter(function (n) {\n return targetRootNode === n.getRootNode();\n });\n\n if (nodes.length) {\n mutation = Object.create(mutation);\n Object.defineProperty(mutation, 'addedNodes', {\n value: nodes,\n configurable: true\n });\n return mutation;\n }\n } else if (mutationInScope) {\n return mutation;\n }\n }).filter(function (m) {\n return m;\n });\n}\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/innerHTML.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n// Cribbed from ShadowDOM polyfill\n// https://github.com/webcomponents/webcomponentsjs/blob/master/src/ShadowDOM/wrappers/HTMLElement.js#L28\n/////////////////////////////////////////////////////////////////////////////\n// innerHTML and outerHTML\n// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#escapingString\nvar escapeAttrRegExp = /[&\\u00A0\"]/g;\nvar escapeDataRegExp = /[&\\u00A0<>]/g;\n\nfunction escapeReplace(c) {\n switch (c) {\n case '&':\n return '&';\n\n case '<':\n return '<';\n\n case '>':\n return '>';\n\n case '\"':\n return '"';\n\n case \"\\xA0\":\n return ' ';\n }\n}\n\nfunction escapeAttr(s) {\n return s.replace(escapeAttrRegExp, escapeReplace);\n}\n\nfunction escapeData(s) {\n return s.replace(escapeDataRegExp, escapeReplace);\n}\n\nfunction makeSet(arr) {\n var set = {};\n\n for (var i = 0; i < arr.length; i++) {\n set[arr[i]] = true;\n }\n\n return set;\n} // http://www.whatwg.org/specs/web-apps/current-work/#void-elements\n\n\nvar voidElements = makeSet(['area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr']);\nvar plaintextParents = makeSet(['style', 'script', 'xmp', 'iframe', 'noembed', 'noframes', 'plaintext', 'noscript']);\n/**\n * @param {Node} node\n * @param {Node} parentNode\n * @param {Function=} callback\n */\n\nfunction getOuterHTML(node, parentNode, callback) {\n switch (node.nodeType) {\n case Node.ELEMENT_NODE:\n {\n var tagName = node.localName;\n var s = '<' + tagName;\n var attrs = node.attributes;\n\n for (var i = 0, attr; attr = attrs[i]; i++) {\n s += ' ' + attr.name + '=\"' + escapeAttr(attr.value) + '\"';\n }\n\n s += '>';\n\n if (voidElements[tagName]) {\n return s;\n }\n\n return s + getInnerHTML(node, callback) + '';\n }\n\n case Node.TEXT_NODE:\n {\n var data =\n /** @type {Text} */\n node.data;\n\n if (parentNode && plaintextParents[parentNode.localName]) {\n return data;\n }\n\n return escapeData(data);\n }\n\n case Node.COMMENT_NODE:\n {\n return '';\n }\n\n default:\n {\n window.console.error(node);\n throw new Error('not implemented');\n }\n }\n}\n/**\n * @param {Node} node\n * @param {Function=} callback\n */\n\nfunction getInnerHTML(node, callback) {\n if (node.localName === 'template') {\n node =\n /** @type {HTMLTemplateElement} */\n node.content;\n }\n\n var s = '';\n var c$ = callback ? callback(node) : node.childNodes;\n\n for (var i = 0, l = c$.length, child; i < l && (child = c$[i]); i++) {\n s += getOuterHTML(child, node, callback);\n }\n\n return s;\n}\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patch-native.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n\nvar hasDescriptors = settings.hasDescriptors;\nvar patch_native_NATIVE_PREFIX = NATIVE_PREFIX; // Object on which raw native methods are stored.\n// e.g. `nativeMethods.querySelector.call(node, selector)`\n// same as `node.querySelector(selector)`\n\nvar nativeMethods = {\n /** @this {Element} */\n querySelector: function querySelector(selector) {\n return this[patch_native_NATIVE_PREFIX + 'querySelector'](selector);\n },\n\n /** @this {Element} */\n querySelectorAll: function querySelectorAll(selector) {\n return this[patch_native_NATIVE_PREFIX + 'querySelectorAll'](selector);\n }\n}; // Object on which raw native accessors are available via `accessorName(node)`.\n// e.g. `nativeTree.firstChild(node)`\n// same as `node.firstChild`\n\nvar nativeTree = {};\n\nvar installNativeAccessor = function installNativeAccessor(name) {\n nativeTree[name] = function (node) {\n return node[patch_native_NATIVE_PREFIX + name];\n };\n};\n\nvar installNativeMethod = function installNativeMethod(name, fn) {\n if (!nativeMethods[name]) {\n nativeMethods[name] = fn;\n }\n};\n\nvar patch_native_defineNativeAccessors = function defineNativeAccessors(proto, descriptors) {\n patchProperties(proto, descriptors, patch_native_NATIVE_PREFIX); // make native accessors available to users\n\n for (var prop in descriptors) {\n installNativeAccessor(prop);\n }\n};\n\nvar copyProperties = function copyProperties(proto) {\n var list = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];\n\n for (var i = 0; i < list.length; i++) {\n var name = list[i];\n var descriptor = Object.getOwnPropertyDescriptor(proto, name);\n\n if (descriptor) {\n Object.defineProperty(proto, patch_native_NATIVE_PREFIX + name, descriptor); // make native methods/accessors available to users\n\n if (descriptor.value) {\n installNativeMethod(name, descriptor.value);\n } else {\n installNativeAccessor(name);\n }\n }\n }\n};\n/** @type {!TreeWalker} */\n\n\nvar nodeWalker = document.createTreeWalker(document, NodeFilter.SHOW_ALL, null, false);\n/** @type {!TreeWalker} */\n\nvar elementWalker = document.createTreeWalker(document, NodeFilter.SHOW_ELEMENT, null, false);\n/** @type {!Document} */\n\nvar inertDoc = document.implementation.createHTMLDocument('inert');\n\nvar clearNode = function clearNode(node) {\n var firstChild;\n\n while (firstChild = node[patch_native_NATIVE_PREFIX + 'firstChild']) {\n node[patch_native_NATIVE_PREFIX + 'removeChild'](firstChild);\n }\n};\n\nvar ParentNodeAccessors = ['firstElementChild', 'lastElementChild', 'children', 'childElementCount'];\nvar ParentNodeMethods = ['querySelector', 'querySelectorAll' // 'append', 'prepend'\n];\nvar patch_native_addNativePrefixedProperties = function addNativePrefixedProperties() {\n // EventTarget\n var eventProps = ['dispatchEvent', 'addEventListener', 'removeEventListener'];\n\n if (window.EventTarget) {\n copyProperties(window.EventTarget.prototype, eventProps);\n } else {\n copyProperties(Node.prototype, eventProps);\n copyProperties(Window.prototype, eventProps);\n } // Node\n\n\n if (hasDescriptors) {\n copyProperties(Node.prototype, ['parentNode', 'firstChild', 'lastChild', 'previousSibling', 'nextSibling', 'childNodes', 'parentElement', 'textContent']);\n } else {\n patch_native_defineNativeAccessors(Node.prototype, {\n parentNode: {\n /** @this {Node} */\n get: function get() {\n nodeWalker.currentNode = this;\n return nodeWalker.parentNode();\n }\n },\n firstChild: {\n /** @this {Node} */\n get: function get() {\n nodeWalker.currentNode = this;\n return nodeWalker.firstChild();\n }\n },\n lastChild: {\n /** @this {Node} */\n get: function get() {\n nodeWalker.currentNode = this;\n return nodeWalker.lastChild();\n }\n },\n previousSibling: {\n /** @this {Node} */\n get: function get() {\n nodeWalker.currentNode = this;\n return nodeWalker.previousSibling();\n }\n },\n nextSibling: {\n /** @this {Node} */\n get: function get() {\n nodeWalker.currentNode = this;\n return nodeWalker.nextSibling();\n }\n },\n // TODO(sorvell): make this a NodeList or whatever\n childNodes: {\n /** @this {Node} */\n get: function get() {\n var nodes = [];\n nodeWalker.currentNode = this;\n var n = nodeWalker.firstChild();\n\n while (n) {\n nodes.push(n);\n n = nodeWalker.nextSibling();\n }\n\n return nodes;\n }\n },\n parentElement: {\n /** @this {Node} */\n get: function get() {\n elementWalker.currentNode = this;\n return elementWalker.parentNode();\n }\n },\n textContent: {\n /** @this {Node} */\n get: function get() {\n /* eslint-disable no-case-declarations */\n switch (this.nodeType) {\n case Node.ELEMENT_NODE:\n case Node.DOCUMENT_FRAGMENT_NODE:\n // TODO(sorvell): This cannot be a single TreeWalker that's reused\n // at least for Safari 9, but it's unclear why.\n var textWalker = document.createTreeWalker(this, NodeFilter.SHOW_TEXT, null, false);\n var content = '',\n n;\n\n while (n = textWalker.nextNode()) {\n // TODO(sorvell): can't use textContent since we patch it on Node.prototype!\n // However, should probably patch it only on element.\n content += n.nodeValue;\n }\n\n return content;\n\n default:\n return this.nodeValue;\n }\n },\n // Needed on browsers that do not proper accessors (e.g. old versions of Chrome)\n\n /** @this {Node} */\n set: function set(value) {\n if (typeof value === 'undefined' || value === null) {\n value = '';\n }\n\n switch (this.nodeType) {\n case Node.ELEMENT_NODE:\n case Node.DOCUMENT_FRAGMENT_NODE:\n clearNode(this); // Document fragments must have no childnodes if setting a blank string\n\n if (value.length > 0 || this.nodeType === Node.ELEMENT_NODE) {\n // Note: old Chrome versions require 2nd argument here\n this[patch_native_NATIVE_PREFIX + 'insertBefore'](document.createTextNode(value), undefined);\n }\n\n break;\n\n default:\n // TODO(sorvell): can't do this if patch nodeValue.\n this.nodeValue = value;\n break;\n }\n }\n }\n });\n }\n\n copyProperties(Node.prototype, ['appendChild', 'insertBefore', 'removeChild', 'replaceChild', 'cloneNode', 'contains']);\n var ParentNodeWalkerDescriptors = {\n firstElementChild: {\n /** @this {ParentNode} */\n get: function get() {\n elementWalker.currentNode = this;\n return elementWalker.firstChild();\n }\n },\n lastElementChild: {\n /** @this {ParentNode} */\n get: function get() {\n elementWalker.currentNode = this;\n return elementWalker.lastChild();\n }\n },\n children: {\n /** @this {ParentNode} */\n get: function get() {\n var nodes = [];\n elementWalker.currentNode = this;\n var n = elementWalker.firstChild();\n\n while (n) {\n nodes.push(n);\n n = elementWalker.nextSibling();\n }\n\n return createPolyfilledHTMLCollection(nodes);\n }\n },\n childElementCount: {\n /** @this {ParentNode} */\n get: function get() {\n if (this.children) {\n return this.children.length;\n }\n\n return 0;\n }\n }\n }; // Element\n\n if (hasDescriptors) {\n copyProperties(Element.prototype, ParentNodeAccessors);\n copyProperties(Element.prototype, ['previousElementSibling', 'nextElementSibling', 'innerHTML']); // NOTE, on IE 11 / Edge 15 children and/or innerHTML are on HTMLElement instead of Element\n\n if (Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'children')) {\n copyProperties(HTMLElement.prototype, ['children']);\n }\n\n if (Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'innerHTML')) {\n copyProperties(HTMLElement.prototype, ['innerHTML']);\n }\n } else {\n patch_native_defineNativeAccessors(Element.prototype, ParentNodeWalkerDescriptors);\n patch_native_defineNativeAccessors(Element.prototype, {\n previousElementSibling: {\n /** @this {Element} */\n get: function get() {\n elementWalker.currentNode = this;\n return elementWalker.previousSibling();\n }\n },\n nextElementSibling: {\n /** @this {Element} */\n get: function get() {\n elementWalker.currentNode = this;\n return elementWalker.nextSibling();\n }\n },\n innerHTML: {\n /** @this {Element} */\n get: function get() {\n return getInnerHTML(this, function (n) {\n return n[patch_native_NATIVE_PREFIX + 'childNodes'];\n });\n },\n // Needed on browsers that do not proper accessors (e.g. old versions of Chrome)\n\n /** @this {Element} */\n set: function set(value) {\n var content = this.localName === 'template' ?\n /** @type {HTMLTemplateElement} */\n this.content : this;\n clearNode(content);\n var containerName = this.localName || 'div';\n var htmlContainer;\n\n if (!this.namespaceURI || this.namespaceURI === inertDoc.namespaceURI) {\n htmlContainer = inertDoc.createElement(containerName);\n } else {\n htmlContainer = inertDoc.createElementNS(this.namespaceURI, containerName);\n }\n\n htmlContainer.innerHTML = value;\n var newContent = this.localName === 'template' ?\n /** @type {HTMLTemplateElement} */\n htmlContainer.content : htmlContainer;\n var firstChild;\n\n while (firstChild = newContent[patch_native_NATIVE_PREFIX + 'firstChild']) {\n // Note: old Chrome versions require 2nd argument here\n content[patch_native_NATIVE_PREFIX + 'insertBefore'](firstChild, undefined);\n }\n }\n }\n });\n }\n\n copyProperties(Element.prototype, ['setAttribute', 'getAttribute', 'hasAttribute', 'removeAttribute', // on older Safari, these are on Element.\n 'focus', 'blur']);\n copyProperties(Element.prototype, ParentNodeMethods); // HTMLElement\n\n copyProperties(HTMLElement.prototype, ['focus', 'blur', // On IE these are on HTMLElement\n 'contains']);\n\n if (hasDescriptors) {\n copyProperties(HTMLElement.prototype, ['parentElement', 'children', 'innerHTML']);\n } // HTMLTemplateElement\n\n\n if (window.HTMLTemplateElement) {\n copyProperties(window.HTMLTemplateElement.prototype, ['innerHTML']);\n } // DocumentFragment\n\n\n if (hasDescriptors) {\n // NOTE, IE 11 does not have on DocumentFragment\n // firstElementChild\n // lastElementChild\n copyProperties(DocumentFragment.prototype, ParentNodeAccessors);\n } else {\n patch_native_defineNativeAccessors(DocumentFragment.prototype, ParentNodeWalkerDescriptors);\n }\n\n copyProperties(DocumentFragment.prototype, ParentNodeMethods); // Document\n\n if (hasDescriptors) {\n copyProperties(Document.prototype, ParentNodeAccessors);\n copyProperties(Document.prototype, ['activeElement']);\n } else {\n patch_native_defineNativeAccessors(Document.prototype, ParentNodeWalkerDescriptors);\n }\n\n copyProperties(Document.prototype, ['importNode', 'getElementById']);\n copyProperties(Document.prototype, ParentNodeMethods);\n};\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patch-instances.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\nvar InsideDescriptors = getOwnPropertyDescriptors({\n /** @this {Node} */\n get childNodes() {\n return this[SHADY_PREFIX + 'childNodes'];\n },\n\n /** @this {Node} */\n get firstChild() {\n return this[SHADY_PREFIX + 'firstChild'];\n },\n\n /** @this {Node} */\n get lastChild() {\n return this[SHADY_PREFIX + 'lastChild'];\n },\n\n /** @this {Node} */\n get textContent() {\n return this[SHADY_PREFIX + 'textContent'];\n },\n\n /** @this {Node} */\n set textContent(value) {\n this[SHADY_PREFIX + 'textContent'] = value;\n },\n\n /** @this {Node} */\n get childElementCount() {\n return this[SHADY_PREFIX + 'childElementCount'];\n },\n\n /** @this {Node} */\n get children() {\n return this[SHADY_PREFIX + 'children'];\n },\n\n /** @this {Node} */\n get firstElementChild() {\n return this[SHADY_PREFIX + 'firstElementChild'];\n },\n\n /** @this {Node} */\n get lastElementChild() {\n return this[SHADY_PREFIX + 'lastElementChild'];\n },\n\n /** @this {Node} */\n get innerHTML() {\n return this[SHADY_PREFIX + 'innerHTML'];\n },\n\n /** @this {Node} */\n set innerHTML(value) {\n return this[SHADY_PREFIX + 'innerHTML'] = value;\n },\n\n /** @this {Node} */\n get shadowRoot() {\n return this[SHADY_PREFIX + 'shadowRoot'];\n }\n\n});\nvar OutsideDescriptors = getOwnPropertyDescriptors({\n /** @this {Node} */\n get parentElement() {\n return this[SHADY_PREFIX + 'parentElement'];\n },\n\n /** @this {Node} */\n get parentNode() {\n return this[SHADY_PREFIX + 'parentNode'];\n },\n\n /** @this {Node} */\n get nextSibling() {\n return this[SHADY_PREFIX + 'nextSibling'];\n },\n\n /** @this {Node} */\n get previousSibling() {\n return this[SHADY_PREFIX + 'previousSibling'];\n },\n\n /** @this {Node} */\n get nextElementSibling() {\n return this[SHADY_PREFIX + 'nextElementSibling'];\n },\n\n /** @this {Node} */\n get previousElementSibling() {\n return this[SHADY_PREFIX + 'previousElementSibling'];\n },\n\n /** @this {Node} */\n get className() {\n return this[SHADY_PREFIX + 'className'];\n },\n\n /** @this {Node} */\n set className(value) {\n return this[SHADY_PREFIX + 'className'] = value;\n }\n\n});\n\nfor (var patch_instances_prop in InsideDescriptors) {\n InsideDescriptors[patch_instances_prop].enumerable = false;\n}\n\nfor (var _prop in OutsideDescriptors) {\n OutsideDescriptors[_prop].enumerable = false;\n}\n\nvar noInstancePatching = settings.hasDescriptors || settings.noPatch; // ensure an element has patched \"outside\" accessors; no-op when not needed\n\nvar patchOutsideElementAccessors = noInstancePatching ? function () {} : function (element) {\n var sd = ensureShadyDataForNode(element);\n\n if (!sd.__outsideAccessors) {\n sd.__outsideAccessors = true;\n patchProperties(element, OutsideDescriptors);\n }\n}; // ensure an element has patched \"inside\" accessors; no-op when not needed\n\nvar patchInsideElementAccessors = noInstancePatching ? function () {} : function (element) {\n var sd = ensureShadyDataForNode(element);\n\n if (!sd.__insideAccessors) {\n sd.__insideAccessors = true;\n patchProperties(element, InsideDescriptors);\n }\n};\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patch-events.js\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n/*\nMake this name unique so it is unlikely to conflict with properties on objects passed to `addEventListener`\nhttps://github.com/webcomponents/shadydom/issues/173\n*/\n\nvar\n/** string */\neventWrappersName = \"__eventWrappers\".concat(Date.now());\n/** @type {?function(!Event): boolean} */\n\nvar composedGetter = function () {\n var composedProp = Object.getOwnPropertyDescriptor(Event.prototype, 'composed');\n return composedProp ? function (ev) {\n return composedProp.get.call(ev);\n } : null;\n}(); // https://github.com/w3c/webcomponents/issues/513#issuecomment-224183937\n\n\nvar alwaysComposed = {\n 'blur': true,\n 'focus': true,\n 'focusin': true,\n 'focusout': true,\n 'click': true,\n 'dblclick': true,\n 'mousedown': true,\n 'mouseenter': true,\n 'mouseleave': true,\n 'mousemove': true,\n 'mouseout': true,\n 'mouseover': true,\n 'mouseup': true,\n 'wheel': true,\n 'beforeinput': true,\n 'input': true,\n 'keydown': true,\n 'keyup': true,\n 'compositionstart': true,\n 'compositionupdate': true,\n 'compositionend': true,\n 'touchstart': true,\n 'touchend': true,\n 'touchmove': true,\n 'touchcancel': true,\n 'pointerover': true,\n 'pointerenter': true,\n 'pointerdown': true,\n 'pointermove': true,\n 'pointerup': true,\n 'pointercancel': true,\n 'pointerout': true,\n 'pointerleave': true,\n 'gotpointercapture': true,\n 'lostpointercapture': true,\n 'dragstart': true,\n 'drag': true,\n 'dragenter': true,\n 'dragleave': true,\n 'dragover': true,\n 'drop': true,\n 'dragend': true,\n 'DOMActivate': true,\n 'DOMFocusIn': true,\n 'DOMFocusOut': true,\n 'keypress': true\n};\nvar unpatchedEvents = {\n 'DOMAttrModified': true,\n 'DOMAttributeNameChanged': true,\n 'DOMCharacterDataModified': true,\n 'DOMElementNameChanged': true,\n 'DOMNodeInserted': true,\n 'DOMNodeInsertedIntoDocument': true,\n 'DOMNodeRemoved': true,\n 'DOMNodeRemovedFromDocument': true,\n 'DOMSubtreeModified': true\n /**\n * Some EventTarget subclasses are not Node subclasses, and you cannot call\n * `getRootNode()` on them.\n *\n * @param {!(Node|EventTarget)} eventTarget\n * @return {!(Node|EventTarget)}\n */\n\n};\n\nfunction getRootNodeWithFallback(eventTarget) {\n if (eventTarget instanceof Node) {\n return eventTarget[SHADY_PREFIX + 'getRootNode']();\n } else {\n return eventTarget;\n }\n}\n\nfunction pathComposer(startNode, composed) {\n var composedPath = [];\n var current = startNode;\n var startRoot = getRootNodeWithFallback(startNode);\n\n while (current) {\n composedPath.push(current);\n\n if (current[SHADY_PREFIX + 'assignedSlot']) {\n current = current[SHADY_PREFIX + 'assignedSlot'];\n } else if (current.nodeType === Node.DOCUMENT_FRAGMENT_NODE && current.host && (composed || current !== startRoot)) {\n current = current.host;\n } else {\n current = current[SHADY_PREFIX + 'parentNode'];\n }\n } // event composedPath includes window when startNode's ownerRoot is document\n\n\n if (composedPath[composedPath.length - 1] === document) {\n composedPath.push(window);\n }\n\n return composedPath;\n}\n\nvar patch_events_composedPath = function composedPath(event) {\n if (!event.__composedPath) {\n event.__composedPath = pathComposer(event.target, true);\n }\n\n return event.__composedPath;\n};\n\nfunction retarget(refNode, path) {\n if (!utils_isShadyRoot) {\n return refNode;\n } // If ANCESTOR's root is not a shadow root or ANCESTOR's root is BASE's\n // shadow-including inclusive ancestor, return ANCESTOR.\n\n\n var refNodePath = pathComposer(refNode, true);\n var p$ = path;\n\n for (var i = 0, ancestor, lastRoot, root, rootIdx; i < p$.length; i++) {\n ancestor = p$[i];\n root = getRootNodeWithFallback(ancestor);\n\n if (root !== lastRoot) {\n rootIdx = refNodePath.indexOf(root);\n lastRoot = root;\n }\n\n if (!utils_isShadyRoot(root) || rootIdx > -1) {\n return ancestor;\n }\n }\n}\n\nvar EventPatches = {\n /**\n * @this {Event}\n */\n get composed() {\n if (this.__composed === undefined) {\n // if there's an original `composed` getter on the Event prototype, use that\n if (composedGetter) {\n // TODO(web-padawan): see https://github.com/webcomponents/shadydom/issues/275\n this.__composed = this.type === 'focusin' || this.type === 'focusout' || composedGetter(this); // If the event is trusted, or `isTrusted` is not supported, check the list of always composed events\n } else if (this.isTrusted !== false) {\n this.__composed = alwaysComposed[this.type];\n }\n }\n\n return (\n /** @type {!Event} */\n this.__composed || false\n );\n },\n\n /**\n * @this {Event}\n */\n composedPath: function composedPath() {\n if (!this.__composedPath) {\n this.__composedPath = pathComposer(this['__target'], this.composed);\n }\n\n return (\n /** @type {!Event} */\n this.__composedPath\n );\n },\n\n /**\n * @this {Event}\n */\n get target() {\n return retarget(this.currentTarget || this['__previousCurrentTarget'], this.composedPath());\n },\n\n // http://w3c.github.io/webcomponents/spec/shadow/#event-relatedtarget-retargeting\n\n /**\n * @this {Event}\n */\n get relatedTarget() {\n if (!this.__relatedTarget) {\n return null;\n }\n\n if (!this.__relatedTargetComposedPath) {\n this.__relatedTargetComposedPath = pathComposer(this.__relatedTarget, true);\n } // find the deepest node in relatedTarget composed path that is in the same root with the currentTarget\n\n\n return retarget(this.currentTarget || this['__previousCurrentTarget'],\n /** @type {!Event} */\n this.__relatedTargetComposedPath);\n },\n\n /**\n * @this {Event}\n */\n stopPropagation: function stopPropagation() {\n Event.prototype.stopPropagation.call(this);\n this.__propagationStopped = true;\n },\n\n /**\n * @this {Event}\n */\n stopImmediatePropagation: function stopImmediatePropagation() {\n Event.prototype.stopImmediatePropagation.call(this);\n this.__immediatePropagationStopped = true;\n this.__propagationStopped = true;\n }\n};\n\nfunction mixinComposedFlag(Base) {\n // NOTE: avoiding use of `class` here so that transpiled output does not\n // try to do `Base.call` with a dom construtor.\n var klazz = function klazz(type, options) {\n var event = new Base(type, options);\n event.__composed = options && Boolean(options['composed']);\n return event;\n }; // put constructor properties on subclass\n\n\n klazz.__proto__ = Base;\n klazz.prototype = Base.prototype;\n return klazz;\n}\n\nvar nonBubblingEventsToRetarget = {\n 'focus': true,\n 'blur': true\n};\n/**\n * Check if the event has been retargeted by comparing original `target`, and calculated `target`\n * @param {Event} event\n * @return {boolean} True if the original target and calculated target are the same\n */\n\nfunction hasRetargeted(event) {\n return event['__target'] !== event.target || event.__relatedTarget !== event.relatedTarget;\n}\n/**\n *\n * @param {Event} event\n * @param {Node} node\n * @param {string} phase\n */\n\n\nfunction fireHandlers(event, node, phase) {\n var hs = node.__handlers && node.__handlers[event.type] && node.__handlers[event.type][phase];\n\n if (hs) {\n for (var i = 0, fn; fn = hs[i]; i++) {\n if (hasRetargeted(event) && event.target === event.relatedTarget) {\n return;\n }\n\n fn.call(node, event);\n\n if (event.__immediatePropagationStopped) {\n return;\n }\n }\n }\n}\n\nfunction retargetNonBubblingEvent(e) {\n var path = e.composedPath();\n var node; // override `currentTarget` to let patched `target` calculate correctly\n\n Object.defineProperty(e, 'currentTarget', {\n get: function get() {\n return node;\n },\n configurable: true\n });\n\n for (var i = path.length - 1; i >= 0; i--) {\n node = path[i]; // capture phase fires all capture handlers\n\n fireHandlers(e, node, 'capture');\n\n if (e.__propagationStopped) {\n return;\n }\n } // set the event phase to `AT_TARGET` as in spec\n\n\n Object.defineProperty(e, 'eventPhase', {\n get: function get() {\n return Event.AT_TARGET;\n }\n }); // the event only needs to be fired when owner roots change when iterating the event path\n // keep track of the last seen owner root\n\n var lastFiredRoot;\n\n for (var _i = 0; _i < path.length; _i++) {\n node = path[_i];\n var nodeData = shadyDataForNode(node);\n var root = nodeData && nodeData.root;\n\n if (_i === 0 || root && root === lastFiredRoot) {\n fireHandlers(e, node, 'bubble'); // don't bother with window, it doesn't have `getRootNode` and will be last in the path anyway\n\n if (node !== window) {\n lastFiredRoot = node[SHADY_PREFIX + 'getRootNode']();\n }\n\n if (e.__propagationStopped) {\n return;\n }\n }\n }\n}\n\nfunction listenerSettingsEqual(savedListener, node, type, capture, once, passive) {\n var savedNode = savedListener.node,\n savedType = savedListener.type,\n savedCapture = savedListener.capture,\n savedOnce = savedListener.once,\n savedPassive = savedListener.passive;\n return node === savedNode && type === savedType && capture === savedCapture && once === savedOnce && passive === savedPassive;\n}\n\nfunction findListener(wrappers, node, type, capture, once, passive) {\n for (var i = 0; i < wrappers.length; i++) {\n if (listenerSettingsEqual(wrappers[i], node, type, capture, once, passive)) {\n return i;\n }\n }\n\n return -1;\n}\n/**\n * Firefox can throw on accessing eventWrappers inside of `removeEventListener` during a selenium run\n * Try/Catch accessing eventWrappers to work around\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1353074\n */\n\nfunction getEventWrappers(eventLike) {\n var wrappers = null;\n\n try {\n wrappers = eventLike[eventWrappersName];\n } catch (e) {} // eslint-disable-line no-empty\n\n\n return wrappers;\n}\n/**\n * @this {EventTarget}\n */\n\n\nfunction patch_events_addEventListener(type, fnOrObj, optionsOrCapture) {\n if (!fnOrObj) {\n return;\n }\n\n var handlerType = _typeof(fnOrObj); // bail if `fnOrObj` is not a function, not an object\n\n\n if (handlerType !== 'function' && handlerType !== 'object') {\n return;\n } // bail if `fnOrObj` is an object without a `handleEvent` method\n\n\n if (handlerType === 'object' && (!fnOrObj.handleEvent || typeof fnOrObj.handleEvent !== 'function')) {\n return;\n }\n\n if (unpatchedEvents[type]) {\n return this[NATIVE_PREFIX + 'addEventListener'](type, fnOrObj, optionsOrCapture);\n } // The callback `fn` might be used for multiple nodes/events. Since we generate\n // a wrapper function, we need to keep track of it when we remove the listener.\n // It's more efficient to store the node/type/options information as Array in\n // `fn` itself rather than the node (we assume that the same callback is used\n // for few nodes at most, whereas a node will likely have many event listeners).\n // NOTE(valdrin) invoking external functions is costly, inline has better perf.\n\n\n var capture, once, passive;\n\n if (optionsOrCapture && _typeof(optionsOrCapture) === 'object') {\n capture = Boolean(optionsOrCapture.capture);\n once = Boolean(optionsOrCapture.once);\n passive = Boolean(optionsOrCapture.passive);\n } else {\n capture = Boolean(optionsOrCapture);\n once = false;\n passive = false;\n } // hack to let ShadyRoots have event listeners\n // event listener will be on host, but `currentTarget`\n // will be set to shadyroot for event listener\n\n\n var target = optionsOrCapture && optionsOrCapture.__shadyTarget || this;\n var wrappers = fnOrObj[eventWrappersName];\n\n if (wrappers) {\n // Stop if the wrapper function has already been created.\n if (findListener(wrappers, target, type, capture, once, passive) > -1) {\n return;\n }\n } else {\n fnOrObj[eventWrappersName] = [];\n }\n /**\n * @this {HTMLElement}\n * @param {Event} e\n */\n\n\n var wrapperFn = function wrapperFn(e) {\n // Support `once` option.\n if (once) {\n this[SHADY_PREFIX + 'removeEventListener'](type, fnOrObj, optionsOrCapture);\n }\n\n if (!e['__target']) {\n patchEvent(e);\n }\n\n var lastCurrentTargetDesc;\n\n if (target !== this) {\n // replace `currentTarget` to make `target` and `relatedTarget` correct for inside the shadowroot\n lastCurrentTargetDesc = Object.getOwnPropertyDescriptor(e, 'currentTarget');\n Object.defineProperty(e, 'currentTarget', {\n get: function get() {\n return target;\n },\n configurable: true\n });\n }\n\n e['__previousCurrentTarget'] = e['currentTarget']; // Always check if a shadowRoot is in the current event path.\n // If it is not, the event was generated on either the host of the shadowRoot\n // or a children of the host.\n\n if (utils_isShadyRoot(target) && e.composedPath().indexOf(target) == -1) {\n return;\n } // There are two critera that should stop events from firing on this node\n // 1. the event is not composed and the current node is not in the same root as the target\n // 2. when bubbling, if after retargeting, relatedTarget and target point to the same node\n\n\n if (e.composed || e.composedPath().indexOf(target) > -1) {\n if (hasRetargeted(e) && e.target === e.relatedTarget) {\n if (e.eventPhase === Event.BUBBLING_PHASE) {\n e.stopImmediatePropagation();\n }\n\n return;\n } // prevent non-bubbling events from triggering bubbling handlers on shadowroot, but only if not in capture phase\n\n\n if (e.eventPhase !== Event.CAPTURING_PHASE && !e.bubbles && e.target !== target && !(target instanceof Window)) {\n return;\n }\n\n var ret = handlerType === 'function' ? fnOrObj.call(target, e) : fnOrObj.handleEvent && fnOrObj.handleEvent(e);\n\n if (target !== this) {\n // replace the \"correct\" `currentTarget`\n if (lastCurrentTargetDesc) {\n Object.defineProperty(e, 'currentTarget', lastCurrentTargetDesc);\n lastCurrentTargetDesc = null;\n } else {\n delete e['currentTarget'];\n }\n }\n\n return ret;\n }\n }; // Store the wrapper information.\n\n\n fnOrObj[eventWrappersName].push({\n // note: use target here which is either a shadowRoot\n // (when the host element is proxy'ing the event) or this element\n node: target,\n type: type,\n capture: capture,\n once: once,\n passive: passive,\n wrapperFn: wrapperFn\n });\n\n if (nonBubblingEventsToRetarget[type]) {\n this.__handlers = this.__handlers || {};\n this.__handlers[type] = this.__handlers[type] || {\n 'capture': [],\n 'bubble': []\n };\n\n this.__handlers[type][capture ? 'capture' : 'bubble'].push(wrapperFn);\n } else {\n this[NATIVE_PREFIX + 'addEventListener'](type, wrapperFn, optionsOrCapture);\n }\n}\n/**\n * @this {EventTarget}\n */\n\nfunction patch_events_removeEventListener(type, fnOrObj, optionsOrCapture) {\n if (!fnOrObj) {\n return;\n }\n\n if (unpatchedEvents[type]) {\n return this[NATIVE_PREFIX + 'removeEventListener'](type, fnOrObj, optionsOrCapture);\n } // NOTE(valdrin) invoking external functions is costly, inline has better perf.\n\n\n var capture, once, passive;\n\n if (optionsOrCapture && _typeof(optionsOrCapture) === 'object') {\n capture = Boolean(optionsOrCapture.capture);\n once = Boolean(optionsOrCapture.once);\n passive = Boolean(optionsOrCapture.passive);\n } else {\n capture = Boolean(optionsOrCapture);\n once = false;\n passive = false;\n }\n\n var target = optionsOrCapture && optionsOrCapture.__shadyTarget || this; // Search the wrapped function.\n\n var wrapperFn = undefined;\n var wrappers = getEventWrappers(fnOrObj);\n\n if (wrappers) {\n var idx = findListener(wrappers, target, type, capture, once, passive);\n\n if (idx > -1) {\n wrapperFn = wrappers.splice(idx, 1)[0].wrapperFn; // Cleanup.\n\n if (!wrappers.length) {\n fnOrObj[eventWrappersName] = undefined;\n }\n }\n }\n\n this[NATIVE_PREFIX + 'removeEventListener'](type, wrapperFn || fnOrObj, optionsOrCapture);\n\n if (wrapperFn && nonBubblingEventsToRetarget[type] && this.__handlers && this.__handlers[type]) {\n var arr = this.__handlers[type][capture ? 'capture' : 'bubble'];\n\n var _idx = arr.indexOf(wrapperFn);\n\n if (_idx > -1) {\n arr.splice(_idx, 1);\n }\n }\n}\n\nfunction activateFocusEventOverrides() {\n for (var ev in nonBubblingEventsToRetarget) {\n window[NATIVE_PREFIX + 'addEventListener'](ev, function (e) {\n if (!e['__target']) {\n patchEvent(e);\n retargetNonBubblingEvent(e);\n }\n }, true);\n }\n}\n\nvar EventPatchesDescriptors = getOwnPropertyDescriptors(EventPatches);\nvar SHADY_PROTO = '__shady_patchedProto';\nvar SHADY_SOURCE_PROTO = '__shady_sourceProto';\n\nfunction patchEvent(event) {\n event['__target'] = event.target;\n event.__relatedTarget = event.relatedTarget; // attempt to patch prototype (via cache)\n\n if (settings.hasDescriptors) {\n var proto = Object.getPrototypeOf(event);\n\n if (!Object.hasOwnProperty(proto, SHADY_PROTO)) {\n var patchedProto = Object.create(proto);\n patchedProto[SHADY_SOURCE_PROTO] = proto;\n patchProperties(patchedProto, EventPatchesDescriptors);\n proto[SHADY_PROTO] = patchedProto;\n }\n\n event.__proto__ = proto[SHADY_PROTO]; // and fallback to patching instance\n } else {\n patchProperties(event, EventPatchesDescriptors);\n }\n}\n\nvar PatchedEvent = mixinComposedFlag(Event);\nvar PatchedCustomEvent = mixinComposedFlag(CustomEvent);\nvar PatchedMouseEvent = mixinComposedFlag(MouseEvent);\nfunction patchEvents() {\n activateFocusEventOverrides();\n window.Event = PatchedEvent;\n window.CustomEvent = PatchedCustomEvent;\n window.MouseEvent = PatchedMouseEvent;\n}\nfunction patchClick() {\n // Fix up `Element.prototype.click()` if `isTrusted` is supported, but `composed` isn't\n if (!composedGetter && Object.getOwnPropertyDescriptor(Event.prototype, 'isTrusted')) {\n /** @this {Element} */\n var composedClickFn = function composedClickFn() {\n var ev = new MouseEvent('click', {\n bubbles: true,\n cancelable: true,\n composed: true\n });\n this[SHADY_PREFIX + 'dispatchEvent'](ev);\n };\n\n if (Element.prototype.click) {\n Element.prototype.click = composedClickFn;\n } else if (HTMLElement.prototype.click) {\n HTMLElement.prototype.click = composedClickFn;\n }\n }\n}\nvar eventPropertyNames = Object.getOwnPropertyNames(Document.prototype).filter(function (name) {\n return name.substring(0, 2) === 'on';\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/array-splice.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\nfunction newSplice(index, removed, addedCount) {\n return {\n index: index,\n removed: removed,\n addedCount: addedCount\n };\n}\n\nvar EDIT_LEAVE = 0;\nvar EDIT_UPDATE = 1;\nvar EDIT_ADD = 2;\nvar EDIT_DELETE = 3; // Note: This function is *based* on the computation of the Levenshtein\n// \"edit\" distance. The one change is that \"updates\" are treated as two\n// edits - not one. With Array splices, an update is really a delete\n// followed by an add. By retaining this, we optimize for \"keeping\" the\n// maximum array items in the original array. For example:\n//\n// 'xxxx123' -> '123yyyy'\n//\n// With 1-edit updates, the shortest path would be just to update all seven\n// characters. With 2-edit updates, we delete 4, leave 3, and add 4. This\n// leaves the substring '123' intact.\n\nfunction calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd) {\n // \"Deletion\" columns\n var rowCount = oldEnd - oldStart + 1;\n var columnCount = currentEnd - currentStart + 1;\n var distances = new Array(rowCount); // \"Addition\" rows. Initialize null column.\n\n for (var i = 0; i < rowCount; i++) {\n distances[i] = new Array(columnCount);\n distances[i][0] = i;\n } // Initialize null row\n\n\n for (var j = 0; j < columnCount; j++) {\n distances[0][j] = j;\n }\n\n for (var _i = 1; _i < rowCount; _i++) {\n for (var _j = 1; _j < columnCount; _j++) {\n if (equals(current[currentStart + _j - 1], old[oldStart + _i - 1])) distances[_i][_j] = distances[_i - 1][_j - 1];else {\n var north = distances[_i - 1][_j] + 1;\n var west = distances[_i][_j - 1] + 1;\n distances[_i][_j] = north < west ? north : west;\n }\n }\n }\n\n return distances;\n} // This starts at the final weight, and walks \"backward\" by finding\n// the minimum previous weight recursively until the origin of the weight\n// matrix.\n\n\nfunction spliceOperationsFromEditDistances(distances) {\n var i = distances.length - 1;\n var j = distances[0].length - 1;\n var current = distances[i][j];\n var edits = [];\n\n while (i > 0 || j > 0) {\n if (i == 0) {\n edits.push(EDIT_ADD);\n j--;\n continue;\n }\n\n if (j == 0) {\n edits.push(EDIT_DELETE);\n i--;\n continue;\n }\n\n var northWest = distances[i - 1][j - 1];\n var west = distances[i - 1][j];\n var north = distances[i][j - 1];\n var min = void 0;\n if (west < north) min = west < northWest ? west : northWest;else min = north < northWest ? north : northWest;\n\n if (min == northWest) {\n if (northWest == current) {\n edits.push(EDIT_LEAVE);\n } else {\n edits.push(EDIT_UPDATE);\n current = northWest;\n }\n\n i--;\n j--;\n } else if (min == west) {\n edits.push(EDIT_DELETE);\n i--;\n current = west;\n } else {\n edits.push(EDIT_ADD);\n j--;\n current = north;\n }\n }\n\n edits.reverse();\n return edits;\n}\n/**\n * Splice Projection functions:\n *\n * A splice map is a representation of how a previous array of items\n * was transformed into a new array of items. Conceptually it is a list of\n * tuples of\n *\n * \n *\n * which are kept in ascending index order of. The tuple represents that at\n * the |index|, |removed| sequence of items were removed, and counting forward\n * from |index|, |addedCount| items were added.\n */\n\n/**\n * Lacking individual splice mutation information, the minimal set of\n * splices can be synthesized given the previous state and final state of an\n * array. The basic approach is to calculate the edit distance matrix and\n * choose the shortest path through it.\n *\n * Complexity: O(l * p)\n * l: The length of the current array\n * p: The length of the old array\n */\n\n\nfunction calcSplices(current, currentStart, currentEnd, old, oldStart, oldEnd) {\n var prefixCount = 0;\n var suffixCount = 0;\n var splice;\n var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);\n if (currentStart == 0 && oldStart == 0) prefixCount = sharedPrefix(current, old, minLength);\n if (currentEnd == current.length && oldEnd == old.length) suffixCount = sharedSuffix(current, old, minLength - prefixCount);\n currentStart += prefixCount;\n oldStart += prefixCount;\n currentEnd -= suffixCount;\n oldEnd -= suffixCount;\n if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0) return [];\n\n if (currentStart == currentEnd) {\n splice = newSplice(currentStart, [], 0);\n\n while (oldStart < oldEnd) {\n splice.removed.push(old[oldStart++]);\n }\n\n return [splice];\n } else if (oldStart == oldEnd) return [newSplice(currentStart, [], currentEnd - currentStart)];\n\n var ops = spliceOperationsFromEditDistances(calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd));\n splice = undefined;\n var splices = [];\n var index = currentStart;\n var oldIndex = oldStart;\n\n for (var i = 0; i < ops.length; i++) {\n switch (ops[i]) {\n case EDIT_LEAVE:\n if (splice) {\n splices.push(splice);\n splice = undefined;\n }\n\n index++;\n oldIndex++;\n break;\n\n case EDIT_UPDATE:\n if (!splice) splice = newSplice(index, [], 0);\n splice.addedCount++;\n index++;\n splice.removed.push(old[oldIndex]);\n oldIndex++;\n break;\n\n case EDIT_ADD:\n if (!splice) splice = newSplice(index, [], 0);\n splice.addedCount++;\n index++;\n break;\n\n case EDIT_DELETE:\n if (!splice) splice = newSplice(index, [], 0);\n splice.removed.push(old[oldIndex]);\n oldIndex++;\n break;\n }\n }\n\n if (splice) {\n splices.push(splice);\n }\n\n return splices;\n}\n\nfunction sharedPrefix(current, old, searchLength) {\n for (var i = 0; i < searchLength; i++) {\n if (!equals(current[i], old[i])) return i;\n }\n\n return searchLength;\n}\n\nfunction sharedSuffix(current, old, searchLength) {\n var index1 = current.length;\n var index2 = old.length;\n var count = 0;\n\n while (count < searchLength && equals(current[--index1], old[--index2])) {\n count++;\n }\n\n return count;\n}\n\nfunction equals(currentValue, previousValue) {\n return currentValue === previousValue;\n}\n\nfunction calculateSplices(current, previous) {\n return calcSplices(current, 0, current.length, previous, 0, previous.length);\n}\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/link-nodes.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n\n\nfunction linkNode(node, container, ref_node) {\n patchOutsideElementAccessors(node);\n ref_node = ref_node || null;\n var nodeData = ensureShadyDataForNode(node);\n var containerData = ensureShadyDataForNode(container);\n var ref_nodeData = ref_node ? ensureShadyDataForNode(ref_node) : null; // update ref_node.previousSibling <-> node\n\n nodeData.previousSibling = ref_node ? ref_nodeData.previousSibling : container[SHADY_PREFIX + 'lastChild'];\n var psd = shadyDataForNode(nodeData.previousSibling);\n\n if (psd) {\n psd.nextSibling = node;\n } // update node <-> ref_node\n\n\n var nsd = shadyDataForNode(nodeData.nextSibling = ref_node);\n\n if (nsd) {\n nsd.previousSibling = node;\n } // update node <-> container\n\n\n nodeData.parentNode = container;\n\n if (ref_node) {\n if (ref_node === containerData.firstChild) {\n containerData.firstChild = node;\n }\n } else {\n containerData.lastChild = node;\n\n if (!containerData.firstChild) {\n containerData.firstChild = node;\n }\n } // remove caching of childNodes\n\n\n containerData.childNodes = null;\n}\n\nvar link_nodes_recordInsertBefore = function recordInsertBefore(node, container, ref_node) {\n patchInsideElementAccessors(container);\n var containerData = ensureShadyDataForNode(container);\n\n if (containerData.firstChild !== undefined) {\n containerData.childNodes = null;\n } // handle document fragments\n\n\n if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n var c$ = node[SHADY_PREFIX + 'childNodes'];\n\n for (var i = 0; i < c$.length; i++) {\n linkNode(c$[i], container, ref_node);\n } // cleanup logical dom in doc fragment.\n\n\n var nodeData = ensureShadyDataForNode(node);\n var resetTo = nodeData.firstChild !== undefined ? null : undefined;\n nodeData.firstChild = nodeData.lastChild = resetTo;\n nodeData.childNodes = resetTo;\n } else {\n linkNode(node, container, ref_node);\n }\n};\nvar link_nodes_recordRemoveChild = function recordRemoveChild(node, container) {\n var nodeData = ensureShadyDataForNode(node);\n var containerData = ensureShadyDataForNode(container);\n\n if (node === containerData.firstChild) {\n containerData.firstChild = nodeData.nextSibling;\n }\n\n if (node === containerData.lastChild) {\n containerData.lastChild = nodeData.previousSibling;\n }\n\n var p = nodeData.previousSibling;\n var n = nodeData.nextSibling;\n\n if (p) {\n ensureShadyDataForNode(p).nextSibling = n;\n }\n\n if (n) {\n ensureShadyDataForNode(n).previousSibling = p;\n } // When an element is removed, logical data is no longer tracked.\n // Explicitly set `undefined` here to indicate this. This is disginguished\n // from `null` which is set if info is null.\n\n\n nodeData.parentNode = nodeData.previousSibling = nodeData.nextSibling = undefined;\n\n if (containerData.childNodes !== undefined) {\n // remove caching of childNodes\n containerData.childNodes = null;\n }\n};\n/**\n * @param {!Node} node\n */\n\nvar link_nodes_recordChildNodes = function recordChildNodes(node) {\n var nodeData = ensureShadyDataForNode(node);\n\n if (nodeData.firstChild === undefined) {\n // remove caching of childNodes\n nodeData.childNodes = null;\n var first = nodeData.firstChild = node[NATIVE_PREFIX + 'firstChild'] || null;\n nodeData.lastChild = node[NATIVE_PREFIX + 'lastChild'] || null;\n patchInsideElementAccessors(node);\n\n for (var n = first, previous; n; n = n[NATIVE_PREFIX + 'nextSibling']) {\n var sd = ensureShadyDataForNode(n);\n sd.parentNode = node;\n sd.nextSibling = n[NATIVE_PREFIX + 'nextSibling'] || null;\n sd.previousSibling = previous || null;\n previous = n;\n patchOutsideElementAccessors(n);\n }\n }\n};\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/style-scoping.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\nvar style_scoping_scopingShim = null;\nfunction getScopingShim() {\n if (!style_scoping_scopingShim) {\n style_scoping_scopingShim = window['ShadyCSS'] && window['ShadyCSS']['ScopingShim'];\n }\n\n return style_scoping_scopingShim || null;\n}\n/**\n * @param {!Node} node\n * @param {string} attr\n * @param {string} value\n */\n\nfunction scopeClassAttribute(node, attr, value) {\n var scopingShim = getScopingShim();\n\n if (scopingShim && attr === 'class') {\n scopingShim['setElementClass'](node, value);\n return true;\n }\n\n return false;\n}\n/**\n * @param {!Node} node\n * @param {string} newScopeName\n */\n\nfunction addShadyScoping(node, newScopeName) {\n var scopingShim = getScopingShim();\n\n if (!scopingShim) {\n return;\n }\n\n scopingShim['scopeNode'](node, newScopeName);\n}\n/**\n * @param {!Node} node\n * @param {string} currentScopeName\n */\n\nfunction removeShadyScoping(node, currentScopeName) {\n var scopingShim = getScopingShim();\n\n if (!scopingShim) {\n return;\n }\n\n scopingShim['unscopeNode'](node, currentScopeName);\n}\n/**\n * @param {!Node} node\n * @param {string} newScopeName\n * @param {string} oldScopeName\n */\n\nfunction replaceShadyScoping(node, newScopeName, oldScopeName) {\n var scopingShim = getScopingShim();\n\n if (!scopingShim) {\n return;\n }\n\n if (oldScopeName) {\n removeShadyScoping(node, oldScopeName);\n }\n\n addShadyScoping(node, newScopeName);\n}\n/**\n * @param {!Node} node\n * @param {string} newScopeName\n * @return {boolean}\n */\n\nfunction currentScopeIsCorrect(node, newScopeName) {\n var scopingShim = getScopingShim();\n\n if (!scopingShim) {\n return true;\n }\n\n if (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {\n // NOTE: as an optimization, only check that all the top-level children\n // have the correct scope.\n var correctScope = true;\n var childNodes = node[SHADY_PREFIX + 'childNodes'];\n\n for (var idx = 0; correctScope && idx < childNodes.length; idx++) {\n correctScope = correctScope && currentScopeIsCorrect(childNodes[idx], newScopeName);\n }\n\n return correctScope;\n }\n\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return true;\n }\n\n var currentScope = scopingShim['currentScopeForNode'](node);\n return currentScope === newScopeName;\n}\n/**\n * @param {!Node} node\n * @return {string}\n */\n\nfunction currentScopeForNode(node) {\n if (node.nodeType !== Node.ELEMENT_NODE) {\n return '';\n }\n\n var scopingShim = getScopingShim();\n\n if (!scopingShim) {\n return '';\n }\n\n return scopingShim['currentScopeForNode'](node);\n}\n/**\n * Walk over a node's tree and apply visitorFn to each element node\n *\n * @param {Node} node\n * @param {function(!Node):void} visitorFn\n */\n\nfunction treeVisitor(node, visitorFn) {\n if (!node) {\n return;\n } // this check is necessary if `node` is a Document Fragment\n\n\n if (node.nodeType === Node.ELEMENT_NODE) {\n visitorFn(node);\n }\n\n var childNodes = node[SHADY_PREFIX + 'childNodes'];\n\n for (var idx = 0, n; idx < childNodes.length; idx++) {\n n = childNodes[idx];\n\n if (n.nodeType === Node.ELEMENT_NODE) {\n treeVisitor(n, visitorFn);\n }\n }\n}\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/Node.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n\n\n\nvar doc = window.document;\nvar preferPerformance = settings.preferPerformance;\nvar nativeIsConnectedAccessors =\n/** @type {ObjectPropertyDescriptor} */\nObject.getOwnPropertyDescriptor(Node.prototype, 'isConnected');\nvar nativeIsConnected = nativeIsConnectedAccessors && nativeIsConnectedAccessors.get;\nfunction Node_clearNode(node) {\n var firstChild;\n\n while (firstChild = node[SHADY_PREFIX + 'firstChild']) {\n node[SHADY_PREFIX + 'removeChild'](firstChild);\n }\n}\n\nfunction removeOwnerShadyRoot(node) {\n // optimization: only reset the tree if node is actually in a root\n if (hasCachedOwnerRoot(node)) {\n var c$ = node[SHADY_PREFIX + 'childNodes'];\n\n for (var i = 0, l = c$.length, n; i < l && (n = c$[i]); i++) {\n removeOwnerShadyRoot(n);\n }\n }\n\n var nodeData = shadyDataForNode(node);\n\n if (nodeData) {\n nodeData.ownerShadyRoot = undefined;\n }\n}\n\nfunction hasCachedOwnerRoot(node) {\n var nodeData = shadyDataForNode(node);\n return Boolean(nodeData && nodeData.ownerShadyRoot !== undefined);\n}\n/**\n * Finds the first flattened node that is composed in the node's parent.\n * If the given node is a slot, then the first flattened node is returned\n * if it exists, otherwise advance to the node's nextSibling.\n * @param {Node} node within which to find first composed node\n * @returns {Node} first composed node\n */\n\n\nfunction firstComposedNode(node) {\n var composed = node;\n\n if (node && node.localName === 'slot') {\n var nodeData = shadyDataForNode(node);\n var flattened = nodeData && nodeData.flattenedNodes;\n composed = flattened && flattened.length ? flattened[0] : firstComposedNode(node[SHADY_PREFIX + 'nextSibling']);\n }\n\n return composed;\n}\n/**\n * @param {Node} node\n * @param {Node=} addedNode\n * @param {Node=} removedNode\n */\n\n\nfunction scheduleObserver(node, addedNode, removedNode) {\n var nodeData = shadyDataForNode(node);\n var observer = nodeData && nodeData.observer;\n\n if (observer) {\n if (addedNode) {\n observer.addedNodes.push(addedNode);\n }\n\n if (removedNode) {\n observer.removedNodes.push(removedNode);\n }\n\n observer.schedule();\n }\n}\n\nvar NodePatches = getOwnPropertyDescriptors({\n /** @this {Node} */\n get parentNode() {\n var nodeData = shadyDataForNode(this);\n var l = nodeData && nodeData.parentNode;\n return l !== undefined ? l : this[NATIVE_PREFIX + 'parentNode'];\n },\n\n /** @this {Node} */\n get firstChild() {\n var nodeData = shadyDataForNode(this);\n var l = nodeData && nodeData.firstChild;\n return l !== undefined ? l : this[NATIVE_PREFIX + 'firstChild'];\n },\n\n /** @this {Node} */\n get lastChild() {\n var nodeData = shadyDataForNode(this);\n var l = nodeData && nodeData.lastChild;\n return l !== undefined ? l : this[NATIVE_PREFIX + 'lastChild'];\n },\n\n /** @this {Node} */\n get nextSibling() {\n var nodeData = shadyDataForNode(this);\n var l = nodeData && nodeData.nextSibling;\n return l !== undefined ? l : this[NATIVE_PREFIX + 'nextSibling'];\n },\n\n /** @this {Node} */\n get previousSibling() {\n var nodeData = shadyDataForNode(this);\n var l = nodeData && nodeData.previousSibling;\n return l !== undefined ? l : this[NATIVE_PREFIX + 'previousSibling'];\n },\n\n /** @this {Node} */\n get childNodes() {\n var childNodes;\n\n if (utils_isTrackingLogicalChildNodes(this)) {\n var nodeData = shadyDataForNode(this);\n\n if (!nodeData.childNodes) {\n nodeData.childNodes = [];\n\n for (var n = this[SHADY_PREFIX + 'firstChild']; n; n = n[SHADY_PREFIX + 'nextSibling']) {\n nodeData.childNodes.push(n);\n }\n }\n\n childNodes = nodeData.childNodes;\n } else {\n childNodes = this[NATIVE_PREFIX + 'childNodes'];\n }\n\n childNodes.item = function (index) {\n return childNodes[index];\n };\n\n return childNodes;\n },\n\n /** @this {Node} */\n get parentElement() {\n var nodeData = shadyDataForNode(this);\n var l = nodeData && nodeData.parentNode;\n\n if (l && l.nodeType !== Node.ELEMENT_NODE) {\n l = null;\n }\n\n return l !== undefined ? l : this[NATIVE_PREFIX + 'parentElement'];\n },\n\n /** @this {Node} */\n get isConnected() {\n if (nativeIsConnected && nativeIsConnected.call(this)) {\n return true;\n }\n\n if (this.nodeType == Node.DOCUMENT_FRAGMENT_NODE) {\n return false;\n } // Fast path for distributed nodes.\n\n\n var ownerDocument = this.ownerDocument;\n\n if (hasDocumentContains) {\n if (ownerDocument[NATIVE_PREFIX + 'contains'](this)) {\n return true;\n }\n } else if (ownerDocument.documentElement && ownerDocument.documentElement[NATIVE_PREFIX + 'contains'](this)) {\n return true;\n } // Slow path for non-distributed nodes.\n\n\n var node = this;\n\n while (node && !(node instanceof Document)) {\n node = node[SHADY_PREFIX + 'parentNode'] || (utils_isShadyRoot(node) ?\n /** @type {ShadowRoot} */\n node.host : undefined);\n }\n\n return !!(node && node instanceof Document);\n },\n\n /** @this {Node} */\n get textContent() {\n if (utils_isTrackingLogicalChildNodes(this)) {\n var tc = [];\n\n for (var i = 0, cn = this[SHADY_PREFIX + 'childNodes'], c; c = cn[i]; i++) {\n if (c.nodeType !== Node.COMMENT_NODE) {\n tc.push(c[SHADY_PREFIX + 'textContent']);\n }\n }\n\n return tc.join('');\n } else {\n return this[NATIVE_PREFIX + 'textContent'];\n }\n },\n\n /**\n * @this {Node}\n * @param {string} value\n */\n set textContent(value) {\n if (typeof value === 'undefined' || value === null) {\n value = '';\n }\n\n switch (this.nodeType) {\n case Node.ELEMENT_NODE:\n case Node.DOCUMENT_FRAGMENT_NODE:\n if (!utils_isTrackingLogicalChildNodes(this) && settings.hasDescriptors) {\n // may be removing a nested slot but fast path if we know we are not.\n var firstChild = this[SHADY_PREFIX + 'firstChild'];\n\n if (firstChild != this[SHADY_PREFIX + 'lastChild'] || firstChild && firstChild.nodeType != Node.TEXT_NODE) {\n Node_clearNode(this);\n }\n\n this[NATIVE_PREFIX + 'textContent'] = value;\n } else {\n Node_clearNode(this); // Document fragments must have no childNodes if setting a blank string\n\n if (value.length > 0 || this.nodeType === Node.ELEMENT_NODE) {\n this[SHADY_PREFIX + 'insertBefore'](document.createTextNode(value));\n }\n }\n\n break;\n\n default:\n // Note, be wary of patching `nodeValue`.\n this.nodeValue = value;\n break;\n }\n },\n\n // Patched `insertBefore`. Note that all mutations that add nodes are routed\n // here. When a is added or a node is added to a host with a shadowRoot\n // with a slot, a standard dom `insert` call is aborted and `_asyncRender`\n // is called on the relevant shadowRoot. In all other cases, a standard dom\n // `insert` can be made, but the location and ref_node may need to be changed.\n\n /**\n * @this {Node}\n * @param {Node} node\n * @param {Node=} ref_node\n */\n insertBefore: function insertBefore(node, ref_node) {\n // optimization: assume native insertBefore is ok if the nodes are not in the document.\n if (this.ownerDocument !== doc && node.ownerDocument !== doc) {\n this[NATIVE_PREFIX + 'insertBefore'](node, ref_node);\n return node;\n }\n\n if (node === this) {\n throw Error(\"Failed to execute 'appendChild' on 'Node': The new child element contains the parent.\");\n }\n\n if (ref_node) {\n var refData = shadyDataForNode(ref_node);\n var p = refData && refData.parentNode;\n\n if (p !== undefined && p !== this || p === undefined && ref_node[NATIVE_PREFIX + 'parentNode'] !== this) {\n throw Error(\"Failed to execute 'insertBefore' on 'Node': The node \" + \"before which the new node is to be inserted is not a child of this node.\");\n }\n }\n\n if (ref_node === node) {\n return node;\n }\n /** @type {!Array} */\n\n\n var slotsAdded = [];\n var ownerRoot = attach_shadow_ownerShadyRootForNode(this);\n /** @type {string} */\n\n var newScopeName = ownerRoot ? ownerRoot.host.localName : currentScopeForNode(this);\n /** @type {string} */\n\n var oldScopeName; // remove from existing location\n\n var parentNode = node[SHADY_PREFIX + 'parentNode'];\n\n if (parentNode) {\n oldScopeName = currentScopeForNode(node);\n parentNode[SHADY_PREFIX + 'removeChild'](node, Boolean(ownerRoot) || !attach_shadow_ownerShadyRootForNode(node));\n } // add to new parent\n\n\n var allowNativeInsert = true;\n var needsScoping = (!preferPerformance || node['__noInsertionPoint'] === undefined) && !currentScopeIsCorrect(node, newScopeName);\n var needsSlotFinding = ownerRoot && !node['__noInsertionPoint'] && (!preferPerformance || node.nodeType === Node.DOCUMENT_FRAGMENT_NODE);\n\n if (needsSlotFinding || needsScoping) {\n // NOTE: avoid node.removeChild as this *can* trigger another patched\n // method (e.g. custom elements) and we want only the shady method to run.\n // The following table describes what style scoping actions should happen as a result of this insertion.\n // document -> shadowRoot: replace\n // shadowRoot -> shadowRoot: replace\n // shadowRoot -> shadowRoot of same type: do nothing\n // shadowRoot -> document: allow unscoping\n // document -> document: do nothing\n // The \"same type of shadowRoot\" and \"document to document cases rely on `currentScopeIsCorrect` returning true\n if (needsScoping) {\n // in a document or disconnected tree, replace scoping if necessary\n oldScopeName = oldScopeName || currentScopeForNode(node);\n }\n\n treeVisitor(node, function (node) {\n if (needsSlotFinding && node.localName === 'slot') {\n slotsAdded.push(\n /** @type {!HTMLSlotElement} */\n node);\n }\n\n if (needsScoping) {\n replaceShadyScoping(node, newScopeName, oldScopeName);\n }\n });\n } // if a slot is added, must render containing root.\n\n\n if (this.localName === 'slot' || slotsAdded.length) {\n if (slotsAdded.length) {\n ownerRoot._addSlots(slotsAdded);\n }\n\n if (ownerRoot) {\n ownerRoot._asyncRender();\n }\n }\n\n if (utils_isTrackingLogicalChildNodes(this)) {\n link_nodes_recordInsertBefore(node, this, ref_node); // when inserting into a host with a shadowRoot with slot, use\n // `shadowRoot._asyncRender()` via `attach-shadow` module\n\n var parentData = shadyDataForNode(this);\n\n if (utils_hasShadowRootWithSlot(this)) {\n parentData.root._asyncRender();\n\n allowNativeInsert = false; // when inserting into a host with shadowRoot with NO slot, do nothing\n // as the node should not be added to composed dome anywhere.\n } else if (parentData.root) {\n allowNativeInsert = false;\n }\n }\n\n if (allowNativeInsert) {\n // if adding to a shadyRoot, add to host instead\n var container = utils_isShadyRoot(this) ?\n /** @type {ShadowRoot} */\n this.host : this; // if ref_node, get the ref_node that's actually in composed dom.\n\n if (ref_node) {\n ref_node = firstComposedNode(ref_node);\n container[NATIVE_PREFIX + 'insertBefore'](node, ref_node);\n } else {\n container[NATIVE_PREFIX + 'appendChild'](node);\n } // Since ownerDocument is not patched, it can be incorrect after this call\n // if the node is physically appended via distribution. This can result\n // in the custom elements polyfill not upgrading the node if it's in an inert doc.\n // We correct this by calling `adoptNode`.\n\n } else if (node.ownerDocument !== this.ownerDocument) {\n this.ownerDocument.adoptNode(node);\n }\n\n scheduleObserver(this, node);\n return node;\n },\n\n /**\n * @this {Node}\n * @param {Node} node\n */\n appendChild: function appendChild(node) {\n return this[SHADY_PREFIX + 'insertBefore'](node);\n },\n\n /**\n * Patched `removeChild`. Note that all dom \"removals\" are routed here.\n * Removes the given `node` from the element's `children`.\n * This method also performs dom composition.\n * @this {Node}\n * @param {Node} node\n * @param {boolean=} skipUnscoping\n */\n removeChild: function removeChild(node) {\n var skipUnscoping = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n if (this.ownerDocument !== doc) {\n return this[NATIVE_PREFIX + 'removeChild'](node);\n }\n\n if (node[SHADY_PREFIX + 'parentNode'] !== this) {\n throw Error('The node to be removed is not a child of this node: ' + node);\n }\n\n var preventNativeRemove;\n var ownerRoot = attach_shadow_ownerShadyRootForNode(node);\n\n var removingInsertionPoint = ownerRoot && ownerRoot._removeContainedSlots(node);\n\n var parentData = shadyDataForNode(this);\n\n if (utils_isTrackingLogicalChildNodes(this)) {\n link_nodes_recordRemoveChild(node, this);\n\n if (utils_hasShadowRootWithSlot(this)) {\n parentData.root._asyncRender();\n\n preventNativeRemove = true;\n }\n } // unscope a node leaving a ShadowRoot if ShadyCSS is present, and this node\n // is not going to be rescoped in `insertBefore`\n\n\n if (getScopingShim() && !skipUnscoping && ownerRoot) {\n var oldScopeName = currentScopeForNode(node);\n treeVisitor(node, function (node) {\n removeShadyScoping(node, oldScopeName);\n });\n }\n\n removeOwnerShadyRoot(node); // if removing slot, must render containing root\n\n if (ownerRoot) {\n var changeSlotContent = this && this.localName === 'slot';\n\n if (changeSlotContent) {\n preventNativeRemove = true;\n }\n\n if (removingInsertionPoint || changeSlotContent) {\n ownerRoot._asyncRender();\n }\n }\n\n if (!preventNativeRemove) {\n // if removing from a shadyRoot, remove from host instead\n var container = utils_isShadyRoot(this) ?\n /** @type {ShadowRoot} */\n this.host : this; // not guaranteed to physically be in container; e.g.\n // (1) if parent has a shadyRoot, element may or may not at distributed\n // location (could be undistributed)\n // (2) if parent is a slot, element may not ben in composed dom\n\n if (!(parentData.root || node.localName === 'slot') || container === node[NATIVE_PREFIX + 'parentNode']) {\n container[NATIVE_PREFIX + 'removeChild'](node);\n }\n }\n\n scheduleObserver(this, null, node);\n return node;\n },\n\n /**\n * @this {Node}\n * @param {Node} node\n * @param {Node=} ref_node\n */\n replaceChild: function replaceChild(node, ref_node) {\n this[SHADY_PREFIX + 'insertBefore'](node, ref_node);\n this[SHADY_PREFIX + 'removeChild'](ref_node);\n return node;\n },\n\n /**\n * @this {Node}\n * @param {boolean=} deep\n */\n cloneNode: function cloneNode(deep) {\n if (this.localName == 'template') {\n return this[NATIVE_PREFIX + 'cloneNode'](deep);\n } else {\n var n = this[NATIVE_PREFIX + 'cloneNode'](false); // Attribute nodes historically had childNodes, but they have later\n // been removed from the spec.\n // Make sure we do not do a deep clone on them for old browsers (IE11)\n\n if (deep && n.nodeType !== Node.ATTRIBUTE_NODE) {\n var c$ = this[SHADY_PREFIX + 'childNodes'];\n\n for (var i = 0, nc; i < c$.length; i++) {\n nc = c$[i][SHADY_PREFIX + 'cloneNode'](true);\n n[SHADY_PREFIX + 'appendChild'](nc);\n }\n }\n\n return n;\n }\n },\n\n /**\n * @this {Node}\n * @param {Object=} options\n */\n // TODO(sorvell): implement `options` e.g. `{ composed: boolean }`\n getRootNode: function getRootNode(options) {\n // eslint-disable-line no-unused-vars\n if (!this || !this.nodeType) {\n return;\n }\n\n var nodeData = ensureShadyDataForNode(this);\n var root = nodeData.ownerShadyRoot;\n\n if (root === undefined) {\n if (utils_isShadyRoot(this)) {\n root = this;\n nodeData.ownerShadyRoot = root;\n } else {\n var parent = this[SHADY_PREFIX + 'parentNode'];\n root = parent ? parent[SHADY_PREFIX + 'getRootNode'](options) : this; // memo-ize result for performance but only memo-ize\n // result if node is in the document. This avoids a problem where a root\n // can be cached while an element is inside a fragment.\n // If this happens and we cache the result, the value can become stale\n // because for perf we avoid processing the subtree of added fragments.\n\n if (document.documentElement[NATIVE_PREFIX + 'contains'](this)) {\n nodeData.ownerShadyRoot = root;\n }\n }\n }\n\n return root;\n },\n\n /** @this {Node} */\n contains: function contains(node) {\n return utils_contains(this, node);\n }\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/ParentNode.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n/**\n * @param {Node} node\n * @param {Function} matcher\n * @param {Function=} halter\n */\n\nfunction query(node, matcher, halter) {\n var list = [];\n queryElements(node[SHADY_PREFIX + 'childNodes'], matcher, halter, list);\n return list;\n}\n\nfunction queryElements(elements, matcher, halter, list) {\n for (var i = 0, l = elements.length, c; i < l && (c = elements[i]); i++) {\n if (c.nodeType === Node.ELEMENT_NODE && queryElement(c, matcher, halter, list)) {\n return true;\n }\n }\n}\n\nfunction queryElement(node, matcher, halter, list) {\n var result = matcher(node);\n\n if (result) {\n list.push(node);\n }\n\n if (halter && halter(result)) {\n return result;\n }\n\n queryElements(node[SHADY_PREFIX + 'childNodes'], matcher, halter, list);\n} // Needed on Element, DocumentFragment, Document\n\n\nvar ParentNodePatches = getOwnPropertyDescriptors({\n /** @this {Element} */\n get firstElementChild() {\n var nodeData = shadyDataForNode(this);\n\n if (nodeData && nodeData.firstChild !== undefined) {\n var n = this[SHADY_PREFIX + 'firstChild'];\n\n while (n && n.nodeType !== Node.ELEMENT_NODE) {\n n = n[SHADY_PREFIX + 'nextSibling'];\n }\n\n return n;\n } else {\n return this[NATIVE_PREFIX + 'firstElementChild'];\n }\n },\n\n /** @this {Element} */\n get lastElementChild() {\n var nodeData = shadyDataForNode(this);\n\n if (nodeData && nodeData.lastChild !== undefined) {\n var n = this[SHADY_PREFIX + 'lastChild'];\n\n while (n && n.nodeType !== Node.ELEMENT_NODE) {\n n = n[SHADY_PREFIX + 'previousSibling'];\n }\n\n return n;\n } else {\n return this[NATIVE_PREFIX + 'lastElementChild'];\n }\n },\n\n /** @this {Element} */\n get children() {\n if (!utils_isTrackingLogicalChildNodes(this)) {\n return this[NATIVE_PREFIX + 'children'];\n }\n\n return createPolyfilledHTMLCollection(Array.prototype.filter.call(this[SHADY_PREFIX + 'childNodes'], function (n) {\n return n.nodeType === Node.ELEMENT_NODE;\n }));\n },\n\n /** @this {Element} */\n get childElementCount() {\n var children = this[SHADY_PREFIX + 'children'];\n\n if (children) {\n return children.length;\n }\n\n return 0;\n }\n\n});\nvar QueryPatches = getOwnPropertyDescriptors({\n // TODO(sorvell): consider doing native QSA and filtering results.\n\n /**\n * @this {Element}\n * @param {string} selector\n */\n querySelector: function querySelector(selector) {\n // match selector and halt on first result.\n var result = query(this, function (n) {\n return matchesSelector(n, selector);\n }, function (n) {\n return Boolean(n);\n })[0];\n return result || null;\n },\n\n /**\n * @this {Element}\n * @param {string} selector\n * @param {boolean} useNative\n */\n // TODO(sorvell): `useNative` option relies on native querySelectorAll and\n // misses distributed nodes, see\n // https://github.com/webcomponents/shadydom/pull/210#issuecomment-361435503\n querySelectorAll: function querySelectorAll(selector, useNative) {\n if (useNative) {\n var o = Array.prototype.slice.call(this[NATIVE_PREFIX + 'querySelectorAll'](selector));\n var root = this[SHADY_PREFIX + 'getRootNode']();\n return o.filter(function (e) {\n return e[SHADY_PREFIX + 'getRootNode']() == root;\n });\n }\n\n return query(this, function (n) {\n return matchesSelector(n, selector);\n });\n }\n}); // Create a custom `ParentNodeDocumentOrFragment` that optionally does not\n// mixin querySelector/All; this is a performance optimization.\n\nvar ParentNodeDocumentOrFragmentPatches = settings.preferPerformance ? Object.assign({}, ParentNodePatches) : ParentNodePatches;\nObject.assign(ParentNodePatches, QueryPatches);\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/DocumentOrFragment.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\nvar DocumentOrFragmentPatches = getOwnPropertyDescriptors({\n /**\n * @this {Element}\n * @param {string} id\n */\n getElementById: function getElementById(id) {\n if (id === '') {\n return null;\n }\n\n var result = query(this, function (n) {\n return n.id == id;\n }, function (n) {\n return Boolean(n);\n })[0];\n return result || null;\n }\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/DocumentOrShadowRoot.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n\nfunction getDocumentActiveElement() {\n if (settings.hasDescriptors) {\n return document[NATIVE_PREFIX + 'activeElement'];\n } else {\n return document.activeElement;\n }\n}\n\nvar DocumentOrShadowRootPatches = getOwnPropertyDescriptors({\n /** @this {Document|ShadowRoot} */\n get activeElement() {\n var active = getDocumentActiveElement(); // In IE11, activeElement might be an empty object if the document is\n // contained in an iframe.\n // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10998788/\n\n if (!active || !active.nodeType) {\n return null;\n }\n\n var isShadyRoot = !!utils_isShadyRoot(this);\n\n if (this !== document) {\n // If this node isn't a document or shady root, then it doesn't have\n // an active element.\n if (!isShadyRoot) {\n return null;\n } // If this shady root's host is the active element or the active\n // element is not a descendant of the host (in the composed tree),\n // then it doesn't have an active element.\n\n\n if (this.host === active || !this.host[NATIVE_PREFIX + 'contains'](active)) {\n return null;\n }\n } // This node is either the document or a shady root of which the active\n // element is a (composed) descendant of its host; iterate upwards to\n // find the active element's most shallow host within it.\n\n\n var activeRoot = attach_shadow_ownerShadyRootForNode(active);\n\n while (activeRoot && activeRoot !== this) {\n active = activeRoot.host;\n activeRoot = attach_shadow_ownerShadyRootForNode(active);\n }\n\n if (this === document) {\n // This node is the document, so activeRoot should be null.\n return activeRoot ? null : active;\n } else {\n // This node is a non-document shady root, and it should be\n // activeRoot.\n return activeRoot === this ? active : null;\n }\n }\n\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/ElementOrShadowRoot.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n\n/** @type {!Document} */\n\nvar ElementOrShadowRoot_inertDoc = document.implementation.createHTMLDocument('inert');\nvar ElementOrShadowRootPatches = getOwnPropertyDescriptors({\n /** @this {Element} */\n get innerHTML() {\n if (utils_isTrackingLogicalChildNodes(this)) {\n var content = this.localName === 'template' ?\n /** @type {HTMLTemplateElement} */\n this.content : this;\n return getInnerHTML(content, function (e) {\n return e[SHADY_PREFIX + 'childNodes'];\n });\n } else {\n return this[NATIVE_PREFIX + 'innerHTML'];\n }\n },\n\n /**\n * @this {Element}\n * @param {string} value\n */\n set innerHTML(value) {\n if (this.localName === 'template') {\n this[NATIVE_PREFIX + 'innerHTML'] = value;\n } else {\n Node_clearNode(this);\n var containerName = this.localName || 'div';\n var htmlContainer;\n\n if (!this.namespaceURI || this.namespaceURI === ElementOrShadowRoot_inertDoc.namespaceURI) {\n htmlContainer = ElementOrShadowRoot_inertDoc.createElement(containerName);\n } else {\n htmlContainer = ElementOrShadowRoot_inertDoc.createElementNS(this.namespaceURI, containerName);\n }\n\n if (settings.hasDescriptors) {\n htmlContainer[NATIVE_PREFIX + 'innerHTML'] = value;\n } else {\n htmlContainer.innerHTML = value;\n }\n\n var firstChild;\n\n while (firstChild = htmlContainer[SHADY_PREFIX + 'firstChild']) {\n this[SHADY_PREFIX + 'insertBefore'](firstChild);\n }\n }\n }\n\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/ShadowRoot.js\nfunction ShadowRoot_typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { ShadowRoot_typeof = function _typeof(obj) { return typeof obj; }; } else { ShadowRoot_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return ShadowRoot_typeof(obj); }\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\nvar ShadowRootPatches = getOwnPropertyDescriptors({\n /**\n * @this {ShadowRoot}\n * @param {string} type\n * @param {Function} fn\n * @param {Object|boolean=} optionsOrCapture\n */\n addEventListener: function addEventListener(type, fn, optionsOrCapture) {\n if (ShadowRoot_typeof(optionsOrCapture) !== 'object') {\n optionsOrCapture = {\n capture: Boolean(optionsOrCapture)\n };\n }\n\n optionsOrCapture.__shadyTarget = this;\n this.host[SHADY_PREFIX + 'addEventListener'](type, fn, optionsOrCapture);\n },\n\n /**\n * @this {ShadowRoot}\n * @param {string} type\n * @param {Function} fn\n * @param {Object|boolean=} optionsOrCapture\n */\n removeEventListener: function removeEventListener(type, fn, optionsOrCapture) {\n if (ShadowRoot_typeof(optionsOrCapture) !== 'object') {\n optionsOrCapture = {\n capture: Boolean(optionsOrCapture)\n };\n }\n\n optionsOrCapture.__shadyTarget = this;\n this.host[SHADY_PREFIX + 'removeEventListener'](type, fn, optionsOrCapture);\n }\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patch-shadyRoot.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n\n\n\n\n\n\n/**\n * @param {!Object} proto\n * @param {string=} prefix\n */\n\nvar patch_shadyRoot_patchShadyAccessors = function patchShadyAccessors(proto, prefix) {\n patchProperties(proto, ShadowRootPatches, prefix);\n patchProperties(proto, DocumentOrShadowRootPatches, prefix);\n patchProperties(proto, ElementOrShadowRootPatches, prefix); // We ensure ParentNode accessors since these do not exist in Edge/IE on DocumentFragments.\n\n patchProperties(proto, ParentNodePatches, prefix); // Ensure `shadowRoot` has basic descriptors when we cannot rely\n // on them coming from DocumentFragment.\n //\n // Case 1, noPatching: Because we want noPatch ShadyRoots to have native property\n // names so that they do not have to be wrapped...\n // When we do *not* patch Node/DocumentFragment.prototype\n // we must manually install those properties on ShadyRoot's prototype.\n // Note, it's important to only install these in this mode so as not to stomp\n // over CustomElements polyfill's patches on Node/DocumentFragment methods.\n\n if (settings.noPatch && !prefix) {\n patchProperties(proto, NodePatches, prefix);\n patchProperties(proto, DocumentOrFragmentPatches, prefix); // Case 2, bad descriptors: Ensure accessors are on ShadowRoot.\n // These descriptors are normally used for instance patching but because\n // ShadyRoot can always be patched, just do it to the prototype.\n } else if (!settings.hasDescriptors) {\n patchProperties(proto, OutsideDescriptors);\n patchProperties(proto, InsideDescriptors);\n }\n};\n\nvar patch_shadyRoot_patchShadyRoot = function patchShadyRoot(proto) {\n proto.__proto__ = DocumentFragment.prototype; // patch both prefixed and not, even when noPatch == true.\n\n patch_shadyRoot_patchShadyAccessors(proto, SHADY_PREFIX);\n patch_shadyRoot_patchShadyAccessors(proto); // Ensure native properties are all safely wrapped since ShadowRoot is not an\n // actual DocumentFragment instance.\n\n Object.defineProperties(proto, {\n nodeType: {\n value: Node.DOCUMENT_FRAGMENT_NODE,\n configurable: true\n },\n nodeName: {\n value: '#document-fragment',\n configurable: true\n },\n nodeValue: {\n value: null,\n configurable: true\n }\n }); // make undefined\n\n ['localName', 'namespaceURI', 'prefix'].forEach(function (prop) {\n Object.defineProperty(proto, prop, {\n value: undefined,\n configurable: true\n });\n }); // defer properties to host\n\n ['ownerDocument', 'baseURI', 'isConnected'].forEach(function (prop) {\n Object.defineProperty(proto, prop, {\n /** @this {ShadowRoot} */\n get: function get() {\n return this.host[prop];\n },\n configurable: true\n });\n });\n};\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/attach-shadow.js\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction attach_shadow_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction attach_shadow_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction attach_shadow_createClass(Constructor, protoProps, staticProps) { if (protoProps) attach_shadow_defineProperties(Constructor.prototype, protoProps); if (staticProps) attach_shadow_defineProperties(Constructor, staticProps); return Constructor; }\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n\n\n\n // Do not export this object. It must be passed as the first argument to the\n// ShadyRoot constructor in `attachShadow` to prevent the constructor from\n// throwing. This prevents the user from being able to manually construct a\n// ShadyRoot (i.e. `new ShadowRoot()`).\n\nvar ShadyRootConstructionToken = {};\nvar CATCHALL_NAME = '__catchall';\nvar SHADYROOT_NAME = 'ShadyRoot';\nvar MODE_CLOSED = 'closed';\nvar isRendering = settings['deferConnectionCallbacks'] && document.readyState === 'loading';\nvar rootRendered;\n\nfunction ancestorList(node) {\n var ancestors = [];\n\n do {\n ancestors.unshift(node);\n } while (node = node[SHADY_PREFIX + 'parentNode']);\n\n return ancestors;\n}\n/**\n * @extends {ShadowRoot}\n */\n\n\nvar attach_shadow_ShadyRoot =\n/*#__PURE__*/\nfunction () {\n function ShadyRoot(token, host, options) {\n attach_shadow_classCallCheck(this, ShadyRoot);\n\n if (token !== ShadyRootConstructionToken) {\n throw new TypeError('Illegal constructor');\n } // NOTE: set a fake local name so this element can be\n // distinguished from a DocumentFragment when patching.\n // FF doesn't allow this to be `localName`\n\n\n this._localName = SHADYROOT_NAME; // root <=> host\n\n this.host = host;\n /** @type {!string|undefined} */\n\n this.mode = options && options.mode;\n link_nodes_recordChildNodes(host);\n var hostData = ensureShadyDataForNode(host);\n /** @type {!ShadyRoot} */\n\n hostData.root = this;\n hostData.publicRoot = this.mode !== MODE_CLOSED ? this : null; // setup root\n\n var rootData = ensureShadyDataForNode(this);\n rootData.firstChild = rootData.lastChild = rootData.parentNode = rootData.nextSibling = rootData.previousSibling = null;\n rootData.childNodes = []; // state flags\n\n this._renderPending = false;\n this._hasRendered = false; // marsalled lazily\n\n this._slotList = null;\n /** @type {Object>} */\n\n this._slotMap = null;\n this._pendingSlots = null; // NOTE: optimization flag, only require an asynchronous render\n // to record parsed children if flag is not set.\n\n if (settings['preferPerformance']) {\n var n;\n\n while (n = host[NATIVE_PREFIX + 'firstChild']) {\n host[NATIVE_PREFIX + 'removeChild'](n);\n }\n } else {\n this._asyncRender();\n }\n }\n\n attach_shadow_createClass(ShadyRoot, [{\n key: \"_asyncRender\",\n value: function _asyncRender() {\n var _this = this;\n\n if (!this._renderPending) {\n this._renderPending = true;\n enqueue(function () {\n return _this._render();\n });\n }\n } // returns the oldest renderPending ancestor root.\n\n }, {\n key: \"_getPendingDistributionRoot\",\n value: function _getPendingDistributionRoot() {\n var renderRoot;\n var root = this;\n\n while (root) {\n if (root._renderPending) {\n renderRoot = root;\n }\n\n root = root._getDistributionParent();\n }\n\n return renderRoot;\n } // Returns the shadyRoot `this.host` if `this.host`\n // has children that require distribution.\n\n }, {\n key: \"_getDistributionParent\",\n value: function _getDistributionParent() {\n var root = this.host[SHADY_PREFIX + 'getRootNode']();\n\n if (!utils_isShadyRoot(root)) {\n return;\n }\n\n var nodeData = shadyDataForNode(this.host);\n\n if (nodeData && nodeData.__childSlotCount > 0) {\n return root;\n }\n } // Renders the top most render pending shadowRoot in the distribution tree.\n // This is safe because when a distribution parent renders, all children render.\n\n }, {\n key: \"_render\",\n value: function _render() {\n // If this root is not pending, it needs no rendering work. Any pending\n // parent that needs to render wll cause this root to render.\n var root = this._renderPending && this._getPendingDistributionRoot();\n\n if (root) {\n root._renderSelf();\n }\n }\n }, {\n key: \"_flushInitial\",\n value: function _flushInitial() {\n if (!this._hasRendered && this._renderPending) {\n this._render();\n }\n }\n /** @override */\n\n }, {\n key: \"_renderSelf\",\n value: function _renderSelf() {\n // track rendering state.\n var wasRendering = isRendering;\n isRendering = true;\n this._renderPending = false;\n\n if (this._slotList) {\n this._distribute();\n\n this._compose();\n } // NOTE: optimization flag, only process parsed children\n // if optimization flag is not set.\n // on initial render remove any undistributed children.\n\n\n if (!settings['preferPerformance'] && !this._hasRendered) {\n var c$ = this.host[SHADY_PREFIX + 'childNodes'];\n\n for (var i = 0, l = c$.length; i < l; i++) {\n var child = c$[i];\n var data = shadyDataForNode(child);\n\n if (child[NATIVE_PREFIX + 'parentNode'] === this.host && (child.localName === 'slot' || !data.assignedSlot)) {\n this.host[NATIVE_PREFIX + 'removeChild'](child);\n }\n }\n }\n\n this._hasRendered = true;\n isRendering = wasRendering;\n\n if (rootRendered) {\n rootRendered();\n }\n }\n }, {\n key: \"_distribute\",\n value: function _distribute() {\n this._validateSlots(); // capture # of previously assigned nodes to help determine if dirty.\n\n\n for (var i = 0, slot; i < this._slotList.length; i++) {\n slot = this._slotList[i];\n\n this._clearSlotAssignedNodes(slot);\n } // distribute host children.\n\n\n for (var n = this.host[SHADY_PREFIX + 'firstChild']; n; n = n[SHADY_PREFIX + 'nextSibling']) {\n this._distributeNodeToSlot(n);\n } // fallback content, slotchange, and dirty roots\n\n\n for (var _i = 0; _i < this._slotList.length; _i++) {\n var _slot = this._slotList[_i];\n var slotData = shadyDataForNode(_slot); // distribute fallback content\n\n if (!slotData.assignedNodes.length) {\n for (var _n = _slot[SHADY_PREFIX + 'firstChild']; _n; _n = _n[SHADY_PREFIX + 'nextSibling']) {\n this._distributeNodeToSlot(_n, _slot);\n }\n }\n\n var slotParentData = shadyDataForNode(_slot[SHADY_PREFIX + 'parentNode']);\n var slotParentRoot = slotParentData && slotParentData.root;\n\n if (slotParentRoot && (slotParentRoot._hasInsertionPoint() || slotParentRoot._renderPending)) {\n slotParentRoot._renderSelf();\n }\n\n this._addAssignedToFlattenedNodes(slotData.flattenedNodes, slotData.assignedNodes);\n\n var prevAssignedNodes = slotData._previouslyAssignedNodes;\n\n if (prevAssignedNodes) {\n for (var _i2 = 0; _i2 < prevAssignedNodes.length; _i2++) {\n shadyDataForNode(prevAssignedNodes[_i2])._prevAssignedSlot = null;\n }\n\n slotData._previouslyAssignedNodes = null; // dirty if previously less assigned nodes than previously assigned.\n\n if (prevAssignedNodes.length > slotData.assignedNodes.length) {\n slotData.dirty = true;\n }\n }\n /* Note: A slot is marked dirty whenever a node is newly assigned to it\n or a node is assigned to a different slot (done in `_distributeNodeToSlot`)\n or if the number of nodes assigned to the slot has decreased (done above);\n */\n\n\n if (slotData.dirty) {\n slotData.dirty = false;\n\n this._fireSlotChange(_slot);\n }\n }\n }\n /**\n * Distributes given `node` to the appropriate slot based on its `slot`\n * attribute. If `forcedSlot` is given, then the node is distributed to the\n * `forcedSlot`.\n * Note: slot to which the node is assigned will be marked dirty for firing\n * `slotchange`.\n * @param {Node} node\n * @param {Node=} forcedSlot\n *\n */\n\n }, {\n key: \"_distributeNodeToSlot\",\n value: function _distributeNodeToSlot(node, forcedSlot) {\n var nodeData = ensureShadyDataForNode(node);\n var oldSlot = nodeData._prevAssignedSlot;\n nodeData._prevAssignedSlot = null;\n var slot = forcedSlot;\n\n if (!slot) {\n var name = node[SHADY_PREFIX + 'slot'] || CATCHALL_NAME;\n var list = this._slotMap[name];\n slot = list && list[0];\n }\n\n if (slot) {\n var slotData = ensureShadyDataForNode(slot);\n slotData.assignedNodes.push(node);\n nodeData.assignedSlot = slot;\n } else {\n nodeData.assignedSlot = undefined;\n }\n\n if (oldSlot !== nodeData.assignedSlot) {\n if (nodeData.assignedSlot) {\n ensureShadyDataForNode(nodeData.assignedSlot).dirty = true;\n }\n }\n }\n /**\n * Clears the assignedNodes tracking data for a given `slot`. Note, the current\n * assigned node data is tracked (via _previouslyAssignedNodes and\n * _prevAssignedSlot) to see if `slotchange` should fire. This data may be out\n * of date at this time because the assigned nodes may have already been\n * distributed to another root. This is ok since this data is only used to\n * track changes.\n * @param {HTMLSlotElement} slot\n */\n\n }, {\n key: \"_clearSlotAssignedNodes\",\n value: function _clearSlotAssignedNodes(slot) {\n var slotData = shadyDataForNode(slot);\n var n$ = slotData.assignedNodes;\n slotData.assignedNodes = [];\n slotData.flattenedNodes = [];\n slotData._previouslyAssignedNodes = n$;\n\n if (n$) {\n for (var i = 0; i < n$.length; i++) {\n var n = shadyDataForNode(n$[i]);\n n._prevAssignedSlot = n.assignedSlot; // only clear if it was previously set to this slot;\n // this helps ensure that if the node has otherwise been distributed\n // ignore it.\n\n if (n.assignedSlot === slot) {\n n.assignedSlot = null;\n }\n }\n }\n }\n }, {\n key: \"_addAssignedToFlattenedNodes\",\n value: function _addAssignedToFlattenedNodes(flattened, assigned) {\n for (var i = 0, n; i < assigned.length && (n = assigned[i]); i++) {\n if (n.localName == 'slot') {\n var nestedAssigned = shadyDataForNode(n).assignedNodes;\n\n if (nestedAssigned && nestedAssigned.length) {\n this._addAssignedToFlattenedNodes(flattened, nestedAssigned);\n }\n } else {\n flattened.push(assigned[i]);\n }\n }\n }\n }, {\n key: \"_fireSlotChange\",\n value: function _fireSlotChange(slot) {\n // NOTE: cannot bubble correctly here so not setting bubbles: true\n // Safari tech preview does not bubble but chrome does\n // Spec says it bubbles (https://dom.spec.whatwg.org/#mutation-observers)\n slot[NATIVE_PREFIX + 'dispatchEvent'](new Event('slotchange'));\n var slotData = shadyDataForNode(slot);\n\n if (slotData.assignedSlot) {\n this._fireSlotChange(slotData.assignedSlot);\n }\n } // Reify dom such that it is at its correct rendering position\n // based on logical distribution.\n // NOTE: here we only compose parents of elements and not the\n // shadowRoot into the host. The latter is performend via a fast path\n // in the `logical-mutation`.insertBefore.\n\n }, {\n key: \"_compose\",\n value: function _compose() {\n var slots = this._slotList;\n var composeList = [];\n\n for (var i = 0; i < slots.length; i++) {\n var parent = slots[i][SHADY_PREFIX + 'parentNode'];\n /* compose node only if:\n (1) parent does not have a shadowRoot since shadowRoot has already\n composed into the host\n (2) we're not already composing it\n [consider (n^2) but rare better than Set]\n */\n\n var parentData = shadyDataForNode(parent);\n\n if (!(parentData && parentData.root) && composeList.indexOf(parent) < 0) {\n composeList.push(parent);\n }\n }\n\n for (var _i3 = 0; _i3 < composeList.length; _i3++) {\n var node = composeList[_i3];\n var targetNode = node === this ? this.host : node;\n\n this._updateChildNodes(targetNode, this._composeNode(node));\n }\n } // Returns the list of nodes which should be rendered inside `node`.\n\n }, {\n key: \"_composeNode\",\n value: function _composeNode(node) {\n var children = [];\n var c$ = node[SHADY_PREFIX + 'childNodes'];\n\n for (var i = 0; i < c$.length; i++) {\n var child = c$[i]; // Note: if we see a slot here, the nodes are guaranteed to need to be\n // composed here. This is because if there is redistribution, it has\n // already been handled by this point.\n\n if (this._isInsertionPoint(child)) {\n var flattenedNodes = shadyDataForNode(child).flattenedNodes;\n\n for (var j = 0; j < flattenedNodes.length; j++) {\n var distributedNode = flattenedNodes[j];\n children.push(distributedNode);\n }\n } else {\n children.push(child);\n }\n }\n\n return children;\n }\n }, {\n key: \"_isInsertionPoint\",\n value: function _isInsertionPoint(node) {\n return node.localName == 'slot';\n } // Ensures that the rendered node list inside `container` is `children`.\n\n }, {\n key: \"_updateChildNodes\",\n value: function _updateChildNodes(container, children) {\n var composed = Array.prototype.slice.call(container[NATIVE_PREFIX + 'childNodes']);\n var splices = calculateSplices(children, composed); // process removals\n\n for (var i = 0, d = 0, s; i < splices.length && (s = splices[i]); i++) {\n for (var j = 0, n; j < s.removed.length && (n = s.removed[j]); j++) {\n // check if the node is still where we expect it is before trying\n // to remove it; this can happen if we move a node and\n // then schedule its previous host for distribution resulting in\n // the node being removed here.\n if (n[NATIVE_PREFIX + 'parentNode'] === container) {\n container[NATIVE_PREFIX + 'removeChild'](n);\n } // TODO(sorvell): avoid the need for splicing here.\n\n\n composed.splice(s.index + d, 1);\n }\n\n d -= s.addedCount;\n } // process adds\n\n\n for (var _i4 = 0, _s, next; _i4 < splices.length && (_s = splices[_i4]); _i4++) {\n //eslint-disable-line no-redeclare\n next = composed[_s.index];\n\n for (var _j = _s.index, _n2; _j < _s.index + _s.addedCount; _j++) {\n _n2 = children[_j];\n container[NATIVE_PREFIX + 'insertBefore'](_n2, next);\n composed.splice(_j, 0, _n2);\n }\n }\n }\n }, {\n key: \"_ensureSlotData\",\n value: function _ensureSlotData() {\n this._pendingSlots = this._pendingSlots || [];\n this._slotList = this._slotList || [];\n this._slotMap = this._slotMap || {};\n }\n }, {\n key: \"_addSlots\",\n value: function _addSlots(slots) {\n var _this$_pendingSlots;\n\n this._ensureSlotData();\n\n (_this$_pendingSlots = this._pendingSlots).push.apply(_this$_pendingSlots, _toConsumableArray(slots));\n }\n }, {\n key: \"_validateSlots\",\n value: function _validateSlots() {\n if (this._pendingSlots && this._pendingSlots.length) {\n this._mapSlots(this._pendingSlots);\n\n this._pendingSlots = [];\n }\n }\n /**\n * Adds the given slots. Slots are maintained in an dom-ordered list.\n * In addition a map of name to slot is updated.\n */\n\n }, {\n key: \"_mapSlots\",\n value: function _mapSlots(slots) {\n var slotNamesToSort;\n\n for (var i = 0; i < slots.length; i++) {\n var slot = slots[i]; // ensure insertionPoints's and their parents have logical dom info.\n // save logical tree info\n // a. for shadyRoot\n // b. for insertion points (fallback)\n // c. for parents of insertion points\n\n link_nodes_recordChildNodes(slot);\n var slotParent = slot[SHADY_PREFIX + 'parentNode'];\n link_nodes_recordChildNodes(slotParent);\n var slotParentData = shadyDataForNode(slotParent);\n slotParentData.__childSlotCount = (slotParentData.__childSlotCount || 0) + 1;\n\n var name = this._nameForSlot(slot);\n\n if (this._slotMap[name]) {\n slotNamesToSort = slotNamesToSort || {};\n slotNamesToSort[name] = true;\n\n this._slotMap[name].push(slot);\n } else {\n this._slotMap[name] = [slot];\n }\n\n this._slotList.push(slot);\n }\n\n if (slotNamesToSort) {\n for (var n in slotNamesToSort) {\n this._slotMap[n] = this._sortSlots(this._slotMap[n]);\n }\n }\n }\n }, {\n key: \"_nameForSlot\",\n value: function _nameForSlot(slot) {\n var name = slot['name'] || slot.getAttribute('name') || CATCHALL_NAME;\n slot.__slotName = name;\n return name;\n }\n /**\n * Slots are kept in an ordered list. Slots with the same name\n * are sorted here by tree order.\n */\n\n }, {\n key: \"_sortSlots\",\n value: function _sortSlots(slots) {\n // NOTE: Cannot use `compareDocumentPosition` because it's not polyfilled,\n // but the code here could be used to polyfill the preceeding/following info\n // in `compareDocumentPosition`.\n return slots.sort(function (a, b) {\n var listA = ancestorList(a);\n var listB = ancestorList(b);\n\n for (var i = 0; i < listA.length; i++) {\n var nA = listA[i];\n var nB = listB[i];\n\n if (nA !== nB) {\n var c$ = Array.from(nA[SHADY_PREFIX + 'parentNode'][SHADY_PREFIX + 'childNodes']);\n return c$.indexOf(nA) - c$.indexOf(nB);\n }\n }\n });\n }\n /**\n * Removes from tracked slot data any slots contained within `container` and\n * then updates the tracked data (_slotList and _slotMap).\n * Any removed slots also have their `assignedNodes` removed from comopsed dom.\n */\n\n }, {\n key: \"_removeContainedSlots\",\n value: function _removeContainedSlots(container) {\n if (!this._slotList) {\n return;\n }\n\n this._validateSlots();\n\n var didRemove;\n var map = this._slotMap;\n\n for (var n in map) {\n var slots = map[n];\n\n for (var i = 0; i < slots.length; i++) {\n var slot = slots[i];\n\n if (utils_contains(container, slot)) {\n slots.splice(i, 1);\n\n var x = this._slotList.indexOf(slot);\n\n if (x >= 0) {\n this._slotList.splice(x, 1);\n\n var slotParentData = shadyDataForNode(slot[SHADY_PREFIX + 'parentNode']);\n\n if (slotParentData && slotParentData.__childSlotCount) {\n slotParentData.__childSlotCount--;\n }\n }\n\n i--;\n\n this._removeFlattenedNodes(slot);\n\n didRemove = true;\n }\n }\n }\n\n return didRemove;\n }\n }, {\n key: \"_updateSlotName\",\n value: function _updateSlotName(slot) {\n if (!this._slotList) {\n return;\n } // make sure slotMap is initialized with this slot\n\n\n this._validateSlots();\n\n var oldName = slot.__slotName;\n\n var name = this._nameForSlot(slot);\n\n if (name === oldName) {\n return;\n } // remove from existing tracking\n\n\n var slots = this._slotMap[oldName];\n var i = slots.indexOf(slot);\n\n if (i >= 0) {\n slots.splice(i, 1);\n } // add to new location and sort if nedessary\n\n\n var list = this._slotMap[name] || (this._slotMap[name] = []);\n list.push(slot);\n\n if (list.length > 1) {\n this._slotMap[name] = this._sortSlots(list);\n }\n }\n }, {\n key: \"_removeFlattenedNodes\",\n value: function _removeFlattenedNodes(slot) {\n var data = shadyDataForNode(slot);\n var n$ = data.flattenedNodes;\n\n if (n$) {\n for (var i = 0; i < n$.length; i++) {\n var node = n$[i];\n var parent = node[NATIVE_PREFIX + 'parentNode'];\n\n if (parent) {\n parent[NATIVE_PREFIX + 'removeChild'](node);\n }\n }\n }\n\n data.flattenedNodes = [];\n data.assignedNodes = [];\n }\n }, {\n key: \"_hasInsertionPoint\",\n value: function _hasInsertionPoint() {\n this._validateSlots();\n\n return Boolean(this._slotList && this._slotList.length);\n }\n }]);\n\n return ShadyRoot;\n}();\n\npatch_shadyRoot_patchShadyRoot(attach_shadow_ShadyRoot.prototype);\n\n/**\n Implements a pared down version of ShadowDOM's scoping, which is easy to\n polyfill across browsers.\n*/\n\nvar attach_shadow_attachShadow = function attachShadow(host, options) {\n if (!host) {\n throw new Error('Must provide a host.');\n }\n\n if (!options) {\n throw new Error('Not enough arguments.');\n }\n\n return new attach_shadow_ShadyRoot(ShadyRootConstructionToken, host, options);\n}; // Mitigate connect/disconnect spam by wrapping custom element classes.\n\nif (window['customElements'] && settings.inUse && !settings['preferPerformance']) {\n // process connect/disconnect after roots have rendered to avoid\n // issues with reaction stack.\n var connectMap = new Map();\n\n rootRendered = function rootRendered() {\n // allow elements to connect\n // save map state (without needing polyfills on IE11)\n var r = [];\n connectMap.forEach(function (v, k) {\n r.push([k, v]);\n });\n connectMap.clear();\n\n for (var i = 0; i < r.length; i++) {\n var e = r[i][0],\n value = r[i][1];\n\n if (value) {\n e.__shadydom_connectedCallback();\n } else {\n e.__shadydom_disconnectedCallback();\n }\n }\n }; // Document is in loading state and flag is set (deferConnectionCallbacks)\n // so process connection stack when `readystatechange` fires.\n\n\n if (isRendering) {\n document.addEventListener('readystatechange', function () {\n isRendering = false;\n rootRendered();\n }, {\n once: true\n });\n }\n /*\n * (1) elements can only be connected/disconnected if they are in the expected\n * state.\n * (2) never run connect/disconnect during rendering to avoid reaction stack issues.\n */\n\n\n var ManageConnect = function ManageConnect(base, connected, disconnected) {\n var counter = 0;\n var connectFlag = \"__isConnected\".concat(counter++);\n\n if (connected || disconnected) {\n /** @this {!HTMLElement} */\n base.prototype.connectedCallback = base.prototype.__shadydom_connectedCallback = function () {\n // if rendering defer connected\n // otherwise connect only if we haven't already\n if (isRendering) {\n connectMap.set(this, true);\n } else if (!this[connectFlag]) {\n this[connectFlag] = true;\n\n if (connected) {\n connected.call(this);\n }\n }\n };\n /** @this {!HTMLElement} */\n\n\n base.prototype.disconnectedCallback = base.prototype.__shadydom_disconnectedCallback = function () {\n // if rendering, cancel a pending connection and queue disconnect,\n // otherwise disconnect only if a connection has been allowed\n if (isRendering) {\n // This is necessary only because calling removeChild\n // on a node that requires distribution leaves it in the DOM tree\n // until distribution.\n // NOTE: remember this is checking the patched isConnected to determine\n // if the node is in the logical tree.\n if (!this.isConnected) {\n connectMap.set(this, false);\n }\n } else if (this[connectFlag]) {\n this[connectFlag] = false;\n\n if (disconnected) {\n disconnected.call(this);\n }\n }\n };\n }\n\n return base;\n };\n\n var define = window['customElements']['define']; // NOTE: Instead of patching customElements.define,\n // re-define on the CustomElementRegistry.prototype.define\n // for Safari 10 compatibility (it's flakey otherwise).\n\n Object.defineProperty(window['CustomElementRegistry'].prototype, 'define', {\n value: function value(name, constructor) {\n var connected = constructor.prototype.connectedCallback;\n var disconnected = constructor.prototype.disconnectedCallback;\n define.call(window['customElements'], name, ManageConnect(constructor, connected, disconnected)); // unpatch connected/disconnected on class; custom elements tears this off\n // so the patch is maintained, but if the user calls these methods for\n // e.g. testing, they will be as expected.\n\n constructor.prototype.connectedCallback = connected;\n constructor.prototype.disconnectedCallback = disconnected;\n }\n });\n}\n/** @return {!ShadyRoot|undefined} */\n\n\nvar attach_shadow_ownerShadyRootForNode = function ownerShadyRootForNode(node) {\n var root = node[SHADY_PREFIX + 'getRootNode']();\n\n if (utils_isShadyRoot(root)) {\n return root;\n }\n};\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/wrapper.js\nfunction wrapper_classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction wrapper_defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction wrapper_createClass(Constructor, protoProps, staticProps) { if (protoProps) wrapper_defineProperties(Constructor.prototype, protoProps); if (staticProps) wrapper_defineProperties(Constructor, staticProps); return Constructor; }\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n/** @implements {IWrapper} */\n\nvar wrapper_Wrapper =\n/*#__PURE__*/\nfunction () {\n /** @param {!Node} node */\n function Wrapper(node) {\n wrapper_classCallCheck(this, Wrapper);\n\n this.node = node;\n } // node\n\n\n wrapper_createClass(Wrapper, [{\n key: \"addEventListener\",\n value: function addEventListener(name, fn, options) {\n return this.node[SHADY_PREFIX + 'addEventListener'](name, fn, options);\n }\n }, {\n key: \"removeEventListener\",\n value: function removeEventListener(name, fn, options) {\n return this.node[SHADY_PREFIX + 'removeEventListener'](name, fn, options);\n }\n }, {\n key: \"appendChild\",\n value: function appendChild(node) {\n return this.node[SHADY_PREFIX + 'appendChild'](node);\n }\n }, {\n key: \"insertBefore\",\n value: function insertBefore(node, ref_node) {\n return this.node[SHADY_PREFIX + 'insertBefore'](node, ref_node);\n }\n }, {\n key: \"removeChild\",\n value: function removeChild(node) {\n return this.node[SHADY_PREFIX + 'removeChild'](node);\n }\n }, {\n key: \"replaceChild\",\n value: function replaceChild(node, ref_node) {\n return this.node[SHADY_PREFIX + 'replaceChild'](node, ref_node);\n }\n }, {\n key: \"cloneNode\",\n value: function cloneNode(deep) {\n return this.node[SHADY_PREFIX + 'cloneNode'](deep);\n }\n }, {\n key: \"getRootNode\",\n value: function getRootNode(options) {\n return this.node[SHADY_PREFIX + 'getRootNode'](options);\n }\n }, {\n key: \"contains\",\n value: function contains(node) {\n return this.node[SHADY_PREFIX + 'contains'](node);\n }\n }, {\n key: \"dispatchEvent\",\n value: function dispatchEvent(event) {\n return this.node[SHADY_PREFIX + 'dispatchEvent'](event);\n } // element\n\n }, {\n key: \"setAttribute\",\n value: function setAttribute(name, value) {\n this.node[SHADY_PREFIX + 'setAttribute'](name, value);\n } // NOTE: not needed, just here for balance\n\n }, {\n key: \"getAttribute\",\n value: function getAttribute(name) {\n return this.node[NATIVE_PREFIX + 'getAttribute'](name);\n } // NOTE: not needed, just here for balance\n\n }, {\n key: \"hasAttribute\",\n value: function hasAttribute(name) {\n return this.node[NATIVE_PREFIX + 'hasAttribute'](name);\n }\n }, {\n key: \"removeAttribute\",\n value: function removeAttribute(name) {\n this.node[SHADY_PREFIX + 'removeAttribute'](name);\n }\n }, {\n key: \"attachShadow\",\n value: function attachShadow(options) {\n return this.node[SHADY_PREFIX + 'attachShadow'](options);\n }\n /** @return {!Node|undefined} */\n\n }, {\n key: \"focus\",\n // NOTE: not needed, just here for balance\n\n /** @override */\n value: function focus() {\n this.node[NATIVE_PREFIX + 'focus']();\n }\n }, {\n key: \"blur\",\n value: function blur() {\n this.node[SHADY_PREFIX + 'blur']();\n } // document\n\n }, {\n key: \"importNode\",\n value: function importNode(node, deep) {\n if (this.node.nodeType === Node.DOCUMENT_NODE) {\n return this.node[SHADY_PREFIX + 'importNode'](node, deep);\n }\n }\n }, {\n key: \"getElementById\",\n value: function getElementById(id) {\n if (this.node.nodeType === Node.DOCUMENT_NODE) {\n return this.node[SHADY_PREFIX + 'getElementById'](id);\n }\n } // query\n\n }, {\n key: \"querySelector\",\n value: function querySelector(selector) {\n return this.node[SHADY_PREFIX + 'querySelector'](selector);\n }\n }, {\n key: \"querySelectorAll\",\n value: function querySelectorAll(selector, useNative) {\n return this.node[SHADY_PREFIX + 'querySelectorAll'](selector, useNative);\n } // slot\n\n }, {\n key: \"assignedNodes\",\n value: function assignedNodes(options) {\n if (this.node.localName === 'slot') {\n return this.node[SHADY_PREFIX + 'assignedNodes'](options);\n }\n }\n }, {\n key: \"activeElement\",\n get: function get() {\n if (utils_isShadyRoot(this.node) || this.node.nodeType === Node.DOCUMENT_NODE) {\n var e = this.node[SHADY_PREFIX + 'activeElement'];\n return e;\n }\n }\n /**\n * Installed for compatibility with browsers (older Chrome/Safari) that do\n * not have a configurable `activeElement` accessor. Enables noPatch and\n * patch mode both to consistently use ShadyDOM.wrap(document)._activeElement.\n * @override\n * @return {!Node|undefined}\n */\n\n }, {\n key: \"_activeElement\",\n get: function get() {\n return this.activeElement;\n }\n }, {\n key: \"host\",\n get: function get() {\n if (utils_isShadyRoot(this.node)) {\n return (\n /** @type {!ShadowRoot} */\n this.node.host\n );\n }\n }\n }, {\n key: \"parentNode\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'parentNode'];\n }\n }, {\n key: \"firstChild\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'firstChild'];\n }\n }, {\n key: \"lastChild\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'lastChild'];\n }\n }, {\n key: \"nextSibling\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'nextSibling'];\n }\n }, {\n key: \"previousSibling\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'previousSibling'];\n }\n }, {\n key: \"childNodes\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'childNodes'];\n }\n }, {\n key: \"parentElement\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'parentElement'];\n }\n }, {\n key: \"firstElementChild\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'firstElementChild'];\n }\n }, {\n key: \"lastElementChild\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'lastElementChild'];\n }\n }, {\n key: \"nextElementSibling\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'nextElementSibling'];\n }\n }, {\n key: \"previousElementSibling\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'previousElementSibling'];\n }\n }, {\n key: \"children\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'children'];\n }\n }, {\n key: \"childElementCount\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'childElementCount'];\n }\n }, {\n key: \"shadowRoot\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'shadowRoot'];\n }\n }, {\n key: \"assignedSlot\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'assignedSlot'];\n }\n }, {\n key: \"isConnected\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'isConnected'];\n }\n }, {\n key: \"innerHTML\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'innerHTML'];\n },\n set: function set(value) {\n this.node[SHADY_PREFIX + 'innerHTML'] = value;\n }\n }, {\n key: \"textContent\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'textContent'];\n },\n set: function set(value) {\n this.node[SHADY_PREFIX + 'textContent'] = value;\n }\n }, {\n key: \"slot\",\n get: function get() {\n return this.node[SHADY_PREFIX + 'slot'];\n },\n set: function set(value) {\n this.node[SHADY_PREFIX + 'slot'] = value;\n }\n }]);\n\n return Wrapper;\n}();\n\neventPropertyNames.forEach(function (name) {\n Object.defineProperty(wrapper_Wrapper.prototype, name, {\n /** @this {Wrapper} */\n get: function get() {\n return this.node[SHADY_PREFIX + name];\n },\n\n /** @this {Wrapper} */\n set: function set(value) {\n this.node[SHADY_PREFIX + name] = value;\n },\n configurable: true\n });\n});\n\nvar wrapperMap = new WeakMap();\nfunction wrap(obj) {\n if (utils_isShadyRoot(obj) || obj instanceof wrapper_Wrapper) {\n return obj;\n }\n\n var wrapper = wrapperMap.get(obj);\n\n if (!wrapper) {\n wrapper = new wrapper_Wrapper(obj);\n wrapperMap.set(obj, wrapper);\n }\n\n return wrapper;\n}\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/EventTarget.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n\nvar EventTargetPatches = getOwnPropertyDescriptors({\n /** @this {Node} */\n dispatchEvent: function dispatchEvent(event) {\n flush();\n return this[NATIVE_PREFIX + 'dispatchEvent'](event);\n },\n addEventListener: patch_events_addEventListener,\n removeEventListener: patch_events_removeEventListener\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/Slotable.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\nvar SlotablePatches = getOwnPropertyDescriptors({\n /** @this {Node} */\n get assignedSlot() {\n // Force any parent's shadowRoot to flush so that distribution occurs\n // and this node has an assignedSlot.\n var parent = this[SHADY_PREFIX + 'parentNode'];\n var ownerRoot = parent && parent[SHADY_PREFIX + 'shadowRoot'];\n\n if (ownerRoot) {\n ownerRoot._render();\n }\n\n var nodeData = shadyDataForNode(this);\n return nodeData && nodeData.assignedSlot || null;\n }\n\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/Element.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n\n\nvar Element_doc = window.document;\n/**\n * Should be called whenever an attribute changes. If the `slot` attribute\n * changes, provokes rendering if necessary. If a `` element's `name`\n * attribute changes, updates the root's slot map and renders.\n * @param {Node} node\n * @param {string} name\n */\n\nfunction distributeAttributeChange(node, name) {\n if (name === 'slot') {\n var parent = node[SHADY_PREFIX + 'parentNode'];\n\n if (utils_hasShadowRootWithSlot(parent)) {\n shadyDataForNode(parent).root._asyncRender();\n }\n } else if (node.localName === 'slot' && name === 'name') {\n var root = attach_shadow_ownerShadyRootForNode(node);\n\n if (root) {\n root._updateSlotName(node);\n\n root._asyncRender();\n }\n }\n}\n\nvar ElementPatches = getOwnPropertyDescriptors({\n /** @this {Element} */\n get previousElementSibling() {\n var nodeData = shadyDataForNode(this);\n\n if (nodeData && nodeData.previousSibling !== undefined) {\n var n = this[SHADY_PREFIX + 'previousSibling'];\n\n while (n && n.nodeType !== Node.ELEMENT_NODE) {\n n = n[SHADY_PREFIX + 'previousSibling'];\n }\n\n return n;\n } else {\n return this[NATIVE_PREFIX + 'previousElementSibling'];\n }\n },\n\n /** @this {Element} */\n get nextElementSibling() {\n var nodeData = shadyDataForNode(this);\n\n if (nodeData && nodeData.nextSibling !== undefined) {\n var n = this[SHADY_PREFIX + 'nextSibling'];\n\n while (n && n.nodeType !== Node.ELEMENT_NODE) {\n n = n[SHADY_PREFIX + 'nextSibling'];\n }\n\n return n;\n } else {\n return this[NATIVE_PREFIX + 'nextElementSibling'];\n }\n },\n\n /** @this {Element} */\n get slot() {\n return this.getAttribute('slot');\n },\n\n /** @this {Element} */\n set slot(value) {\n this[SHADY_PREFIX + 'setAttribute']('slot', value);\n },\n\n // Note: Can be patched on element prototype on all browsers.\n // Must be patched on instance on browsers that support native Shadow DOM\n // but do not have builtin accessors (old Chrome).\n\n /** @this {Element} */\n get shadowRoot() {\n var nodeData = shadyDataForNode(this);\n return nodeData && nodeData.publicRoot || null;\n },\n\n /** @this {Element} */\n get className() {\n return this.getAttribute('class') || '';\n },\n\n /**\n * @this {Element}\n * @param {string} value\n */\n set className(value) {\n this[SHADY_PREFIX + 'setAttribute']('class', value);\n },\n\n /**\n * @this {Element}\n * @param {string} attr\n * @param {string} value\n */\n setAttribute: function setAttribute(attr, value) {\n if (this.ownerDocument !== Element_doc) {\n this[NATIVE_PREFIX + 'setAttribute'](attr, value);\n } else if (!scopeClassAttribute(this, attr, value)) {\n this[NATIVE_PREFIX + 'setAttribute'](attr, value);\n distributeAttributeChange(this, attr);\n }\n },\n\n /**\n * @this {Element}\n * @param {string} attr\n */\n removeAttribute: function removeAttribute(attr) {\n this[NATIVE_PREFIX + 'removeAttribute'](attr);\n distributeAttributeChange(this, attr);\n },\n\n /**\n * @this {Element}\n * @param {!{mode: string}} options\n */\n attachShadow: function attachShadow(options) {\n return attach_shadow_attachShadow(this, options);\n }\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/HTMLElement.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n\nvar HTMLElementPatches = getOwnPropertyDescriptors({\n /** @this {HTMLElement} */\n blur: function blur() {\n var nodeData = shadyDataForNode(this);\n var root = nodeData && nodeData.root;\n var shadowActive = root && root.activeElement;\n\n if (shadowActive) {\n shadowActive[SHADY_PREFIX + 'blur']();\n } else {\n this[NATIVE_PREFIX + 'blur']();\n }\n }\n});\neventPropertyNames.forEach(function (property) {\n HTMLElementPatches[property] = {\n /** @this {HTMLElement} */\n set: function set(fn) {\n var shadyData = ensureShadyDataForNode(this);\n var eventName = property.substring(2);\n shadyData.__onCallbackListeners[property] && this.removeEventListener(eventName, shadyData.__onCallbackListeners[property]);\n this[SHADY_PREFIX + 'addEventListener'](eventName, fn);\n shadyData.__onCallbackListeners[property] = fn;\n },\n\n /** @this {HTMLElement} */\n get: function get() {\n var shadyData = shadyDataForNode(this);\n return shadyData && shadyData.__onCallbackListeners[property];\n },\n configurable: true\n };\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/Slot.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\nvar SlotPatches = getOwnPropertyDescriptors({\n /**\n * @this {HTMLSlotElement}\n * @param {Object=} options\n */\n assignedNodes: function assignedNodes(options) {\n if (this.localName === 'slot') {\n // Force any containing shadowRoot to flush so that distribution occurs\n // and this node has assignedNodes.\n var root = this[SHADY_PREFIX + 'getRootNode']();\n\n if (root && utils_isShadyRoot(root)) {\n root._render();\n }\n\n var nodeData = shadyDataForNode(this);\n return nodeData ? (options && options.flatten ? nodeData.flattenedNodes : nodeData.assignedNodes) || [] : [];\n }\n }\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/Document.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\nvar Document_doc = window.document;\nvar DocumentPatches = getOwnPropertyDescriptors({\n // note: Though not technically correct, we fast path `importNode`\n // when called on a node not owned by the main document.\n // This allows, for example, elements that cannot\n // contain custom elements and are therefore not likely to contain shadowRoots\n // to cloned natively. This is a fairly significant performance win.\n\n /**\n * @this {Document}\n * @param {Node} node\n * @param {boolean} deep\n */\n importNode: function importNode(node, deep) {\n // A template element normally has no children with shadowRoots, so make\n // sure we always make a deep copy to correctly construct the template.content\n if (node.ownerDocument !== Document_doc || node.localName === 'template') {\n return this[NATIVE_PREFIX + 'importNode'](node, deep);\n }\n\n var n = this[NATIVE_PREFIX + 'importNode'](node, false);\n\n if (deep) {\n var c$ = node[SHADY_PREFIX + 'childNodes'];\n\n for (var i = 0, nc; i < c$.length; i++) {\n nc = this[SHADY_PREFIX + 'importNode'](c$[i], true);\n n[SHADY_PREFIX + 'appendChild'](nc);\n }\n }\n\n return n;\n }\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patches/Window.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\nvar WindowPatches = getOwnPropertyDescriptors({\n // NOTE: ensure these methods are bound to `window` so that `this` is correct\n // when called directly from global context without a receiver; e.g.\n // `addEventListener(...)`.\n addEventListener: patch_events_addEventListener.bind(window),\n removeEventListener: patch_events_removeEventListener.bind(window)\n});\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/patch-prototypes.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n\n\n\n\n\n\n\n\n\n\n\n // Some browsers (IE/Edge) have non-standard HTMLElement accessors.\n\nvar NonStandardHTMLElement = {};\n\nif (Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'parentElement')) {\n NonStandardHTMLElement.parentElement = NodePatches.parentElement;\n}\n\nif (Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'contains')) {\n NonStandardHTMLElement.contains = NodePatches.contains;\n}\n\nif (Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'children')) {\n NonStandardHTMLElement.children = ParentNodePatches.children;\n}\n\nif (Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'innerHTML')) {\n NonStandardHTMLElement.innerHTML = ElementOrShadowRootPatches.innerHTML;\n}\n\nif (Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'className')) {\n NonStandardHTMLElement.className = ElementPatches.className;\n} // Avoid patching `innerHTML` if it does not exist on Element (IE)\n// and we can patch accessors (hasDescriptors).\n\n\nvar ElementShouldHaveInnerHTML = !settings.hasDescriptors || 'innerHTML' in Element.prototype; // setup patching\n\nvar patchMap = {\n EventTarget: [EventTargetPatches],\n Node: [NodePatches, !window.EventTarget ? EventTargetPatches : null],\n Text: [SlotablePatches],\n Element: [ElementPatches, ParentNodePatches, SlotablePatches, ElementShouldHaveInnerHTML ? ElementOrShadowRootPatches : null, !window.HTMLSlotElement ? SlotPatches : null],\n HTMLElement: [HTMLElementPatches, NonStandardHTMLElement],\n HTMLSlotElement: [SlotPatches],\n DocumentFragment: [ParentNodeDocumentOrFragmentPatches, DocumentOrFragmentPatches],\n Document: [DocumentPatches, ParentNodeDocumentOrFragmentPatches, DocumentOrFragmentPatches, DocumentOrShadowRootPatches],\n Window: [WindowPatches]\n};\n\nvar getPatchPrototype = function getPatchPrototype(name) {\n return window[name] && window[name].prototype;\n}; // Note, must avoid patching accessors on prototypes when descriptors are not correct\n// because the CustomElements polyfill checks if these exist before patching instances.\n// CustomElements polyfill *only* cares about these accessors.\n\n\nvar disallowedNativePatches = settings.hasDescriptors ? null : ['innerHTML', 'textContent'];\n/** @param {string=} prefix */\n\nvar patch_prototypes_applyPatches = function applyPatches(prefix) {\n var disallowed = prefix ? null : disallowedNativePatches;\n\n var _loop = function _loop(p) {\n var proto = getPatchPrototype(p);\n patchMap[p].forEach(function (patch) {\n return proto && patch && patchProperties(proto, patch, prefix, disallowed);\n });\n };\n\n for (var p in patchMap) {\n _loop(p);\n }\n};\nvar patch_prototypes_addShadyPrefixedProperties = function addShadyPrefixedProperties() {\n // perform shady patches\n patch_prototypes_applyPatches(SHADY_PREFIX); // install `_activeElement` because some browsers (older Chrome/Safari) do not have\n // a 'configurable' `activeElement` accesssor.\n\n var descriptor = DocumentOrShadowRootPatches.activeElement;\n Object.defineProperty(document, '_activeElement', descriptor); // On Window, we're patching `addEventListener` which is a weird auto-bound\n // property that is not directly on the Window prototype.\n\n patchProperties(Window.prototype, WindowPatches, SHADY_PREFIX);\n};\n// CONCATENATED MODULE: ./node_modules/@webcomponents/shadydom/src/shadydom.js\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 http://polymer.github.io/LICENSE.txt\nThe complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\nThe complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt\nCode distributed by Google as part of the polymer project is also\nsubject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt\n*/\n\n/**\n * Patches elements that interacts with ShadyDOM\n * such that tree traversal and mutation apis act like they would under\n * ShadowDOM.\n *\n * This import enables seemless interaction with ShadyDOM powered\n * custom elements, enabling better interoperation with 3rd party code,\n * libraries, and frameworks that use DOM tree manipulation apis.\n */\n\n\n\n\n\n\n\n\n\n\nif (settings.inUse) {\n var ShadyDOM = {\n // TODO(sorvell): remove when Polymer does not depend on this.\n 'inUse': settings.inUse,\n // NOTE: old browsers without prototype accessors (very old Chrome\n // and Safari) need manually patched accessors to properly set\n // `innerHTML` and `textContent` when an element is:\n // (1) inside a shadowRoot\n // (2) does not have special (slot) children itself\n // (3) and setting the property needs to provoke distribution (because\n // a nested slot is added/removed)\n 'patch': function patch(node) {\n patchInsideElementAccessors(node);\n patchOutsideElementAccessors(node);\n return node;\n },\n 'isShadyRoot': utils_isShadyRoot,\n 'enqueue': enqueue,\n 'flush': flush,\n 'flushInitial': function flushInitial(root) {\n root._flushInitial();\n },\n 'settings': settings,\n 'filterMutations': filterMutations,\n 'observeChildren': observe_changes_observeChildren,\n 'unobserveChildren': observe_changes_unobserveChildren,\n // Set to true to defer native custom elements connection until the\n // document has fully parsed. This enables custom elements that create\n // shadowRoots to be defined while the document is loading. Elements\n // customized as they are created by the parser will successfully\n // render with this flag on.\n 'deferConnectionCallbacks': settings['deferConnectionCallbacks'],\n // Set to true to speed up the polyfill slightly at the cost of correctness\n // * does not patch querySelector/All on Document or DocumentFragment\n // * does not wrap connected/disconnected callbacks to de-dup these\n // when using native customElements\n // * does not wait to process children of elements with shadowRoots\n // meaning shadowRoots should not be created while an element is parsing\n // (e.g. if a custom element that creates a shadowRoot is defined before\n // a candidate element in the document below it.\n 'preferPerformance': settings['preferPerformance'],\n // Integration point with ShadyCSS to disable styling MutationObserver,\n // as ShadyDOM will now handle dynamic scoping.\n 'handlesDynamicScoping': true,\n 'wrap': settings.noPatch ? wrap : function (n) {\n return n;\n },\n 'Wrapper': wrapper_Wrapper,\n 'composedPath': patch_events_composedPath,\n // Set to true to avoid patching regular platform property names. When set,\n // Shadow DOM compatible behavior is only available when accessing DOM\n // API using `ShadyDOM.wrap`, e.g. `ShadyDOM.wrap(element).shadowRoot`.\n // This setting provides a small performance boost, but requires all DOM API\n // access that requires Shadow DOM behavior to be proxied via `ShadyDOM.wrap`.\n 'noPatch': settings.noPatch,\n 'nativeMethods': nativeMethods,\n 'nativeTree': nativeTree\n };\n window['ShadyDOM'] = ShadyDOM; // Modifies native prototypes for Node, Element, etc. to\n // make native platform behavior available at prefixed names, e.g.\n // `utils.NATIVE_PREFIX + 'firstChild'` or `__shady_native_firstChild`.\n // This allows the standard names to be safely patched while retaining the\n // ability for native behavior to be used. This polyfill manipulates DOM\n // by using this saved native behavior.\n // Note, some browsers do not have proper element descriptors for\n // accessors; in this case, native behavior for these accessors is simulated\n // via a TreeWalker.\n\n patch_native_addNativePrefixedProperties(); // Modifies native prototypes for Node, Element, etc. to make ShadowDOM\n // behavior available at prefixed names, e.g.\n // `utils.SHADY_PREFIX + 'firstChild` or `__shady_firstChild`. This is done\n // so this polyfill can perform Shadow DOM style DOM manipulation.\n // Because patching normal platform property names is optional, these prefixed\n // names are used internally.\n\n patch_prototypes_addShadyPrefixedProperties(); // Modifies native prototypes for Node, Element, etc. to patch\n // regular platform property names to have Shadow DOM compatible API behavior.\n // This applies the utils.SHADY_PREFIX behavior to normal names. For example,\n // if `noPatch` is not set, then `el.__shady_firstChild` is equivalent to\n // `el.firstChild`.\n // NOTE, on older browsers (old Chrome/Safari) native accessors cannot be\n // patched on prototypes (e.g. Node.prototype.firstChild cannot be modified).\n // On these browsers, instance level patching is performed where needed; this\n // instance patching is only done when `noPatch` is *not* set.\n\n if (!settings.noPatch) {\n patch_prototypes_applyPatches(); // Patch click event behavior only if we're patching\n\n patchClick();\n } // For simplicity, patch events unconditionally.\n // Patches the event system to have Shadow DOM compatible behavior (e.g.\n // event retargeting). When `noPatch` is set, retargeting is only available\n // when adding event listeners and dispatching events via `ShadyDOM.wrap`\n // (e.g. `ShadyDOM.wrap(element).addEventListener(...)`).\n\n\n patchEvents();\n window.ShadowRoot =\n /** @type {function(new:ShadowRoot)} */\n attach_shadow_ShadyRoot;\n}\n\n//# sourceURL=webpack:///./node_modules/@webcomponents/shadydom/src/shadydom.js_+_28_modules?"); - -/***/ }) - -}]); \ No newline at end of file diff --git a/packages/uikit-workshop/dist/styleguide/js/1-chunk-861f2bf3817d7850085a.js b/packages/uikit-workshop/dist/styleguide/js/1-chunk-861f2bf3817d7850085a.js deleted file mode 100644 index 73c9dde7c..000000000 --- a/packages/uikit-workshop/dist/styleguide/js/1-chunk-861f2bf3817d7850085a.js +++ /dev/null @@ -1,15 +0,0 @@ -(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[1],{ - -/***/ "./node_modules/document-register-element/build/document-register-element.js": -/*!***********************************************************************************!*\ - !*** ./node_modules/document-register-element/build/document-register-element.js ***! - \***********************************************************************************/ -/*! no static exports found */ -/*! ModuleConcatenation bailout: Module is not an ECMAScript module */ -/***/ (function(module, exports) { - -eval("function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n/*! (C) Andrea Giammarchi - @WebReflection - ISC Style License */\n!function (e, t) {\n \"use strict\";\n\n function n() {\n var e = A.splice(0, A.length);\n\n for (Ye = 0; e.length;) {\n e.shift().call(null, e.shift());\n }\n }\n\n function r(e, t) {\n for (var n = 0, r = e.length; n < r; n++) {\n T(e[n], t);\n }\n }\n\n function o(e) {\n for (var t, n = 0, r = e.length; n < r; n++) {\n t = e[n], V(t, le[a(t)]);\n }\n }\n\n function l(e) {\n return function (t) {\n ke(t) && (T(t, e), ae.length && r(t.querySelectorAll(ae), e));\n };\n }\n\n function a(e) {\n var t = Ze.call(e, \"is\"),\n n = e.nodeName.toUpperCase(),\n r = ue.call(oe, t ? te + t.toUpperCase() : ee + n);\n return t && -1 < r && !i(n, t) ? -1 : r;\n }\n\n function i(e, t) {\n return -1 < ae.indexOf(e + '[is=\"' + t + '\"]');\n }\n\n function u(e) {\n var t = e.currentTarget,\n n = e.attrChange,\n r = e.attrName,\n o = e.target,\n l = e[$] || 2,\n a = e[Q] || 3;\n !ot || o && o !== t || !t[Z] || \"style\" === r || e.prevValue === e.newValue && (\"\" !== e.newValue || n !== l && n !== a) || t[Z](r, n === l ? null : e.prevValue, n === a ? null : e.newValue);\n }\n\n function c(e) {\n var t = l(e);\n return function (e) {\n A.push(t, e.target), Ye && clearTimeout(Ye), Ye = setTimeout(n, 1);\n };\n }\n\n function s(e) {\n rt && (rt = !1, e.currentTarget.removeEventListener(Y, s)), ae.length && r((e.target || y).querySelectorAll(ae), e.detail === q ? q : _), Re && d();\n }\n\n function m(e, t) {\n var n = this;\n ze.call(n, e, t), O.call(n, {\n target: n\n });\n }\n\n function f(e, t, n) {\n var r = t.apply(e, n),\n l = a(r);\n return -1 < l && V(r, le[l]), n.pop() && ae.length && o(r.querySelectorAll(ae)), r;\n }\n\n function p(e, t) {\n Fe(e, t), I ? I.observe(e, Qe) : (nt && (e.setAttribute = m, e[U] = D(e), e[k](J, O)), e[k](W, u)), e[K] && ot && (e.created = !0, e[K](), e.created = !1);\n }\n\n function d() {\n for (var e, t = 0, n = _e.length; t < n; t++) {\n e = _e[t], ie.contains(e) || (n--, _e.splice(t--, 1), T(e, q));\n }\n }\n\n function h(e) {\n throw new Error(\"A \" + e + \" type is already registered\");\n }\n\n function T(e, t) {\n var n,\n r,\n o = a(e);\n -1 < o && (S(e, le[o]), o = 0, t !== _ || e[_] ? t !== q || e[q] || (e[_] = !1, e[q] = !0, r = \"disconnected\", o = 1) : (e[q] = !1, e[_] = !0, r = \"connected\", o = 1, Re && ue.call(_e, e) < 0 && _e.push(e)), o && (n = e[t + x] || e[r + x]) && n.call(e));\n }\n\n function L() {}\n\n function M(e, t, n) {\n var r = n && n[B] || \"\",\n o = t.prototype,\n l = Ie(o),\n a = t.observedAttributes || pe,\n i = {\n prototype: l\n };\n Ue(l, K, {\n value: function value() {\n if (we) we = !1;else if (!this[ve]) {\n this[ve] = !0, new t(this), o[K] && o[K].call(this);\n var e = Ae[Ne.get(t)];\n (!ge || e.create.length > 1) && H(this);\n }\n }\n }), Ue(l, Z, {\n value: function value(e) {\n -1 < ue.call(a, e) && o[Z] && o[Z].apply(this, arguments);\n }\n }), o[G] && Ue(l, j, {\n value: o[G]\n }), o[z] && Ue(l, X, {\n value: o[z]\n }), r && (i[B] = r), e = e.toUpperCase(), Ae[e] = {\n constructor: t,\n create: r ? [r, De(e)] : [e]\n }, Ne.set(t, e), y[R](e.toLowerCase(), i), g(e), Oe[e].r();\n }\n\n function E(e) {\n var t = Ae[e.toUpperCase()];\n return t && t.constructor;\n }\n\n function v(e) {\n return \"string\" == typeof e ? e : e && e.is || \"\";\n }\n\n function H(e) {\n for (var t, n = e[Z], r = n ? e.attributes : pe, o = r.length; o--;) {\n t = r[o], n.call(e, t.name || t.nodeName, null, t.value || t.nodeValue);\n }\n }\n\n function g(e) {\n return e = e.toUpperCase(), e in Oe || (Oe[e] = {}, Oe[e].p = new Ce(function (t) {\n Oe[e].r = t;\n })), Oe[e].p;\n }\n\n function b() {\n He && delete e.customElements, fe(e, \"customElements\", {\n configurable: !0,\n value: new L()\n }), fe(e, \"CustomElementRegistry\", {\n configurable: !0,\n value: L\n });\n\n for (var t = w.get(/^HTML[A-Z]*[a-z]/), n = t.length; n--; function (t) {\n var n = e[t];\n\n if (n) {\n e[t] = function (e) {\n var t, r;\n return e || (e = this), e[ve] || (we = !0, t = Ae[Ne.get(e.constructor)], r = ge && 1 === t.create.length, e = r ? Reflect.construct(n, pe, t.constructor) : y.createElement.apply(y, t.create), e[ve] = !0, we = !1, r || H(e)), e;\n }, e[t].prototype = n.prototype;\n\n try {\n n.prototype.constructor = e[t];\n } catch (r) {\n Ee = !0, fe(n, ve, {\n value: e[t]\n });\n }\n }\n }(t[n])) {\n ;\n }\n\n y.createElement = function (e, t) {\n var n = v(t);\n return n ? $e.call(this, e, De(n)) : $e.call(this, e);\n }, Je || (tt = !0, y[R](\"\"));\n }\n\n var y = e.document,\n C = e.Object,\n w = function (e) {\n var t,\n n,\n r,\n o,\n l = /^[A-Z]+[a-z]/,\n a = function a(e) {\n var t,\n n = [];\n\n for (t in u) {\n e.test(t) && n.push(t);\n }\n\n return n;\n },\n i = function i(e, t) {\n (t = t.toLowerCase()) in u || (u[e] = (u[e] || []).concat(t), u[t] = u[t.toUpperCase()] = e);\n },\n u = (C.create || C)(null),\n c = {};\n\n for (n in e) {\n for (o in e[n]) {\n for (r = e[n][o], u[o] = r, t = 0; t < r.length; t++) {\n u[r[t].toLowerCase()] = u[r[t].toUpperCase()] = o;\n }\n }\n }\n\n return c.get = function (e) {\n return \"string\" == typeof e ? u[e] || (l.test(e) ? [] : \"\") : a(e);\n }, c.set = function (e, t) {\n return l.test(e) ? i(e, t) : i(t, e), c;\n }, c;\n }({\n collections: {\n HTMLAllCollection: [\"all\"],\n HTMLCollection: [\"forms\"],\n HTMLFormControlsCollection: [\"elements\"],\n HTMLOptionsCollection: [\"options\"]\n },\n elements: {\n Element: [\"element\"],\n HTMLAnchorElement: [\"a\"],\n HTMLAppletElement: [\"applet\"],\n HTMLAreaElement: [\"area\"],\n HTMLAttachmentElement: [\"attachment\"],\n HTMLAudioElement: [\"audio\"],\n HTMLBRElement: [\"br\"],\n HTMLBaseElement: [\"base\"],\n HTMLBodyElement: [\"body\"],\n HTMLButtonElement: [\"button\"],\n HTMLCanvasElement: [\"canvas\"],\n HTMLContentElement: [\"content\"],\n HTMLDListElement: [\"dl\"],\n HTMLDataElement: [\"data\"],\n HTMLDataListElement: [\"datalist\"],\n HTMLDetailsElement: [\"details\"],\n HTMLDialogElement: [\"dialog\"],\n HTMLDirectoryElement: [\"dir\"],\n HTMLDivElement: [\"div\"],\n HTMLDocument: [\"document\"],\n HTMLElement: [\"element\", \"abbr\", \"address\", \"article\", \"aside\", \"b\", \"bdi\", \"bdo\", \"cite\", \"code\", \"command\", \"dd\", \"dfn\", \"dt\", \"em\", \"figcaption\", \"figure\", \"footer\", \"header\", \"i\", \"kbd\", \"mark\", \"nav\", \"noscript\", \"rp\", \"rt\", \"ruby\", \"s\", \"samp\", \"section\", \"small\", \"strong\", \"sub\", \"summary\", \"sup\", \"u\", \"var\", \"wbr\"],\n HTMLEmbedElement: [\"embed\"],\n HTMLFieldSetElement: [\"fieldset\"],\n HTMLFontElement: [\"font\"],\n HTMLFormElement: [\"form\"],\n HTMLFrameElement: [\"frame\"],\n HTMLFrameSetElement: [\"frameset\"],\n HTMLHRElement: [\"hr\"],\n HTMLHeadElement: [\"head\"],\n HTMLHeadingElement: [\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\"],\n HTMLHtmlElement: [\"html\"],\n HTMLIFrameElement: [\"iframe\"],\n HTMLImageElement: [\"img\"],\n HTMLInputElement: [\"input\"],\n HTMLKeygenElement: [\"keygen\"],\n HTMLLIElement: [\"li\"],\n HTMLLabelElement: [\"label\"],\n HTMLLegendElement: [\"legend\"],\n HTMLLinkElement: [\"link\"],\n HTMLMapElement: [\"map\"],\n HTMLMarqueeElement: [\"marquee\"],\n HTMLMediaElement: [\"media\"],\n HTMLMenuElement: [\"menu\"],\n HTMLMenuItemElement: [\"menuitem\"],\n HTMLMetaElement: [\"meta\"],\n HTMLMeterElement: [\"meter\"],\n HTMLModElement: [\"del\", \"ins\"],\n HTMLOListElement: [\"ol\"],\n HTMLObjectElement: [\"object\"],\n HTMLOptGroupElement: [\"optgroup\"],\n HTMLOptionElement: [\"option\"],\n HTMLOutputElement: [\"output\"],\n HTMLParagraphElement: [\"p\"],\n HTMLParamElement: [\"param\"],\n HTMLPictureElement: [\"picture\"],\n HTMLPreElement: [\"pre\"],\n HTMLProgressElement: [\"progress\"],\n HTMLQuoteElement: [\"blockquote\", \"q\", \"quote\"],\n HTMLScriptElement: [\"script\"],\n HTMLSelectElement: [\"select\"],\n HTMLShadowElement: [\"shadow\"],\n HTMLSlotElement: [\"slot\"],\n HTMLSourceElement: [\"source\"],\n HTMLSpanElement: [\"span\"],\n HTMLStyleElement: [\"style\"],\n HTMLTableCaptionElement: [\"caption\"],\n HTMLTableCellElement: [\"td\", \"th\"],\n HTMLTableColElement: [\"col\", \"colgroup\"],\n HTMLTableElement: [\"table\"],\n HTMLTableRowElement: [\"tr\"],\n HTMLTableSectionElement: [\"thead\", \"tbody\", \"tfoot\"],\n HTMLTemplateElement: [\"template\"],\n HTMLTextAreaElement: [\"textarea\"],\n HTMLTimeElement: [\"time\"],\n HTMLTitleElement: [\"title\"],\n HTMLTrackElement: [\"track\"],\n HTMLUListElement: [\"ul\"],\n HTMLUnknownElement: [\"unknown\", \"vhgroupv\", \"vkeygen\"],\n HTMLVideoElement: [\"video\"]\n },\n nodes: {\n Attr: [\"node\"],\n Audio: [\"audio\"],\n CDATASection: [\"node\"],\n CharacterData: [\"node\"],\n Comment: [\"#comment\"],\n Document: [\"#document\"],\n DocumentFragment: [\"#document-fragment\"],\n DocumentType: [\"node\"],\n HTMLDocument: [\"#document\"],\n Image: [\"img\"],\n Option: [\"option\"],\n ProcessingInstruction: [\"node\"],\n ShadowRoot: [\"#shadow-root\"],\n Text: [\"#text\"],\n XMLDocument: [\"xml\"]\n }\n });\n\n \"object\" != _typeof(t) && (t = {\n type: t || \"auto\"\n });\n\n var A,\n O,\n N,\n D,\n I,\n F,\n S,\n V,\n P,\n R = \"registerElement\",\n U = \"__\" + R + (1e5 * e.Math.random() >> 0),\n k = \"addEventListener\",\n _ = \"attached\",\n x = \"Callback\",\n q = \"detached\",\n B = \"extends\",\n Z = \"attributeChanged\" + x,\n j = _ + x,\n G = \"connected\" + x,\n z = \"disconnected\" + x,\n K = \"created\" + x,\n X = q + x,\n $ = \"ADDITION\",\n Q = \"REMOVAL\",\n W = \"DOMAttrModified\",\n Y = \"DOMContentLoaded\",\n J = \"DOMSubtreeModified\",\n ee = \"<\",\n te = \"=\",\n ne = /^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/,\n re = [\"ANNOTATION-XML\", \"COLOR-PROFILE\", \"FONT-FACE\", \"FONT-FACE-SRC\", \"FONT-FACE-URI\", \"FONT-FACE-FORMAT\", \"FONT-FACE-NAME\", \"MISSING-GLYPH\"],\n oe = [],\n le = [],\n ae = \"\",\n ie = y.documentElement,\n ue = oe.indexOf || function (e) {\n for (var t = this.length; t-- && this[t] !== e;) {\n ;\n }\n\n return t;\n },\n ce = C.prototype,\n se = ce.hasOwnProperty,\n me = ce.isPrototypeOf,\n fe = C.defineProperty,\n pe = [],\n de = C.getOwnPropertyDescriptor,\n he = C.getOwnPropertyNames,\n Te = C.getPrototypeOf,\n Le = C.setPrototypeOf,\n Me = !!C.__proto__,\n Ee = !1,\n ve = \"__dreCEv1\",\n He = e.customElements,\n ge = !/^force/.test(t.type) && !!(He && He.define && He.get && He.whenDefined),\n be = C.create || C,\n ye = e.Map || function () {\n var e,\n t = [],\n n = [];\n return {\n get: function get(e) {\n return n[ue.call(t, e)];\n },\n set: function set(r, o) {\n e = ue.call(t, r), e < 0 ? n[t.push(r) - 1] = o : n[e] = o;\n }\n };\n },\n Ce = e.Promise || function (e) {\n function t(e) {\n for (r = !0; n.length;) {\n n.shift()(e);\n }\n }\n\n var n = [],\n r = !1,\n o = {\n \"catch\": function _catch() {\n return o;\n },\n then: function then(e) {\n return n.push(e), r && setTimeout(t, 1), o;\n }\n };\n return e(t), o;\n },\n we = !1,\n Ae = be(null),\n Oe = be(null),\n Ne = new ye(),\n De = function De(e) {\n return e.toLowerCase();\n },\n Ie = C.create || function it(e) {\n return e ? (it.prototype = e, new it()) : this;\n },\n Fe = Le || (Me ? function (e, t) {\n return e.__proto__ = t, e;\n } : he && de ? function () {\n function e(e, t) {\n for (var n, r = he(t), o = 0, l = r.length; o < l; o++) {\n n = r[o], se.call(e, n) || fe(e, n, de(t, n));\n }\n }\n\n return function (t, n) {\n do {\n e(t, n);\n } while ((n = Te(n)) && !me.call(n, t));\n\n return t;\n };\n }() : function (e, t) {\n for (var n in t) {\n e[n] = t[n];\n }\n\n return e;\n }),\n Se = e.MutationObserver || e.WebKitMutationObserver,\n Ve = e.HTMLAnchorElement,\n Pe = (e.HTMLElement || e.Element || e.Node).prototype,\n Re = !me.call(Pe, ie),\n Ue = Re ? function (e, t, n) {\n return e[t] = n.value, e;\n } : fe,\n ke = Re ? function (e) {\n return 1 === e.nodeType;\n } : function (e) {\n return me.call(Pe, e);\n },\n _e = Re && [],\n xe = Pe.attachShadow,\n qe = Pe.cloneNode,\n Be = Pe.dispatchEvent,\n Ze = Pe.getAttribute,\n je = Pe.hasAttribute,\n Ge = Pe.removeAttribute,\n ze = Pe.setAttribute,\n Ke = y.createElement,\n Xe = y.importNode,\n $e = Ke,\n Qe = Se && {\n attributes: !0,\n characterData: !0,\n attributeOldValue: !0\n },\n We = Se || function (e) {\n nt = !1, ie.removeEventListener(W, We);\n },\n Ye = 0,\n Je = R in y && !/^force-all/.test(t.type),\n et = !0,\n tt = !1,\n nt = !0,\n rt = !0,\n ot = !0;\n\n if (Se && (P = y.createElement(\"div\"), P.innerHTML = \"
\", new Se(function (e, t) {\n if (e[0] && \"childList\" == e[0].type && !e[0].removedNodes[0].childNodes.length) {\n P = de(Pe, \"innerHTML\");\n var n = P && P.set;\n n && fe(Pe, \"innerHTML\", {\n set: function set(e) {\n for (; this.lastChild;) {\n this.removeChild(this.lastChild);\n }\n\n n.call(this, e);\n }\n });\n }\n\n t.disconnect(), P = null;\n }).observe(P, {\n childList: !0,\n subtree: !0\n }), P.innerHTML = \"\"), Je || (Le || Me ? (S = function S(e, t) {\n me.call(t, e) || p(e, t);\n }, V = p) : (S = function S(e, t) {\n e[U] || (e[U] = C(!0), p(e, t));\n }, V = S), Re ? (nt = !1, function () {\n var e = de(Pe, k),\n t = e.value,\n n = function n(e) {\n var t = new CustomEvent(W, {\n bubbles: !0\n });\n t.attrName = e, t.prevValue = Ze.call(this, e), t.newValue = null, t[Q] = t.attrChange = 2, Ge.call(this, e), Be.call(this, t);\n },\n r = function r(e, t) {\n var n = je.call(this, e),\n r = n && Ze.call(this, e),\n o = new CustomEvent(W, {\n bubbles: !0\n });\n ze.call(this, e, t), o.attrName = e, o.prevValue = n ? r : null, o.newValue = t, n ? o.MODIFICATION = o.attrChange = 1 : o[$] = o.attrChange = 0, Be.call(this, o);\n },\n o = function o(e) {\n var t,\n n = e.currentTarget,\n r = n[U],\n o = e.propertyName;\n r.hasOwnProperty(o) && (r = r[o], t = new CustomEvent(W, {\n bubbles: !0\n }), t.attrName = r.name, t.prevValue = r.value || null, t.newValue = r.value = n[o] || null, null == t.prevValue ? t[$] = t.attrChange = 0 : t.MODIFICATION = t.attrChange = 1, Be.call(n, t));\n };\n\n e.value = function (e, l, a) {\n e === W && this[Z] && this.setAttribute !== r && (this[U] = {\n className: {\n name: \"class\",\n value: this.className\n }\n }, this.setAttribute = r, this.removeAttribute = n, t.call(this, \"propertychange\", o)), t.call(this, e, l, a);\n }, fe(Pe, k, e);\n }()) : Se || (ie[k](W, We), ie.setAttribute(U, 1), ie.removeAttribute(U), nt && (O = function O(e) {\n var t,\n n,\n r,\n o = this;\n\n if (o === e.target) {\n t = o[U], o[U] = n = D(o);\n\n for (r in n) {\n if (!(r in t)) return N(0, o, r, t[r], n[r], $);\n if (n[r] !== t[r]) return N(1, o, r, t[r], n[r], \"MODIFICATION\");\n }\n\n for (r in t) {\n if (!(r in n)) return N(2, o, r, t[r], n[r], Q);\n }\n }\n }, N = function N(e, t, n, r, o, l) {\n var a = {\n attrChange: e,\n currentTarget: t,\n attrName: n,\n prevValue: r,\n newValue: o\n };\n a[l] = e, u(a);\n }, D = function D(e) {\n for (var t, n, r = {}, o = e.attributes, l = 0, a = o.length; l < a; l++) {\n t = o[l], \"setAttribute\" !== (n = t.name) && (r[n] = t.value);\n }\n\n return r;\n })), y[R] = function (e, t) {\n if (n = e.toUpperCase(), et && (et = !1, Se ? (I = function (e, t) {\n function n(e, t) {\n for (var n = 0, r = e.length; n < r; t(e[n++])) {\n ;\n }\n }\n\n return new Se(function (r) {\n for (var o, l, a, i = 0, u = r.length; i < u; i++) {\n o = r[i], \"childList\" === o.type ? (n(o.addedNodes, e), n(o.removedNodes, t)) : (l = o.target, ot && l[Z] && \"style\" !== o.attributeName && (a = Ze.call(l, o.attributeName)) !== o.oldValue && l[Z](o.attributeName, o.oldValue, a));\n }\n });\n }(l(_), l(q)), F = function F(e) {\n return I.observe(e, {\n childList: !0,\n subtree: !0\n }), e;\n }, F(y), xe && (Pe.attachShadow = function () {\n return F(xe.apply(this, arguments));\n })) : (A = [], y[k](\"DOMNodeInserted\", c(_)), y[k](\"DOMNodeRemoved\", c(q))), y[k](Y, s), y[k](\"readystatechange\", s), y.importNode = function (e, t) {\n switch (e.nodeType) {\n case 1:\n return f(y, Xe, [e, !!t]);\n\n case 11:\n for (var n = y.createDocumentFragment(), r = e.childNodes, o = r.length, l = 0; l < o; l++) {\n n.appendChild(y.importNode(r[l], !!t));\n }\n\n return n;\n\n default:\n return qe.call(e, !!t);\n }\n }, Pe.cloneNode = function (e) {\n return f(this, qe, [!!e]);\n }), tt) return tt = !1;\n if (-2 < ue.call(oe, te + n) + ue.call(oe, ee + n) && h(e), !ne.test(n) || -1 < ue.call(re, n)) throw new Error(\"The type \" + e + \" is invalid\");\n\n var n,\n o,\n a = function a() {\n return u ? y.createElement(m, n) : y.createElement(m);\n },\n i = t || ce,\n u = se.call(i, B),\n m = u ? t[B].toUpperCase() : n;\n\n return u && -1 < ue.call(oe, ee + m) && h(m), o = oe.push((u ? te : ee) + n) - 1, ae = ae.concat(ae.length ? \",\" : \"\", u ? m + '[is=\"' + e.toLowerCase() + '\"]' : m), a.prototype = le[o] = se.call(i, \"prototype\") ? i.prototype : Ie(Pe), ae.length && r(y.querySelectorAll(ae), _), a;\n }, y.createElement = $e = function $e(e, t) {\n var n = v(t),\n r = n ? Ke.call(y, e, De(n)) : Ke.call(y, e),\n o = \"\" + e,\n l = ue.call(oe, (n ? te : ee) + (n || o).toUpperCase()),\n a = -1 < l;\n return n && (r.setAttribute(\"is\", n = n.toLowerCase()), a && (a = i(o.toUpperCase(), n))), ot = !y.createElement.innerHTMLHelper, a && V(r, le[l]), r;\n }), L.prototype = {\n constructor: L,\n define: ge ? function (e, t, n) {\n if (n) M(e, t, n);else {\n var r = e.toUpperCase();\n Ae[r] = {\n constructor: t,\n create: [r]\n }, Ne.set(t, r), He.define(e, t);\n }\n } : M,\n get: ge ? function (e) {\n return He.get(e) || E(e);\n } : E,\n whenDefined: ge ? function (e) {\n return Ce.race([He.whenDefined(e), g(e)]);\n } : g\n }, !He || /^force/.test(t.type)) b();else if (!t.noBuiltIn) try {\n !function (t, n, r) {\n var o = new RegExp(\"^$\");\n if (n[B] = \"a\", t.prototype = Ie(Ve.prototype), t.prototype.constructor = t, e.customElements.define(r, t, n), !o.test(y.createElement(\"a\", {\n is: r\n }).outerHTML) || !o.test(new t().outerHTML)) throw n;\n }(function ut() {\n return Reflect.construct(Ve, [], ut);\n }, {}, \"document-register-element-a\");\n } catch (lt) {\n b();\n }\n if (!t.noBuiltIn) try {\n if (Ke.call(y, \"a\", \"a\").outerHTML.indexOf(\"is\") < 0) throw {};\n } catch (at) {\n De = function De(e) {\n return {\n is: e.toLowerCase()\n };\n };\n }\n}(window);\n\n//# sourceURL=webpack:///./node_modules/document-register-element/build/document-register-element.js?"); - -/***/ }) - -}]); \ No newline at end of file diff --git a/packages/uikit-workshop/dist/styleguide/js/2-chunk-e309c72e0e8f5783df94.js b/packages/uikit-workshop/dist/styleguide/js/2-chunk-e309c72e0e8f5783df94.js deleted file mode 100644 index de9e8f130..000000000 --- a/packages/uikit-workshop/dist/styleguide/js/2-chunk-e309c72e0e8f5783df94.js +++ /dev/null @@ -1,15 +0,0 @@ -(window["webpackJsonp"] = window["webpackJsonp"] || []).push([[2],{ - -/***/ "./node_modules/@webcomponents/custom-elements/src/native-shim.js": -/*!************************************************************************!*\ - !*** ./node_modules/@webcomponents/custom-elements/src/native-shim.js ***! - \************************************************************************/ -/*! no static exports found */ -/*! ModuleConcatenation bailout: Module is not an ECMAScript module */ -/***/ (function(module, exports) { - -eval("/**\n * @license\n * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at 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 http://polymer.github.io/PATENTS.txt\n */\n\n/**\n * This shim allows elements written in, or compiled to, ES5 to work on native\n * implementations of Custom Elements v1. It sets new.target to the value of\n * this.constructor so that the native HTMLElement constructor can access the\n * current under-construction element's definition.\n */\n(function () {\n if ( // No Reflect, no classes, no need for shim because native custom elements\n // require ES2015 classes or Reflect.\n window.Reflect === undefined || window.customElements === undefined || // The webcomponentsjs custom elements polyfill doesn't require\n // ES2015-compatible construction (`super()` or `Reflect.construct`).\n window.customElements.hasOwnProperty('polyfillWrapFlushCallback')) {\n return;\n }\n\n var BuiltInHTMLElement = HTMLElement;\n\n window.HTMLElement = function HTMLElement() {\n return Reflect.construct(BuiltInHTMLElement, [], this.constructor);\n };\n\n HTMLElement.prototype = BuiltInHTMLElement.prototype;\n HTMLElement.prototype.constructor = HTMLElement;\n Object.setPrototypeOf(HTMLElement, BuiltInHTMLElement);\n})();\n\n//# sourceURL=webpack:///./node_modules/@webcomponents/custom-elements/src/native-shim.js?"); - -/***/ }) - -}]); \ No newline at end of file diff --git a/packages/uikit-workshop/dist/styleguide/js/patternlab-pattern.js b/packages/uikit-workshop/dist/styleguide/js/patternlab-pattern.js index 107d34080..0a174ef39 100644 --- a/packages/uikit-workshop/dist/styleguide/js/patternlab-pattern.js +++ b/packages/uikit-workshop/dist/styleguide/js/patternlab-pattern.js @@ -1,228 +1 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { -/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); -/******/ } -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // create a fake namespace object -/******/ // mode & 1: value is a module id, require it -/******/ // mode & 2: merge all properties of value into the ns -/******/ // mode & 4: return value when already ns object -/******/ // mode & 8|1: behave like require -/******/ __webpack_require__.t = function(value, mode) { -/******/ if(mode & 1) value = __webpack_require__(value); -/******/ if(mode & 8) return value; -/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; -/******/ var ns = Object.create(null); -/******/ __webpack_require__.r(ns); -/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); -/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); -/******/ return ns; -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = "./styleguide/"; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = "./src/scripts/patternlab-pattern.js"); -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ "./node_modules/clipboard/dist/clipboard.js": -/*!**************************************************!*\ - !*** ./node_modules/clipboard/dist/clipboard.js ***! - \**************************************************/ -/*! no static exports found */ -/*! ModuleConcatenation bailout: Module is not an ECMAScript module */ -/***/ (function(module, exports, __webpack_require__) { - -eval("/* WEBPACK VAR INJECTION */(function(module) {var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof2(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof2 = function _typeof2(obj) { return typeof obj; }; } else { _typeof2 = function _typeof2(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof2(obj); }\n\n/*!\n * clipboard.js v2.0.4\n * https://zenorocha.github.io/clipboard.js\n * \n * Licensed MIT © Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n if (( false ? undefined : _typeof2(exports)) === 'object' && ( false ? undefined : _typeof2(module)) === 'object') module.exports = factory();else if (true) !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));else {}\n})(this, function () {\n return (\n /******/\n function (modules) {\n // webpackBootstrap\n\n /******/\n // The module cache\n\n /******/\n var installedModules = {};\n /******/\n\n /******/\n // The require function\n\n /******/\n\n function __webpack_require__(moduleId) {\n /******/\n\n /******/\n // Check if module is in cache\n\n /******/\n if (installedModules[moduleId]) {\n /******/\n return installedModules[moduleId].exports;\n /******/\n }\n /******/\n // Create a new module (and put it into the cache)\n\n /******/\n\n\n var module = installedModules[moduleId] = {\n /******/\n i: moduleId,\n\n /******/\n l: false,\n\n /******/\n exports: {}\n /******/\n\n };\n /******/\n\n /******/\n // Execute the module function\n\n /******/\n\n modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n /******/\n\n /******/\n // Flag the module as loaded\n\n /******/\n\n module.l = true;\n /******/\n\n /******/\n // Return the exports of the module\n\n /******/\n\n return module.exports;\n /******/\n }\n /******/\n\n /******/\n\n /******/\n // expose the modules object (__webpack_modules__)\n\n /******/\n\n\n __webpack_require__.m = modules;\n /******/\n\n /******/\n // expose the module cache\n\n /******/\n\n __webpack_require__.c = installedModules;\n /******/\n\n /******/\n // define getter function for harmony exports\n\n /******/\n\n __webpack_require__.d = function (exports, name, getter) {\n /******/\n if (!__webpack_require__.o(exports, name)) {\n /******/\n Object.defineProperty(exports, name, {\n enumerable: true,\n get: getter\n });\n /******/\n }\n /******/\n\n };\n /******/\n\n /******/\n // define __esModule on exports\n\n /******/\n\n\n __webpack_require__.r = function (exports) {\n /******/\n if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n /******/\n Object.defineProperty(exports, Symbol.toStringTag, {\n value: 'Module'\n });\n /******/\n }\n /******/\n\n\n Object.defineProperty(exports, '__esModule', {\n value: true\n });\n /******/\n };\n /******/\n\n /******/\n // create a fake namespace object\n\n /******/\n // mode & 1: value is a module id, require it\n\n /******/\n // mode & 2: merge all properties of value into the ns\n\n /******/\n // mode & 4: return value when already ns object\n\n /******/\n // mode & 8|1: behave like require\n\n /******/\n\n\n __webpack_require__.t = function (value, mode) {\n /******/\n if (mode & 1) value = __webpack_require__(value);\n /******/\n\n if (mode & 8) return value;\n /******/\n\n if (mode & 4 && _typeof2(value) === 'object' && value && value.__esModule) return value;\n /******/\n\n var ns = Object.create(null);\n /******/\n\n __webpack_require__.r(ns);\n /******/\n\n\n Object.defineProperty(ns, 'default', {\n enumerable: true,\n value: value\n });\n /******/\n\n if (mode & 2 && typeof value != 'string') for (var key in value) {\n __webpack_require__.d(ns, key, function (key) {\n return value[key];\n }.bind(null, key));\n }\n /******/\n\n return ns;\n /******/\n };\n /******/\n\n /******/\n // getDefaultExport function for compatibility with non-harmony modules\n\n /******/\n\n\n __webpack_require__.n = function (module) {\n /******/\n var getter = module && module.__esModule ?\n /******/\n function getDefault() {\n return module['default'];\n } :\n /******/\n function getModuleExports() {\n return module;\n };\n /******/\n\n __webpack_require__.d(getter, 'a', getter);\n /******/\n\n\n return getter;\n /******/\n };\n /******/\n\n /******/\n // Object.prototype.hasOwnProperty.call\n\n /******/\n\n\n __webpack_require__.o = function (object, property) {\n return Object.prototype.hasOwnProperty.call(object, property);\n };\n /******/\n\n /******/\n // __webpack_public_path__\n\n /******/\n\n\n __webpack_require__.p = \"\";\n /******/\n\n /******/\n\n /******/\n // Load entry module and return exports\n\n /******/\n\n return __webpack_require__(__webpack_require__.s = 0);\n /******/\n }(\n /************************************************************************/\n\n /******/\n [\n /* 0 */\n\n /***/\n function (module, exports, __webpack_require__) {\n \"use strict\";\n\n var _typeof = typeof Symbol === \"function\" && _typeof2(Symbol.iterator) === \"symbol\" ? function (obj) {\n return _typeof2(obj);\n } : function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : _typeof2(obj);\n };\n\n var _createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n }();\n\n var _clipboardAction = __webpack_require__(1);\n\n var _clipboardAction2 = _interopRequireDefault(_clipboardAction);\n\n var _tinyEmitter = __webpack_require__(3);\n\n var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter);\n\n var _goodListener = __webpack_require__(4);\n\n var _goodListener2 = _interopRequireDefault(_goodListener);\n\n function _interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n default: obj\n };\n }\n\n function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n }\n\n function _possibleConstructorReturn(self, call) {\n if (!self) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return call && (_typeof2(call) === \"object\" || typeof call === \"function\") ? call : self;\n }\n\n function _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function, not \" + _typeof2(superClass));\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;\n }\n /**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\n var Clipboard = function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n\n\n function Clipboard(trigger, options) {\n _classCallCheck(this, Clipboard);\n\n var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this));\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: 'resolveOptions',\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = _typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: 'listenClick',\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: 'onClick',\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n\n if (this.clipboardAction) {\n this.clipboardAction = null;\n }\n\n this.clipboardAction = new _clipboardAction2.default({\n action: this.action(trigger),\n target: this.target(trigger),\n text: this.text(trigger),\n container: this.container,\n trigger: trigger,\n emitter: this\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: 'defaultAction',\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: 'defaultTarget',\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: 'defaultText',\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: 'destroy',\n value: function destroy() {\n this.listener.destroy();\n\n if (this.clipboardAction) {\n this.clipboardAction.destroy();\n this.clipboardAction = null;\n }\n }\n }], [{\n key: 'isSupported',\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n }(_tinyEmitter2.default);\n /**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\n\n function getAttributeValue(suffix, element) {\n var attribute = 'data-clipboard-' + suffix;\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n }\n\n module.exports = Clipboard;\n /***/\n },\n /* 1 */\n\n /***/\n function (module, exports, __webpack_require__) {\n \"use strict\";\n\n var _typeof = typeof Symbol === \"function\" && _typeof2(Symbol.iterator) === \"symbol\" ? function (obj) {\n return _typeof2(obj);\n } : function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : _typeof2(obj);\n };\n\n var _createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n }();\n\n var _select = __webpack_require__(2);\n\n var _select2 = _interopRequireDefault(_select);\n\n function _interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n default: obj\n };\n }\n\n function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n }\n /**\n * Inner class which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n */\n\n\n var ClipboardAction = function () {\n /**\n * @param {Object} options\n */\n function ClipboardAction(options) {\n _classCallCheck(this, ClipboardAction);\n\n this.resolveOptions(options);\n this.initSelection();\n }\n /**\n * Defines base properties passed from constructor.\n * @param {Object} options\n */\n\n\n _createClass(ClipboardAction, [{\n key: 'resolveOptions',\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = options.action;\n this.container = options.container;\n this.emitter = options.emitter;\n this.target = options.target;\n this.text = options.text;\n this.trigger = options.trigger;\n this.selectedText = '';\n }\n /**\n * Decides which selection strategy is going to be applied based\n * on the existence of `text` and `target` properties.\n */\n\n }, {\n key: 'initSelection',\n value: function initSelection() {\n if (this.text) {\n this.selectFake();\n } else if (this.target) {\n this.selectTarget();\n }\n }\n /**\n * Creates a fake textarea element, sets its value from `text` property,\n * and makes a selection on it.\n */\n\n }, {\n key: 'selectFake',\n value: function selectFake() {\n var _this = this;\n\n var isRTL = document.documentElement.getAttribute('dir') == 'rtl';\n this.removeFake();\n\n this.fakeHandlerCallback = function () {\n return _this.removeFake();\n };\n\n this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || true;\n this.fakeElem = document.createElement('textarea'); // Prevent zooming on iOS\n\n this.fakeElem.style.fontSize = '12pt'; // Reset box model\n\n this.fakeElem.style.border = '0';\n this.fakeElem.style.padding = '0';\n this.fakeElem.style.margin = '0'; // Move element out of screen horizontally\n\n this.fakeElem.style.position = 'absolute';\n this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n this.fakeElem.style.top = yPosition + 'px';\n this.fakeElem.setAttribute('readonly', '');\n this.fakeElem.value = this.text;\n this.container.appendChild(this.fakeElem);\n this.selectedText = (0, _select2.default)(this.fakeElem);\n this.copyText();\n }\n /**\n * Only removes the fake element after another click event, that way\n * a user can hit `Ctrl+C` to copy because selection still exists.\n */\n\n }, {\n key: 'removeFake',\n value: function removeFake() {\n if (this.fakeHandler) {\n this.container.removeEventListener('click', this.fakeHandlerCallback);\n this.fakeHandler = null;\n this.fakeHandlerCallback = null;\n }\n\n if (this.fakeElem) {\n this.container.removeChild(this.fakeElem);\n this.fakeElem = null;\n }\n }\n /**\n * Selects the content from element passed on `target` property.\n */\n\n }, {\n key: 'selectTarget',\n value: function selectTarget() {\n this.selectedText = (0, _select2.default)(this.target);\n this.copyText();\n }\n /**\n * Executes the copy operation based on the current selection.\n */\n\n }, {\n key: 'copyText',\n value: function copyText() {\n var succeeded = void 0;\n\n try {\n succeeded = document.execCommand(this.action);\n } catch (err) {\n succeeded = false;\n }\n\n this.handleResult(succeeded);\n }\n /**\n * Fires an event based on the copy operation result.\n * @param {Boolean} succeeded\n */\n\n }, {\n key: 'handleResult',\n value: function handleResult(succeeded) {\n this.emitter.emit(succeeded ? 'success' : 'error', {\n action: this.action,\n text: this.selectedText,\n trigger: this.trigger,\n clearSelection: this.clearSelection.bind(this)\n });\n }\n /**\n * Moves focus away from `target` and back to the trigger, removes current selection.\n */\n\n }, {\n key: 'clearSelection',\n value: function clearSelection() {\n if (this.trigger) {\n this.trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n /**\n * Sets the `action` to be performed which can be either 'copy' or 'cut'.\n * @param {String} action\n */\n\n }, {\n key: 'destroy',\n\n /**\n * Destroy lifecycle.\n */\n value: function destroy() {\n this.removeFake();\n }\n }, {\n key: 'action',\n set: function set() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy';\n this._action = action;\n\n if (this._action !== 'copy' && this._action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n }\n }\n /**\n * Gets the `action` property.\n * @return {String}\n */\n ,\n get: function get() {\n return this._action;\n }\n /**\n * Sets the `target` property using an element\n * that will be have its content copied.\n * @param {Element} target\n */\n\n }, {\n key: 'target',\n set: function set(target) {\n if (target !== undefined) {\n if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) {\n if (this.action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n\n this._target = target;\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n }\n }\n /**\n * Gets the `target` property.\n * @return {String|HTMLElement}\n */\n ,\n get: function get() {\n return this._target;\n }\n }]);\n\n return ClipboardAction;\n }();\n\n module.exports = ClipboardAction;\n /***/\n },\n /* 2 */\n\n /***/\n function (module, exports) {\n function select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n selectedText = element.value;\n } else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n } else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n selectedText = selection.toString();\n }\n\n return selectedText;\n }\n\n module.exports = select;\n /***/\n },\n /* 3 */\n\n /***/\n function (module, exports) {\n function E() {// Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n }\n\n E.prototype = {\n on: function on(name, callback, ctx) {\n var e = this.e || (this.e = {});\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n return this;\n },\n once: function once(name, callback, ctx) {\n var self = this;\n\n function listener() {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n }\n\n ;\n listener._ = callback;\n return this.on(name, listener, ctx);\n },\n emit: function emit(name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n off: function off(name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback) liveEvents.push(evts[i]);\n }\n } // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n\n liveEvents.length ? e[name] = liveEvents : delete e[name];\n return this;\n }\n };\n module.exports = E;\n /***/\n },\n /* 4 */\n\n /***/\n function (module, exports, __webpack_require__) {\n var is = __webpack_require__(5);\n\n var delegate = __webpack_require__(6);\n /**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\n\n\n function listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n } else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n } else if (is.string(target)) {\n return listenSelector(target, type, callback);\n } else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n }\n /**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\n\n\n function listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n return {\n destroy: function destroy() {\n node.removeEventListener(type, callback);\n }\n };\n }\n /**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\n\n\n function listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function (node) {\n node.addEventListener(type, callback);\n });\n return {\n destroy: function destroy() {\n Array.prototype.forEach.call(nodeList, function (node) {\n node.removeEventListener(type, callback);\n });\n }\n };\n }\n /**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\n\n\n function listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n }\n\n module.exports = listen;\n /***/\n },\n /* 5 */\n\n /***/\n function (module, exports) {\n /**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\n exports.node = function (value) {\n return value !== undefined && value instanceof HTMLElement && value.nodeType === 1;\n };\n /**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\n\n\n exports.nodeList = function (value) {\n var type = Object.prototype.toString.call(value);\n return value !== undefined && (type === '[object NodeList]' || type === '[object HTMLCollection]') && 'length' in value && (value.length === 0 || exports.node(value[0]));\n };\n /**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\n\n\n exports.string = function (value) {\n return typeof value === 'string' || value instanceof String;\n };\n /**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\n\n\n exports.fn = function (value) {\n var type = Object.prototype.toString.call(value);\n return type === '[object Function]';\n };\n /***/\n\n },\n /* 6 */\n\n /***/\n function (module, exports, __webpack_require__) {\n var closest = __webpack_require__(7);\n /**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\n\n\n function _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n element.addEventListener(type, listenerFn, useCapture);\n return {\n destroy: function destroy() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n };\n }\n /**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\n\n\n function delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n } // Handle Element-less usage, it defaults to global delegation\n\n\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n } // Handle Selector-based usage\n\n\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n } // Handle Array-like based usage\n\n\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n }\n /**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\n\n\n function listener(element, selector, type, callback) {\n return function (e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n };\n }\n\n module.exports = delegate;\n /***/\n },\n /* 7 */\n\n /***/\n function (module, exports) {\n var DOCUMENT_NODE_TYPE = 9;\n /**\n * A polyfill for Element.matches()\n */\n\n if (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n proto.matches = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector || proto.webkitMatchesSelector;\n }\n /**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\n\n\n function closest(element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' && element.matches(selector)) {\n return element;\n }\n\n element = element.parentNode;\n }\n }\n\n module.exports = closest;\n /***/\n }])\n );\n});\n/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! ./../../webpack/buildin/module.js */ \"./node_modules/webpack/buildin/module.js\")(module)))\n\n//# sourceURL=webpack:///./node_modules/clipboard/dist/clipboard.js?"); - -/***/ }), - -/***/ "./node_modules/iframe-resizer/js/iframeResizer.contentWindow.min.js": -/*!***************************************************************************!*\ - !*** ./node_modules/iframe-resizer/js/iframeResizer.contentWindow.min.js ***! - \***************************************************************************/ -/*! no static exports found */ -/*! ModuleConcatenation bailout: Module is not an ECMAScript module */ -/***/ (function(module, exports) { - -eval("function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n/*! iFrame Resizer (iframeSizer.contentWindow.min.js) - v3.6.6 - 2019-02-26\n * Desc: Include this file in any page being loaded into an iframe\n * to force the iframe to resize to the content size.\n * Requires: iframeResizer.min.js on host page.\n * Copyright: (c) 2019 David J. Bradshaw - dave@bradshaw.net\n * License: MIT\n */\n!function (d) {\n \"use strict\";\n\n if (\"undefined\" != typeof window) {\n var n = !0,\n i = 10,\n o = \"\",\n r = 0,\n a = \"\",\n t = null,\n u = \"\",\n c = !1,\n s = {\n resize: 1,\n click: 1\n },\n l = 128,\n f = !0,\n m = 1,\n g = \"bodyOffset\",\n h = g,\n p = !0,\n v = \"\",\n y = {},\n w = 32,\n e = null,\n b = !1,\n T = \"[iFrameSizer]\",\n E = T.length,\n S = \"\",\n O = {\n max: 1,\n min: 1,\n bodyScroll: 1,\n documentElementScroll: 1\n },\n M = \"child\",\n I = !0,\n N = window.parent,\n C = \"*\",\n k = 0,\n A = !1,\n x = null,\n z = 16,\n L = 1,\n R = \"scroll\",\n F = R,\n P = window,\n D = function D() {\n ue(\"MessageCallback function not defined\");\n },\n q = function q() {},\n H = function H() {},\n W = {\n height: function height() {\n return ue(\"Custom height calculation function not defined\"), document.documentElement.offsetHeight;\n },\n width: function width() {\n return ue(\"Custom width calculation function not defined\"), document.body.scrollWidth;\n }\n },\n j = {},\n B = !1;\n\n try {\n var V = Object.create({}, {\n passive: {\n get: function get() {\n B = !0;\n }\n },\n once: {\n get: function get() {\n !0;\n }\n }\n });\n window.addEventListener(\"test\", te, V), window.removeEventListener(\"test\", te, V);\n } catch (e) {}\n\n var J,\n U,\n K,\n Q,\n X,\n Y,\n $,\n G = Date.now || function () {\n return new Date().getTime();\n },\n Z = {\n bodyOffset: function bodyOffset() {\n return document.body.offsetHeight + ye(\"marginTop\") + ye(\"marginBottom\");\n },\n offset: function offset() {\n return Z.bodyOffset();\n },\n bodyScroll: function bodyScroll() {\n return document.body.scrollHeight;\n },\n custom: function custom() {\n return W.height();\n },\n documentElementOffset: function documentElementOffset() {\n return document.documentElement.offsetHeight;\n },\n documentElementScroll: function documentElementScroll() {\n return document.documentElement.scrollHeight;\n },\n max: function max() {\n return Math.max.apply(null, be(Z));\n },\n min: function min() {\n return Math.min.apply(null, be(Z));\n },\n grow: function grow() {\n return Z.max();\n },\n lowestElement: function lowestElement() {\n return Math.max(Z.bodyOffset() || Z.documentElementOffset(), we(\"bottom\", Ee()));\n },\n taggedElement: function taggedElement() {\n return Te(\"bottom\", \"data-iframe-height\");\n }\n },\n _ = {\n bodyScroll: function bodyScroll() {\n return document.body.scrollWidth;\n },\n bodyOffset: function bodyOffset() {\n return document.body.offsetWidth;\n },\n custom: function custom() {\n return W.width();\n },\n documentElementScroll: function documentElementScroll() {\n return document.documentElement.scrollWidth;\n },\n documentElementOffset: function documentElementOffset() {\n return document.documentElement.offsetWidth;\n },\n scroll: function scroll() {\n return Math.max(_.bodyScroll(), _.documentElementScroll());\n },\n max: function max() {\n return Math.max.apply(null, be(_));\n },\n min: function min() {\n return Math.min.apply(null, be(_));\n },\n rightMostElement: function rightMostElement() {\n return we(\"right\", Ee());\n },\n taggedElement: function taggedElement() {\n return Te(\"right\", \"data-iframe-width\");\n }\n },\n ee = (J = Se, X = null, Y = 0, $ = function $() {\n Y = G(), X = null, Q = J.apply(U, K), X || (U = K = null);\n }, function () {\n var e = G();\n Y || (Y = e);\n var t = z - (e - Y);\n return U = this, K = arguments, t <= 0 || z < t ? (X && (clearTimeout(X), X = null), Y = e, Q = J.apply(U, K), X || (U = K = null)) : X || (X = setTimeout($, t)), Q;\n });\n\n ne(window, \"message\", ke), ne(window, \"readystatechange\", Ae), Ae();\n }\n\n function te() {}\n\n function ne(e, t, n, o) {\n \"addEventListener\" in window ? e.addEventListener(t, n, !!B && (o || {})) : \"attachEvent\" in window && e.attachEvent(\"on\" + t, n);\n }\n\n function oe(e, t, n) {\n \"removeEventListener\" in window ? e.removeEventListener(t, n, !1) : \"detachEvent\" in window && e.detachEvent(\"on\" + t, n);\n }\n\n function ie(e) {\n return e.charAt(0).toUpperCase() + e.slice(1);\n }\n\n function re(e) {\n return T + \"[\" + S + \"] \" + e;\n }\n\n function ae(e) {\n b && \"object\" == _typeof(window.console) && console.log(re(e));\n }\n\n function ue(e) {\n \"object\" == _typeof(window.console) && console.warn(re(e));\n }\n\n function ce() {\n var e;\n !function () {\n function e(e) {\n return \"true\" === e;\n }\n\n var t = v.substr(E).split(\":\");\n S = t[0], r = d !== t[1] ? Number(t[1]) : r, c = d !== t[2] ? e(t[2]) : c, b = d !== t[3] ? e(t[3]) : b, w = d !== t[4] ? Number(t[4]) : w, n = d !== t[6] ? e(t[6]) : n, a = t[7], h = d !== t[8] ? t[8] : h, o = t[9], u = t[10], k = d !== t[11] ? Number(t[11]) : k, y.enable = d !== t[12] && e(t[12]), M = d !== t[13] ? t[13] : M, F = d !== t[14] ? t[14] : F;\n }(), ae(\"Initialising iFrame (\" + location.href + \")\"), function () {\n function e(e, t) {\n return \"function\" == typeof e && (ae(\"Setup custom \" + t + \"CalcMethod\"), W[t] = e, e = \"custom\"), e;\n }\n\n \"iFrameResizer\" in window && Object === window.iFrameResizer.constructor && (t = window.iFrameResizer, ae(\"Reading data from page: \" + JSON.stringify(t)), D = \"messageCallback\" in t ? t.messageCallback : D, q = \"readyCallback\" in t ? t.readyCallback : q, C = \"targetOrigin\" in t ? t.targetOrigin : C, h = \"heightCalculationMethod\" in t ? t.heightCalculationMethod : h, F = \"widthCalculationMethod\" in t ? t.widthCalculationMethod : F, h = e(h, \"height\"), F = e(F, \"width\"));\n var t;\n ae(\"TargetOrigin for parent set to: \" + C);\n }(), function () {\n d === a && (a = r + \"px\");\n se(\"margin\", function (e, t) {\n -1 !== t.indexOf(\"-\") && (ue(\"Negative CSS value ignored for \" + e), t = \"\");\n return t;\n }(\"margin\", a));\n }(), se(\"background\", o), se(\"padding\", u), (e = document.createElement(\"div\")).style.clear = \"both\", e.style.display = \"block\", document.body.appendChild(e), me(), ge(), document.documentElement.style.height = \"\", document.body.style.height = \"\", ae('HTML & body height set to \"auto\"'), ae(\"Enable public methods\"), P.parentIFrame = {\n autoResize: function autoResize(e) {\n return !0 === e && !1 === n ? (n = !0, he()) : !1 === e && !0 === n && (n = !1, pe()), n;\n },\n close: function close() {\n Ce(0, 0, \"close\"), ae(\"Disable outgoing messages\"), I = !1, ae(\"Remove event listener: Message\"), oe(window, \"message\", ke), !0 === n && pe();\n },\n getId: function getId() {\n return S;\n },\n getPageInfo: function getPageInfo(e) {\n \"function\" == typeof e ? (H = e, Ce(0, 0, \"pageInfo\")) : (H = function H() {}, Ce(0, 0, \"pageInfoStop\"));\n },\n moveToAnchor: function moveToAnchor(e) {\n y.findTarget(e);\n },\n reset: function reset() {\n Ne(\"parentIFrame.reset\");\n },\n scrollTo: function scrollTo(e, t) {\n Ce(t, e, \"scrollTo\");\n },\n scrollToOffset: function scrollToOffset(e, t) {\n Ce(t, e, \"scrollToOffset\");\n },\n sendMessage: function sendMessage(e, t) {\n Ce(0, 0, \"message\", JSON.stringify(e), t);\n },\n setHeightCalculationMethod: function setHeightCalculationMethod(e) {\n h = e, me();\n },\n setWidthCalculationMethod: function setWidthCalculationMethod(e) {\n F = e, ge();\n },\n setTargetOrigin: function setTargetOrigin(e) {\n ae(\"Set targetOrigin: \" + e), C = e;\n },\n size: function size(e, t) {\n var n = (e || \"\") + (t ? \",\" + t : \"\");\n Oe(\"size\", \"parentIFrame.size(\" + n + \")\", e, t);\n }\n }, he(), y = function () {\n function r(e) {\n var t = e.getBoundingClientRect(),\n n = {\n x: window.pageXOffset !== d ? window.pageXOffset : document.documentElement.scrollLeft,\n y: window.pageYOffset !== d ? window.pageYOffset : document.documentElement.scrollTop\n };\n return {\n x: parseInt(t.left, 10) + parseInt(n.x, 10),\n y: parseInt(t.top, 10) + parseInt(n.y, 10)\n };\n }\n\n function n(e) {\n var t,\n n = e.split(\"#\")[1] || e,\n o = decodeURIComponent(n),\n i = document.getElementById(o) || document.getElementsByName(o)[0];\n d !== i ? (t = r(i), ae(\"Moving to in page link (#\" + n + \") at x: \" + t.x + \" y: \" + t.y), Ce(t.y, t.x, \"scrollToOffset\")) : (ae(\"In page link (#\" + n + \") not found in iFrame, so sending to parent\"), Ce(0, 0, \"inPageLink\", \"#\" + n));\n }\n\n function e() {\n \"\" !== location.hash && \"#\" !== location.hash && n(location.href);\n }\n\n function t() {\n Array.prototype.forEach.call(document.querySelectorAll('a[href^=\"#\"]'), function (e) {\n function t(e) {\n e.preventDefault(), n(this.getAttribute(\"href\"));\n }\n\n \"#\" !== e.getAttribute(\"href\") && ne(e, \"click\", t);\n });\n }\n\n y.enable ? Array.prototype.forEach && document.querySelectorAll ? (ae(\"Setting up location.hash handlers\"), t(), ne(window, \"hashchange\", e), setTimeout(e, l)) : ue(\"In page linking not fully supported in this browser! (See README.md for IE8 workaround)\") : ae(\"In page linking not enabled\");\n return {\n findTarget: n\n };\n }(), Oe(\"init\", \"Init message from host page\"), q();\n }\n\n function se(e, t) {\n d !== t && \"\" !== t && \"null\" !== t && ae(\"Body \" + e + ' set to \"' + (document.body.style[e] = t) + '\"');\n }\n\n function le(n) {\n var e = {\n add: function add(e) {\n function t() {\n Oe(n.eventName, n.eventType);\n }\n\n j[e] = t, ne(window, e, t, {\n passive: !0\n });\n },\n remove: function remove(e) {\n var t = j[e];\n delete j[e], oe(window, e, t);\n }\n };\n n.eventNames && Array.prototype.map ? (n.eventName = n.eventNames[0], n.eventNames.map(e[n.method])) : e[n.method](n.eventName), ae(ie(n.method) + \" event listener: \" + n.eventType);\n }\n\n function de(e) {\n le({\n method: e,\n eventType: \"Animation Start\",\n eventNames: [\"animationstart\", \"webkitAnimationStart\"]\n }), le({\n method: e,\n eventType: \"Animation Iteration\",\n eventNames: [\"animationiteration\", \"webkitAnimationIteration\"]\n }), le({\n method: e,\n eventType: \"Animation End\",\n eventNames: [\"animationend\", \"webkitAnimationEnd\"]\n }), le({\n method: e,\n eventType: \"Input\",\n eventName: \"input\"\n }), le({\n method: e,\n eventType: \"Mouse Up\",\n eventName: \"mouseup\"\n }), le({\n method: e,\n eventType: \"Mouse Down\",\n eventName: \"mousedown\"\n }), le({\n method: e,\n eventType: \"Orientation Change\",\n eventName: \"orientationchange\"\n }), le({\n method: e,\n eventType: \"Print\",\n eventName: [\"afterprint\", \"beforeprint\"]\n }), le({\n method: e,\n eventType: \"Ready State Change\",\n eventName: \"readystatechange\"\n }), le({\n method: e,\n eventType: \"Touch Start\",\n eventName: \"touchstart\"\n }), le({\n method: e,\n eventType: \"Touch End\",\n eventName: \"touchend\"\n }), le({\n method: e,\n eventType: \"Touch Cancel\",\n eventName: \"touchcancel\"\n }), le({\n method: e,\n eventType: \"Transition Start\",\n eventNames: [\"transitionstart\", \"webkitTransitionStart\", \"MSTransitionStart\", \"oTransitionStart\", \"otransitionstart\"]\n }), le({\n method: e,\n eventType: \"Transition Iteration\",\n eventNames: [\"transitioniteration\", \"webkitTransitionIteration\", \"MSTransitionIteration\", \"oTransitionIteration\", \"otransitioniteration\"]\n }), le({\n method: e,\n eventType: \"Transition End\",\n eventNames: [\"transitionend\", \"webkitTransitionEnd\", \"MSTransitionEnd\", \"oTransitionEnd\", \"otransitionend\"]\n }), \"child\" === M && le({\n method: e,\n eventType: \"IFrame Resized\",\n eventName: \"resize\"\n });\n }\n\n function fe(e, t, n, o) {\n return t !== e && (e in n || (ue(e + \" is not a valid option for \" + o + \"CalculationMethod.\"), e = t), ae(o + ' calculation method set to \"' + e + '\"')), e;\n }\n\n function me() {\n h = fe(h, g, Z, \"height\");\n }\n\n function ge() {\n F = fe(F, R, _, \"width\");\n }\n\n function he() {\n var e;\n !0 === n ? (de(\"add\"), e = w < 0, window.MutationObserver || window.WebKitMutationObserver ? e ? ve() : t = function () {\n function t(e) {\n function t(e) {\n !1 === e.complete && (ae(\"Attach listeners to \" + e.src), e.addEventListener(\"load\", i, !1), e.addEventListener(\"error\", r, !1), c.push(e));\n }\n\n \"attributes\" === e.type && \"src\" === e.attributeName ? t(e.target) : \"childList\" === e.type && Array.prototype.forEach.call(e.target.querySelectorAll(\"img\"), t);\n }\n\n function o(e) {\n var t;\n ae(\"Remove listeners from \" + e.src), e.removeEventListener(\"load\", i, !1), e.removeEventListener(\"error\", r, !1), t = e, c.splice(c.indexOf(t), 1);\n }\n\n function n(e, t, n) {\n o(e.target), Oe(t, n + \": \" + e.target.src, d, d);\n }\n\n function i(e) {\n n(e, \"imageLoad\", \"Image loaded\");\n }\n\n function r(e) {\n n(e, \"imageLoadFailed\", \"Image load failed\");\n }\n\n function e(e) {\n Oe(\"mutationObserver\", \"mutationObserver: \" + e[0].target + \" \" + e[0].type), e.forEach(t);\n }\n\n var a,\n u,\n c = [],\n s = window.MutationObserver || window.WebKitMutationObserver,\n l = (a = document.querySelector(\"body\"), u = {\n attributes: !0,\n attributeOldValue: !1,\n characterData: !0,\n characterDataOldValue: !1,\n childList: !0,\n subtree: !0\n }, l = new s(e), ae(\"Create body MutationObserver\"), l.observe(a, u), l);\n return {\n disconnect: function disconnect() {\n \"disconnect\" in l && (ae(\"Disconnect body MutationObserver\"), l.disconnect(), c.forEach(o));\n }\n };\n }() : (ae(\"MutationObserver not supported in this browser!\"), ve())) : ae(\"Auto Resize disabled\");\n }\n\n function pe() {\n de(\"remove\"), null !== t && t.disconnect(), clearInterval(e);\n }\n\n function ve() {\n 0 !== w && (ae(\"setInterval: \" + w + \"ms\"), e = setInterval(function () {\n Oe(\"interval\", \"setInterval: \" + w);\n }, Math.abs(w)));\n }\n\n function ye(e, o) {\n var t = 0;\n return o = o || document.body, t = \"defaultView\" in document && \"getComputedStyle\" in document.defaultView ? null !== (t = document.defaultView.getComputedStyle(o, null)) ? t[e] : 0 : function (e) {\n if (/^\\d+(px)?$/i.test(e)) return parseInt(e, i);\n var t = o.style.left,\n n = o.runtimeStyle.left;\n return o.runtimeStyle.left = o.currentStyle.left, o.style.left = e || 0, e = o.style.pixelLeft, o.style.left = t, o.runtimeStyle.left = n, e;\n }(o.currentStyle[e]), parseInt(t, i);\n }\n\n function we(e, t) {\n for (var n, o = t.length, i = 0, r = 0, a = ie(e), u = G(), c = 0; c < o; c++) {\n r < (i = t[c].getBoundingClientRect()[e] + ye(\"margin\" + a, t[c])) && (r = i);\n }\n\n return u = G() - u, ae(\"Parsed \" + o + \" HTML elements\"), ae(\"Element position calculated in \" + u + \"ms\"), z / 2 < (n = u) && ae(\"Event throttle increased to \" + (z = 2 * n) + \"ms\"), r;\n }\n\n function be(e) {\n return [e.bodyOffset(), e.bodyScroll(), e.documentElementOffset(), e.documentElementScroll()];\n }\n\n function Te(e, t) {\n var n = document.querySelectorAll(\"[\" + t + \"]\");\n return 0 === n.length && (ue(\"No tagged elements (\" + t + \") found on page\"), document.querySelectorAll(\"body *\")), we(e, n);\n }\n\n function Ee() {\n return document.querySelectorAll(\"body *\");\n }\n\n function Se(e, t, n, o) {\n var i, r;\n !function () {\n function e(e, t) {\n return !(Math.abs(e - t) <= k);\n }\n\n return i = d !== n ? n : Z[h](), r = d !== o ? o : _[F](), e(m, i) || c && e(L, r);\n }() && \"init\" !== e ? e in {\n init: 1,\n interval: 1,\n size: 1\n } || !(h in O || c && F in O) ? e in {\n interval: 1\n } || ae(\"No change in size detected\") : Ne(t) : (Me(), Ce(m = i, L = r, e));\n }\n\n function Oe(e, t, n, o) {\n A && e in s ? ae(\"Trigger event cancelled: \" + e) : (e in {\n reset: 1,\n resetPage: 1,\n init: 1\n } || ae(\"Trigger event: \" + t), \"init\" === e ? Se(e, t, n, o) : ee(e, t, n, o));\n }\n\n function Me() {\n A || (A = !0, ae(\"Trigger event lock on\")), clearTimeout(x), x = setTimeout(function () {\n A = !1, ae(\"Trigger event lock off\"), ae(\"--\");\n }, l);\n }\n\n function Ie(e) {\n m = Z[h](), L = _[F](), Ce(m, L, e);\n }\n\n function Ne(e) {\n var t = h;\n h = g, ae(\"Reset trigger event: \" + e), Me(), Ie(\"reset\"), h = t;\n }\n\n function Ce(e, t, n, o, i) {\n var r;\n !0 === I && (d === i ? i = C : ae(\"Message targetOrigin: \" + i), ae(\"Sending message to host page (\" + (r = S + \":\" + e + \":\" + t + \":\" + n + (d !== o ? \":\" + o : \"\")) + \")\"), N.postMessage(T + r, i));\n }\n\n function ke(t) {\n var n = {\n init: function init() {\n v = t.data, N = t.source, ce(), f = !1, setTimeout(function () {\n p = !1;\n }, l);\n },\n reset: function reset() {\n p ? ae(\"Page reset ignored by init\") : (ae(\"Page size reset by host page\"), Ie(\"resetPage\"));\n },\n resize: function resize() {\n Oe(\"resizeParent\", \"Parent window requested size check\");\n },\n moveToAnchor: function moveToAnchor() {\n y.findTarget(i());\n },\n inPageLink: function inPageLink() {\n this.moveToAnchor();\n },\n pageInfo: function pageInfo() {\n var e = i();\n ae(\"PageInfoFromParent called from parent: \" + e), H(JSON.parse(e)), ae(\" --\");\n },\n message: function message() {\n var e = i();\n ae(\"MessageCallback called from parent: \" + e), D(JSON.parse(e)), ae(\" --\");\n }\n };\n\n function o() {\n return t.data.split(\"]\")[1].split(\":\")[0];\n }\n\n function i() {\n return t.data.substr(t.data.indexOf(\":\") + 1);\n }\n\n function r() {\n return t.data.split(\":\")[2] in {\n true: 1,\n false: 1\n };\n }\n\n function e() {\n var e = o();\n e in n ? n[e]() : (\"undefined\" == typeof module || !module.exports) && \"iFrameResize\" in window || \"jQuery\" in window && \"iFrameResize\" in window.jQuery.prototype || r() || ue(\"Unexpected message (\" + t.data + \")\");\n }\n\n T === (\"\" + t.data).substr(0, E) && (!1 === f ? e() : r() ? n.init() : ae('Ignored message of type \"' + o() + '\". Received before initialization.'));\n }\n\n function Ae() {\n \"loading\" !== document.readyState && window.parent.postMessage(\"[iFrameResizerChild]Ready\", \"*\");\n }\n}();\n\n//# sourceURL=webpack:///./node_modules/iframe-resizer/js/iframeResizer.contentWindow.min.js?"); - -/***/ }), - -/***/ "./node_modules/js-cookie/src/js.cookie.js": -/*!*************************************************!*\ - !*** ./node_modules/js-cookie/src/js.cookie.js ***! - \*************************************************/ -/*! no static exports found */ -/*! ModuleConcatenation bailout: Module is not an ECMAScript module */ -/***/ (function(module, exports, __webpack_require__) { - -eval("var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n/*!\n * JavaScript Cookie v2.2.0\n * https://github.com/js-cookie/js-cookie\n *\n * Copyright 2006, 2015 Klaus Hartl & Fagner Brack\n * Released under the MIT license\n */\n;\n\n(function (factory) {\n var registeredInModuleLoader = false;\n\n if (true) {\n !(__WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :\n\t\t\t\t__WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n registeredInModuleLoader = true;\n }\n\n if (( false ? undefined : _typeof(exports)) === 'object') {\n module.exports = factory();\n registeredInModuleLoader = true;\n }\n\n if (!registeredInModuleLoader) {\n var OldCookies = window.Cookies;\n var api = window.Cookies = factory();\n\n api.noConflict = function () {\n window.Cookies = OldCookies;\n return api;\n };\n }\n})(function () {\n function extend() {\n var i = 0;\n var result = {};\n\n for (; i < arguments.length; i++) {\n var attributes = arguments[i];\n\n for (var key in attributes) {\n result[key] = attributes[key];\n }\n }\n\n return result;\n }\n\n function init(converter) {\n function api(key, value, attributes) {\n var result;\n\n if (typeof document === 'undefined') {\n return;\n } // Write\n\n\n if (arguments.length > 1) {\n attributes = extend({\n path: '/'\n }, api.defaults, attributes);\n\n if (typeof attributes.expires === 'number') {\n var expires = new Date();\n expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);\n attributes.expires = expires;\n } // We're using \"expires\" because \"max-age\" is not supported by IE\n\n\n attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';\n\n try {\n result = JSON.stringify(value);\n\n if (/^[\\{\\[]/.test(result)) {\n value = result;\n }\n } catch (e) {}\n\n if (!converter.write) {\n value = encodeURIComponent(String(value)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);\n } else {\n value = converter.write(value, key);\n }\n\n key = encodeURIComponent(String(key));\n key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);\n key = key.replace(/[\\(\\)]/g, escape);\n var stringifiedAttributes = '';\n\n for (var attributeName in attributes) {\n if (!attributes[attributeName]) {\n continue;\n }\n\n stringifiedAttributes += '; ' + attributeName;\n\n if (attributes[attributeName] === true) {\n continue;\n }\n\n stringifiedAttributes += '=' + attributes[attributeName];\n }\n\n return document.cookie = key + '=' + value + stringifiedAttributes;\n } // Read\n\n\n if (!key) {\n result = {};\n } // To prevent the for loop in the first place assign an empty array\n // in case there are no cookies at all. Also prevents odd result when\n // calling \"get()\"\n\n\n var cookies = document.cookie ? document.cookie.split('; ') : [];\n var rdecode = /(%[0-9A-Z]{2})+/g;\n var i = 0;\n\n for (; i < cookies.length; i++) {\n var parts = cookies[i].split('=');\n var cookie = parts.slice(1).join('=');\n\n if (!this.json && cookie.charAt(0) === '\"') {\n cookie = cookie.slice(1, -1);\n }\n\n try {\n var name = parts[0].replace(rdecode, decodeURIComponent);\n cookie = converter.read ? converter.read(cookie, name) : converter(cookie, name) || cookie.replace(rdecode, decodeURIComponent);\n\n if (this.json) {\n try {\n cookie = JSON.parse(cookie);\n } catch (e) {}\n }\n\n if (key === name) {\n result = cookie;\n break;\n }\n\n if (!key) {\n result[name] = cookie;\n }\n } catch (e) {}\n }\n\n return result;\n }\n\n api.set = api;\n\n api.get = function (key) {\n return api.call(api, key);\n };\n\n api.getJSON = function () {\n return api.apply({\n json: true\n }, [].slice.call(arguments));\n };\n\n api.defaults = {};\n\n api.remove = function (key, attributes) {\n api(key, '', extend(attributes, {\n expires: -1\n }));\n };\n\n api.withConverter = init;\n return api;\n }\n\n return init(function () {});\n});\n\n//# sourceURL=webpack:///./node_modules/js-cookie/src/js.cookie.js?"); - -/***/ }), - -/***/ "./node_modules/mousetrap/mousetrap.js": -/*!*********************************************!*\ - !*** ./node_modules/mousetrap/mousetrap.js ***! - \*********************************************/ -/*! no static exports found */ -/*! ModuleConcatenation bailout: Module is not an ECMAScript module */ -/***/ (function(module, exports, __webpack_require__) { - -eval("var __WEBPACK_AMD_DEFINE_RESULT__;/*global define:false */\n\n/**\n * Copyright 2012-2017 Craig Campbell\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n * Mousetrap is a simple keyboard shortcut library for Javascript with\n * no external dependencies\n *\n * @version 1.6.3\n * @url craig.is/killing/mice\n */\n(function (window, document, undefined) {\n // Check if mousetrap is used inside browser, if not, return\n if (!window) {\n return;\n }\n /**\n * mapping of special keycodes to their corresponding keys\n *\n * everything in this dictionary cannot use keypress events\n * so it has to be here to map to the correct keycodes for\n * keyup/keydown events\n *\n * @type {Object}\n */\n\n\n var _MAP = {\n 8: 'backspace',\n 9: 'tab',\n 13: 'enter',\n 16: 'shift',\n 17: 'ctrl',\n 18: 'alt',\n 20: 'capslock',\n 27: 'esc',\n 32: 'space',\n 33: 'pageup',\n 34: 'pagedown',\n 35: 'end',\n 36: 'home',\n 37: 'left',\n 38: 'up',\n 39: 'right',\n 40: 'down',\n 45: 'ins',\n 46: 'del',\n 91: 'meta',\n 93: 'meta',\n 224: 'meta'\n };\n /**\n * mapping for special characters so they can support\n *\n * this dictionary is only used incase you want to bind a\n * keyup or keydown event to one of these keys\n *\n * @type {Object}\n */\n\n var _KEYCODE_MAP = {\n 106: '*',\n 107: '+',\n 109: '-',\n 110: '.',\n 111: '/',\n 186: ';',\n 187: '=',\n 188: ',',\n 189: '-',\n 190: '.',\n 191: '/',\n 192: '`',\n 219: '[',\n 220: '\\\\',\n 221: ']',\n 222: '\\''\n };\n /**\n * this is a mapping of keys that require shift on a US keypad\n * back to the non shift equivelents\n *\n * this is so you can use keyup events with these keys\n *\n * note that this will only work reliably on US keyboards\n *\n * @type {Object}\n */\n\n var _SHIFT_MAP = {\n '~': '`',\n '!': '1',\n '@': '2',\n '#': '3',\n '$': '4',\n '%': '5',\n '^': '6',\n '&': '7',\n '*': '8',\n '(': '9',\n ')': '0',\n '_': '-',\n '+': '=',\n ':': ';',\n '\\\"': '\\'',\n '<': ',',\n '>': '.',\n '?': '/',\n '|': '\\\\'\n };\n /**\n * this is a list of special strings you can use to map\n * to modifier keys when you specify your keyboard shortcuts\n *\n * @type {Object}\n */\n\n var _SPECIAL_ALIASES = {\n 'option': 'alt',\n 'command': 'meta',\n 'return': 'enter',\n 'escape': 'esc',\n 'plus': '+',\n 'mod': /Mac|iPod|iPhone|iPad/.test(navigator.platform) ? 'meta' : 'ctrl'\n };\n /**\n * variable to store the flipped version of _MAP from above\n * needed to check if we should use keypress or not when no action\n * is specified\n *\n * @type {Object|undefined}\n */\n\n var _REVERSE_MAP;\n /**\n * loop through the f keys, f1 to f19 and add them to the map\n * programatically\n */\n\n\n for (var i = 1; i < 20; ++i) {\n _MAP[111 + i] = 'f' + i;\n }\n /**\n * loop through to map numbers on the numeric keypad\n */\n\n\n for (i = 0; i <= 9; ++i) {\n // This needs to use a string cause otherwise since 0 is falsey\n // mousetrap will never fire for numpad 0 pressed as part of a keydown\n // event.\n //\n // @see https://github.com/ccampbell/mousetrap/pull/258\n _MAP[i + 96] = i.toString();\n }\n /**\n * cross browser add event method\n *\n * @param {Element|HTMLDocument} object\n * @param {string} type\n * @param {Function} callback\n * @returns void\n */\n\n\n function _addEvent(object, type, callback) {\n if (object.addEventListener) {\n object.addEventListener(type, callback, false);\n return;\n }\n\n object.attachEvent('on' + type, callback);\n }\n /**\n * takes the event and returns the key character\n *\n * @param {Event} e\n * @return {string}\n */\n\n\n function _characterFromEvent(e) {\n // for keypress events we should return the character as is\n if (e.type == 'keypress') {\n var character = String.fromCharCode(e.which); // if the shift key is not pressed then it is safe to assume\n // that we want the character to be lowercase. this means if\n // you accidentally have caps lock on then your key bindings\n // will continue to work\n //\n // the only side effect that might not be desired is if you\n // bind something like 'A' cause you want to trigger an\n // event when capital A is pressed caps lock will no longer\n // trigger the event. shift+a will though.\n\n if (!e.shiftKey) {\n character = character.toLowerCase();\n }\n\n return character;\n } // for non keypress events the special maps are needed\n\n\n if (_MAP[e.which]) {\n return _MAP[e.which];\n }\n\n if (_KEYCODE_MAP[e.which]) {\n return _KEYCODE_MAP[e.which];\n } // if it is not in the special map\n // with keydown and keyup events the character seems to always\n // come in as an uppercase character whether you are pressing shift\n // or not. we should make sure it is always lowercase for comparisons\n\n\n return String.fromCharCode(e.which).toLowerCase();\n }\n /**\n * checks if two arrays are equal\n *\n * @param {Array} modifiers1\n * @param {Array} modifiers2\n * @returns {boolean}\n */\n\n\n function _modifiersMatch(modifiers1, modifiers2) {\n return modifiers1.sort().join(',') === modifiers2.sort().join(',');\n }\n /**\n * takes a key event and figures out what the modifiers are\n *\n * @param {Event} e\n * @returns {Array}\n */\n\n\n function _eventModifiers(e) {\n var modifiers = [];\n\n if (e.shiftKey) {\n modifiers.push('shift');\n }\n\n if (e.altKey) {\n modifiers.push('alt');\n }\n\n if (e.ctrlKey) {\n modifiers.push('ctrl');\n }\n\n if (e.metaKey) {\n modifiers.push('meta');\n }\n\n return modifiers;\n }\n /**\n * prevents default for this event\n *\n * @param {Event} e\n * @returns void\n */\n\n\n function _preventDefault(e) {\n if (e.preventDefault) {\n e.preventDefault();\n return;\n }\n\n e.returnValue = false;\n }\n /**\n * stops propogation for this event\n *\n * @param {Event} e\n * @returns void\n */\n\n\n function _stopPropagation(e) {\n if (e.stopPropagation) {\n e.stopPropagation();\n return;\n }\n\n e.cancelBubble = true;\n }\n /**\n * determines if the keycode specified is a modifier key or not\n *\n * @param {string} key\n * @returns {boolean}\n */\n\n\n function _isModifier(key) {\n return key == 'shift' || key == 'ctrl' || key == 'alt' || key == 'meta';\n }\n /**\n * reverses the map lookup so that we can look for specific keys\n * to see what can and can't use keypress\n *\n * @return {Object}\n */\n\n\n function _getReverseMap() {\n if (!_REVERSE_MAP) {\n _REVERSE_MAP = {};\n\n for (var key in _MAP) {\n // pull out the numeric keypad from here cause keypress should\n // be able to detect the keys from the character\n if (key > 95 && key < 112) {\n continue;\n }\n\n if (_MAP.hasOwnProperty(key)) {\n _REVERSE_MAP[_MAP[key]] = key;\n }\n }\n }\n\n return _REVERSE_MAP;\n }\n /**\n * picks the best action based on the key combination\n *\n * @param {string} key - character for key\n * @param {Array} modifiers\n * @param {string=} action passed in\n */\n\n\n function _pickBestAction(key, modifiers, action) {\n // if no action was picked in we should try to pick the one\n // that we think would work best for this key\n if (!action) {\n action = _getReverseMap()[key] ? 'keydown' : 'keypress';\n } // modifier keys don't work as expected with keypress,\n // switch to keydown\n\n\n if (action == 'keypress' && modifiers.length) {\n action = 'keydown';\n }\n\n return action;\n }\n /**\n * Converts from a string key combination to an array\n *\n * @param {string} combination like \"command+shift+l\"\n * @return {Array}\n */\n\n\n function _keysFromString(combination) {\n if (combination === '+') {\n return ['+'];\n }\n\n combination = combination.replace(/\\+{2}/g, '+plus');\n return combination.split('+');\n }\n /**\n * Gets info for a specific key combination\n *\n * @param {string} combination key combination (\"command+s\" or \"a\" or \"*\")\n * @param {string=} action\n * @returns {Object}\n */\n\n\n function _getKeyInfo(combination, action) {\n var keys;\n var key;\n var i;\n var modifiers = []; // take the keys from this pattern and figure out what the actual\n // pattern is all about\n\n keys = _keysFromString(combination);\n\n for (i = 0; i < keys.length; ++i) {\n key = keys[i]; // normalize key names\n\n if (_SPECIAL_ALIASES[key]) {\n key = _SPECIAL_ALIASES[key];\n } // if this is not a keypress event then we should\n // be smart about using shift keys\n // this will only work for US keyboards however\n\n\n if (action && action != 'keypress' && _SHIFT_MAP[key]) {\n key = _SHIFT_MAP[key];\n modifiers.push('shift');\n } // if this key is a modifier then add it to the list of modifiers\n\n\n if (_isModifier(key)) {\n modifiers.push(key);\n }\n } // depending on what the key combination is\n // we will try to pick the best event for it\n\n\n action = _pickBestAction(key, modifiers, action);\n return {\n key: key,\n modifiers: modifiers,\n action: action\n };\n }\n\n function _belongsTo(element, ancestor) {\n if (element === null || element === document) {\n return false;\n }\n\n if (element === ancestor) {\n return true;\n }\n\n return _belongsTo(element.parentNode, ancestor);\n }\n\n function Mousetrap(targetElement) {\n var self = this;\n targetElement = targetElement || document;\n\n if (!(self instanceof Mousetrap)) {\n return new Mousetrap(targetElement);\n }\n /**\n * element to attach key events to\n *\n * @type {Element}\n */\n\n\n self.target = targetElement;\n /**\n * a list of all the callbacks setup via Mousetrap.bind()\n *\n * @type {Object}\n */\n\n self._callbacks = {};\n /**\n * direct map of string combinations to callbacks used for trigger()\n *\n * @type {Object}\n */\n\n self._directMap = {};\n /**\n * keeps track of what level each sequence is at since multiple\n * sequences can start out with the same sequence\n *\n * @type {Object}\n */\n\n var _sequenceLevels = {};\n /**\n * variable to store the setTimeout call\n *\n * @type {null|number}\n */\n\n var _resetTimer;\n /**\n * temporary state where we will ignore the next keyup\n *\n * @type {boolean|string}\n */\n\n\n var _ignoreNextKeyup = false;\n /**\n * temporary state where we will ignore the next keypress\n *\n * @type {boolean}\n */\n\n var _ignoreNextKeypress = false;\n /**\n * are we currently inside of a sequence?\n * type of action (\"keyup\" or \"keydown\" or \"keypress\") or false\n *\n * @type {boolean|string}\n */\n\n var _nextExpectedAction = false;\n /**\n * resets all sequence counters except for the ones passed in\n *\n * @param {Object} doNotReset\n * @returns void\n */\n\n function _resetSequences(doNotReset) {\n doNotReset = doNotReset || {};\n var activeSequences = false,\n key;\n\n for (key in _sequenceLevels) {\n if (doNotReset[key]) {\n activeSequences = true;\n continue;\n }\n\n _sequenceLevels[key] = 0;\n }\n\n if (!activeSequences) {\n _nextExpectedAction = false;\n }\n }\n /**\n * finds all callbacks that match based on the keycode, modifiers,\n * and action\n *\n * @param {string} character\n * @param {Array} modifiers\n * @param {Event|Object} e\n * @param {string=} sequenceName - name of the sequence we are looking for\n * @param {string=} combination\n * @param {number=} level\n * @returns {Array}\n */\n\n\n function _getMatches(character, modifiers, e, sequenceName, combination, level) {\n var i;\n var callback;\n var matches = [];\n var action = e.type; // if there are no events related to this keycode\n\n if (!self._callbacks[character]) {\n return [];\n } // if a modifier key is coming up on its own we should allow it\n\n\n if (action == 'keyup' && _isModifier(character)) {\n modifiers = [character];\n } // loop through all callbacks for the key that was pressed\n // and see if any of them match\n\n\n for (i = 0; i < self._callbacks[character].length; ++i) {\n callback = self._callbacks[character][i]; // if a sequence name is not specified, but this is a sequence at\n // the wrong level then move onto the next match\n\n if (!sequenceName && callback.seq && _sequenceLevels[callback.seq] != callback.level) {\n continue;\n } // if the action we are looking for doesn't match the action we got\n // then we should keep going\n\n\n if (action != callback.action) {\n continue;\n } // if this is a keypress event and the meta key and control key\n // are not pressed that means that we need to only look at the\n // character, otherwise check the modifiers as well\n //\n // chrome will not fire a keypress if meta or control is down\n // safari will fire a keypress if meta or meta+shift is down\n // firefox will fire a keypress if meta or control is down\n\n\n if (action == 'keypress' && !e.metaKey && !e.ctrlKey || _modifiersMatch(modifiers, callback.modifiers)) {\n // when you bind a combination or sequence a second time it\n // should overwrite the first one. if a sequenceName or\n // combination is specified in this call it does just that\n //\n // @todo make deleting its own method?\n var deleteCombo = !sequenceName && callback.combo == combination;\n var deleteSequence = sequenceName && callback.seq == sequenceName && callback.level == level;\n\n if (deleteCombo || deleteSequence) {\n self._callbacks[character].splice(i, 1);\n }\n\n matches.push(callback);\n }\n }\n\n return matches;\n }\n /**\n * actually calls the callback function\n *\n * if your callback function returns false this will use the jquery\n * convention - prevent default and stop propogation on the event\n *\n * @param {Function} callback\n * @param {Event} e\n * @returns void\n */\n\n\n function _fireCallback(callback, e, combo, sequence) {\n // if this event should not happen stop here\n if (self.stopCallback(e, e.target || e.srcElement, combo, sequence)) {\n return;\n }\n\n if (callback(e, combo) === false) {\n _preventDefault(e);\n\n _stopPropagation(e);\n }\n }\n /**\n * handles a character key event\n *\n * @param {string} character\n * @param {Array} modifiers\n * @param {Event} e\n * @returns void\n */\n\n\n self._handleKey = function (character, modifiers, e) {\n var callbacks = _getMatches(character, modifiers, e);\n\n var i;\n var doNotReset = {};\n var maxLevel = 0;\n var processedSequenceCallback = false; // Calculate the maxLevel for sequences so we can only execute the longest callback sequence\n\n for (i = 0; i < callbacks.length; ++i) {\n if (callbacks[i].seq) {\n maxLevel = Math.max(maxLevel, callbacks[i].level);\n }\n } // loop through matching callbacks for this key event\n\n\n for (i = 0; i < callbacks.length; ++i) {\n // fire for all sequence callbacks\n // this is because if for example you have multiple sequences\n // bound such as \"g i\" and \"g t\" they both need to fire the\n // callback for matching g cause otherwise you can only ever\n // match the first one\n if (callbacks[i].seq) {\n // only fire callbacks for the maxLevel to prevent\n // subsequences from also firing\n //\n // for example 'a option b' should not cause 'option b' to fire\n // even though 'option b' is part of the other sequence\n //\n // any sequences that do not match here will be discarded\n // below by the _resetSequences call\n if (callbacks[i].level != maxLevel) {\n continue;\n }\n\n processedSequenceCallback = true; // keep a list of which sequences were matches for later\n\n doNotReset[callbacks[i].seq] = 1;\n\n _fireCallback(callbacks[i].callback, e, callbacks[i].combo, callbacks[i].seq);\n\n continue;\n } // if there were no sequence matches but we are still here\n // that means this is a regular match so we should fire that\n\n\n if (!processedSequenceCallback) {\n _fireCallback(callbacks[i].callback, e, callbacks[i].combo);\n }\n } // if the key you pressed matches the type of sequence without\n // being a modifier (ie \"keyup\" or \"keypress\") then we should\n // reset all sequences that were not matched by this event\n //\n // this is so, for example, if you have the sequence \"h a t\" and you\n // type \"h e a r t\" it does not match. in this case the \"e\" will\n // cause the sequence to reset\n //\n // modifier keys are ignored because you can have a sequence\n // that contains modifiers such as \"enter ctrl+space\" and in most\n // cases the modifier key will be pressed before the next key\n //\n // also if you have a sequence such as \"ctrl+b a\" then pressing the\n // \"b\" key will trigger a \"keypress\" and a \"keydown\"\n //\n // the \"keydown\" is expected when there is a modifier, but the\n // \"keypress\" ends up matching the _nextExpectedAction since it occurs\n // after and that causes the sequence to reset\n //\n // we ignore keypresses in a sequence that directly follow a keydown\n // for the same character\n\n\n var ignoreThisKeypress = e.type == 'keypress' && _ignoreNextKeypress;\n\n if (e.type == _nextExpectedAction && !_isModifier(character) && !ignoreThisKeypress) {\n _resetSequences(doNotReset);\n }\n\n _ignoreNextKeypress = processedSequenceCallback && e.type == 'keydown';\n };\n /**\n * handles a keydown event\n *\n * @param {Event} e\n * @returns void\n */\n\n\n function _handleKeyEvent(e) {\n // normalize e.which for key events\n // @see http://stackoverflow.com/questions/4285627/javascript-keycode-vs-charcode-utter-confusion\n if (typeof e.which !== 'number') {\n e.which = e.keyCode;\n }\n\n var character = _characterFromEvent(e); // no character found then stop\n\n\n if (!character) {\n return;\n } // need to use === for the character check because the character can be 0\n\n\n if (e.type == 'keyup' && _ignoreNextKeyup === character) {\n _ignoreNextKeyup = false;\n return;\n }\n\n self.handleKey(character, _eventModifiers(e), e);\n }\n /**\n * called to set a 1 second timeout on the specified sequence\n *\n * this is so after each key press in the sequence you have 1 second\n * to press the next key before you have to start over\n *\n * @returns void\n */\n\n\n function _resetSequenceTimer() {\n clearTimeout(_resetTimer);\n _resetTimer = setTimeout(_resetSequences, 1000);\n }\n /**\n * binds a key sequence to an event\n *\n * @param {string} combo - combo specified in bind call\n * @param {Array} keys\n * @param {Function} callback\n * @param {string=} action\n * @returns void\n */\n\n\n function _bindSequence(combo, keys, callback, action) {\n // start off by adding a sequence level record for this combination\n // and setting the level to 0\n _sequenceLevels[combo] = 0;\n /**\n * callback to increase the sequence level for this sequence and reset\n * all other sequences that were active\n *\n * @param {string} nextAction\n * @returns {Function}\n */\n\n function _increaseSequence(nextAction) {\n return function () {\n _nextExpectedAction = nextAction;\n ++_sequenceLevels[combo];\n\n _resetSequenceTimer();\n };\n }\n /**\n * wraps the specified callback inside of another function in order\n * to reset all sequence counters as soon as this sequence is done\n *\n * @param {Event} e\n * @returns void\n */\n\n\n function _callbackAndReset(e) {\n _fireCallback(callback, e, combo); // we should ignore the next key up if the action is key down\n // or keypress. this is so if you finish a sequence and\n // release the key the final key will not trigger a keyup\n\n\n if (action !== 'keyup') {\n _ignoreNextKeyup = _characterFromEvent(e);\n } // weird race condition if a sequence ends with the key\n // another sequence begins with\n\n\n setTimeout(_resetSequences, 10);\n } // loop through keys one at a time and bind the appropriate callback\n // function. for any key leading up to the final one it should\n // increase the sequence. after the final, it should reset all sequences\n //\n // if an action is specified in the original bind call then that will\n // be used throughout. otherwise we will pass the action that the\n // next key in the sequence should match. this allows a sequence\n // to mix and match keypress and keydown events depending on which\n // ones are better suited to the key provided\n\n\n for (var i = 0; i < keys.length; ++i) {\n var isFinal = i + 1 === keys.length;\n var wrappedCallback = isFinal ? _callbackAndReset : _increaseSequence(action || _getKeyInfo(keys[i + 1]).action);\n\n _bindSingle(keys[i], wrappedCallback, action, combo, i);\n }\n }\n /**\n * binds a single keyboard combination\n *\n * @param {string} combination\n * @param {Function} callback\n * @param {string=} action\n * @param {string=} sequenceName - name of sequence if part of sequence\n * @param {number=} level - what part of the sequence the command is\n * @returns void\n */\n\n\n function _bindSingle(combination, callback, action, sequenceName, level) {\n // store a direct mapped reference for use with Mousetrap.trigger\n self._directMap[combination + ':' + action] = callback; // make sure multiple spaces in a row become a single space\n\n combination = combination.replace(/\\s+/g, ' ');\n var sequence = combination.split(' ');\n var info; // if this pattern is a sequence of keys then run through this method\n // to reprocess each pattern one key at a time\n\n if (sequence.length > 1) {\n _bindSequence(combination, sequence, callback, action);\n\n return;\n }\n\n info = _getKeyInfo(combination, action); // make sure to initialize array if this is the first time\n // a callback is added for this key\n\n self._callbacks[info.key] = self._callbacks[info.key] || []; // remove an existing match if there is one\n\n _getMatches(info.key, info.modifiers, {\n type: info.action\n }, sequenceName, combination, level); // add this call back to the array\n // if it is a sequence put it at the beginning\n // if not put it at the end\n //\n // this is important because the way these are processed expects\n // the sequence ones to come first\n\n\n self._callbacks[info.key][sequenceName ? 'unshift' : 'push']({\n callback: callback,\n modifiers: info.modifiers,\n action: info.action,\n seq: sequenceName,\n level: level,\n combo: combination\n });\n }\n /**\n * binds multiple combinations to the same callback\n *\n * @param {Array} combinations\n * @param {Function} callback\n * @param {string|undefined} action\n * @returns void\n */\n\n\n self._bindMultiple = function (combinations, callback, action) {\n for (var i = 0; i < combinations.length; ++i) {\n _bindSingle(combinations[i], callback, action);\n }\n }; // start!\n\n\n _addEvent(targetElement, 'keypress', _handleKeyEvent);\n\n _addEvent(targetElement, 'keydown', _handleKeyEvent);\n\n _addEvent(targetElement, 'keyup', _handleKeyEvent);\n }\n /**\n * binds an event to mousetrap\n *\n * can be a single key, a combination of keys separated with +,\n * an array of keys, or a sequence of keys separated by spaces\n *\n * be sure to list the modifier keys first to make sure that the\n * correct key ends up getting bound (the last key in the pattern)\n *\n * @param {string|Array} keys\n * @param {Function} callback\n * @param {string=} action - 'keypress', 'keydown', or 'keyup'\n * @returns void\n */\n\n\n Mousetrap.prototype.bind = function (keys, callback, action) {\n var self = this;\n keys = keys instanceof Array ? keys : [keys];\n\n self._bindMultiple.call(self, keys, callback, action);\n\n return self;\n };\n /**\n * unbinds an event to mousetrap\n *\n * the unbinding sets the callback function of the specified key combo\n * to an empty function and deletes the corresponding key in the\n * _directMap dict.\n *\n * TODO: actually remove this from the _callbacks dictionary instead\n * of binding an empty function\n *\n * the keycombo+action has to be exactly the same as\n * it was defined in the bind method\n *\n * @param {string|Array} keys\n * @param {string} action\n * @returns void\n */\n\n\n Mousetrap.prototype.unbind = function (keys, action) {\n var self = this;\n return self.bind.call(self, keys, function () {}, action);\n };\n /**\n * triggers an event that has already been bound\n *\n * @param {string} keys\n * @param {string=} action\n * @returns void\n */\n\n\n Mousetrap.prototype.trigger = function (keys, action) {\n var self = this;\n\n if (self._directMap[keys + ':' + action]) {\n self._directMap[keys + ':' + action]({}, keys);\n }\n\n return self;\n };\n /**\n * resets the library back to its initial state. this is useful\n * if you want to clear out the current keyboard shortcuts and bind\n * new ones - for example if you switch to another page\n *\n * @returns void\n */\n\n\n Mousetrap.prototype.reset = function () {\n var self = this;\n self._callbacks = {};\n self._directMap = {};\n return self;\n };\n /**\n * should we stop this event before firing off callbacks\n *\n * @param {Event} e\n * @param {Element} element\n * @return {boolean}\n */\n\n\n Mousetrap.prototype.stopCallback = function (e, element) {\n var self = this; // if the element has the class \"mousetrap\" then no need to stop\n\n if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) {\n return false;\n }\n\n if (_belongsTo(element, self.target)) {\n return false;\n } // Events originating from a shadow DOM are re-targetted and `e.target` is the shadow host,\n // not the initial event target in the shadow tree. Note that not all events cross the\n // shadow boundary.\n // For shadow trees with `mode: 'open'`, the initial event target is the first element in\n // the event’s composed path. For shadow trees with `mode: 'closed'`, the initial event\n // target cannot be obtained.\n\n\n if ('composedPath' in e && typeof e.composedPath === 'function') {\n // For open shadow trees, update `element` so that the following check works.\n var initialEventTarget = e.composedPath()[0];\n\n if (initialEventTarget !== e.target) {\n element = initialEventTarget;\n }\n } // stop for input, select, and textarea\n\n\n return element.tagName == 'INPUT' || element.tagName == 'SELECT' || element.tagName == 'TEXTAREA' || element.isContentEditable;\n };\n /**\n * exposes _handleKey publicly so it can be overwritten by extensions\n */\n\n\n Mousetrap.prototype.handleKey = function () {\n var self = this;\n return self._handleKey.apply(self, arguments);\n };\n /**\n * allow custom key mappings\n */\n\n\n Mousetrap.addKeycodes = function (object) {\n for (var key in object) {\n if (object.hasOwnProperty(key)) {\n _MAP[key] = object[key];\n }\n }\n\n _REVERSE_MAP = null;\n };\n /**\n * Init the global mousetrap functions\n *\n * This method is needed to allow the global mousetrap functions to work\n * now that mousetrap is a constructor function.\n */\n\n\n Mousetrap.init = function () {\n var documentMousetrap = Mousetrap(document);\n\n for (var method in documentMousetrap) {\n if (method.charAt(0) !== '_') {\n Mousetrap[method] = function (method) {\n return function () {\n return documentMousetrap[method].apply(documentMousetrap, arguments);\n };\n }(method);\n }\n }\n };\n\n Mousetrap.init(); // expose mousetrap to the global object\n\n window.Mousetrap = Mousetrap; // expose as a common js module\n\n if (typeof module !== 'undefined' && module.exports) {\n module.exports = Mousetrap;\n } // expose mousetrap as an AMD module\n\n\n if (true) {\n !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {\n return Mousetrap;\n }).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n }\n})(typeof window !== 'undefined' ? window : null, typeof window !== 'undefined' ? document : null);\n\n//# sourceURL=webpack:///./node_modules/mousetrap/mousetrap.js?"); - -/***/ }), - -/***/ "./node_modules/webpack/buildin/module.js": -/*!***********************************!*\ - !*** (webpack)/buildin/module.js ***! - \***********************************/ -/*! no static exports found */ -/*! ModuleConcatenation bailout: Module is not an ECMAScript module */ -/***/ (function(module, exports) { - -eval("module.exports = function (module) {\n if (!module.webpackPolyfill) {\n module.deprecate = function () {};\n\n module.paths = []; // module.parent = undefined by default\n\n if (!module.children) module.children = [];\n Object.defineProperty(module, \"loaded\", {\n enumerable: true,\n get: function get() {\n return module.l;\n }\n });\n Object.defineProperty(module, \"id\", {\n enumerable: true,\n get: function get() {\n return module.i;\n }\n });\n module.webpackPolyfill = 1;\n }\n\n return module;\n};\n\n//# sourceURL=webpack:///(webpack)/buildin/module.js?"); - -/***/ }), - -/***/ "./node_modules/wolfy87-eventemitter/EventEmitter.js": -/*!***********************************************************!*\ - !*** ./node_modules/wolfy87-eventemitter/EventEmitter.js ***! - \***********************************************************/ -/*! no static exports found */ -/*! ModuleConcatenation bailout: Module is not an ECMAScript module */ -/***/ (function(module, exports, __webpack_require__) { - -eval("var __WEBPACK_AMD_DEFINE_RESULT__;function _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n/*!\n * EventEmitter v5.2.6 - git.io/ee\n * Unlicense - http://unlicense.org/\n * Oliver Caldwell - https://oli.me.uk/\n * @preserve\n */\n;\n\n(function (exports) {\n 'use strict';\n /**\n * Class for managing events.\n * Can be extended to provide event functionality in other classes.\n *\n * @class EventEmitter Manages event registering and emitting.\n */\n\n function EventEmitter() {} // Shortcuts to improve speed and size\n\n\n var proto = EventEmitter.prototype;\n var originalGlobalValue = exports.EventEmitter;\n /**\n * Finds the index of the listener for the event in its storage array.\n *\n * @param {Function[]} listeners Array of listeners to search through.\n * @param {Function} listener Method to look for.\n * @return {Number} Index of the specified listener, -1 if not found\n * @api private\n */\n\n function indexOfListener(listeners, listener) {\n var i = listeners.length;\n\n while (i--) {\n if (listeners[i].listener === listener) {\n return i;\n }\n }\n\n return -1;\n }\n /**\n * Alias a method while keeping the context correct, to allow for overwriting of target method.\n *\n * @param {String} name The name of the target method.\n * @return {Function} The aliased method\n * @api private\n */\n\n\n function alias(name) {\n return function aliasClosure() {\n return this[name].apply(this, arguments);\n };\n }\n /**\n * Returns the listener array for the specified event.\n * Will initialise the event object and listener arrays if required.\n * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.\n * Each property in the object response is an array of listener functions.\n *\n * @param {String|RegExp} evt Name of the event to return the listeners from.\n * @return {Function[]|Object} All listener functions for the event.\n */\n\n\n proto.getListeners = function getListeners(evt) {\n var events = this._getEvents();\n\n var response;\n var key; // Return a concatenated array of all matching events if\n // the selector is a regular expression.\n\n if (evt instanceof RegExp) {\n response = {};\n\n for (key in events) {\n if (events.hasOwnProperty(key) && evt.test(key)) {\n response[key] = events[key];\n }\n }\n } else {\n response = events[evt] || (events[evt] = []);\n }\n\n return response;\n };\n /**\n * Takes a list of listener objects and flattens it into a list of listener functions.\n *\n * @param {Object[]} listeners Raw listener objects.\n * @return {Function[]} Just the listener functions.\n */\n\n\n proto.flattenListeners = function flattenListeners(listeners) {\n var flatListeners = [];\n var i;\n\n for (i = 0; i < listeners.length; i += 1) {\n flatListeners.push(listeners[i].listener);\n }\n\n return flatListeners;\n };\n /**\n * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.\n *\n * @param {String|RegExp} evt Name of the event to return the listeners from.\n * @return {Object} All listener functions for an event in an object.\n */\n\n\n proto.getListenersAsObject = function getListenersAsObject(evt) {\n var listeners = this.getListeners(evt);\n var response;\n\n if (listeners instanceof Array) {\n response = {};\n response[evt] = listeners;\n }\n\n return response || listeners;\n };\n\n function isValidListener(listener) {\n if (typeof listener === 'function' || listener instanceof RegExp) {\n return true;\n } else if (listener && _typeof(listener) === 'object') {\n return isValidListener(listener.listener);\n } else {\n return false;\n }\n }\n /**\n * Adds a listener function to the specified event.\n * The listener will not be added if it is a duplicate.\n * If the listener returns true then it will be removed after it is called.\n * If you pass a regular expression as the event name then the listener will be added to all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to attach the listener to.\n * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n\n\n proto.addListener = function addListener(evt, listener) {\n if (!isValidListener(listener)) {\n throw new TypeError('listener must be a function');\n }\n\n var listeners = this.getListenersAsObject(evt);\n var listenerIsWrapped = _typeof(listener) === 'object';\n var key;\n\n for (key in listeners) {\n if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {\n listeners[key].push(listenerIsWrapped ? listener : {\n listener: listener,\n once: false\n });\n }\n }\n\n return this;\n };\n /**\n * Alias of addListener\n */\n\n\n proto.on = alias('addListener');\n /**\n * Semi-alias of addListener. It will add a listener that will be\n * automatically removed after its first execution.\n *\n * @param {String|RegExp} evt Name of the event to attach the listener to.\n * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n\n proto.addOnceListener = function addOnceListener(evt, listener) {\n return this.addListener(evt, {\n listener: listener,\n once: true\n });\n };\n /**\n * Alias of addOnceListener.\n */\n\n\n proto.once = alias('addOnceListener');\n /**\n * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.\n * You need to tell it what event names should be matched by a regex.\n *\n * @param {String} evt Name of the event to create.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n\n proto.defineEvent = function defineEvent(evt) {\n this.getListeners(evt);\n return this;\n };\n /**\n * Uses defineEvent to define multiple events.\n *\n * @param {String[]} evts An array of event names to define.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n\n\n proto.defineEvents = function defineEvents(evts) {\n for (var i = 0; i < evts.length; i += 1) {\n this.defineEvent(evts[i]);\n }\n\n return this;\n };\n /**\n * Removes a listener function from the specified event.\n * When passed a regular expression as the event name, it will remove the listener from all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to remove the listener from.\n * @param {Function} listener Method to remove from the event.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n\n\n proto.removeListener = function removeListener(evt, listener) {\n var listeners = this.getListenersAsObject(evt);\n var index;\n var key;\n\n for (key in listeners) {\n if (listeners.hasOwnProperty(key)) {\n index = indexOfListener(listeners[key], listener);\n\n if (index !== -1) {\n listeners[key].splice(index, 1);\n }\n }\n }\n\n return this;\n };\n /**\n * Alias of removeListener\n */\n\n\n proto.off = alias('removeListener');\n /**\n * Adds listeners in bulk using the manipulateListeners method.\n * If you pass an object as the first argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.\n * You can also pass it a regular expression to add the array of listeners to all events that match it.\n * Yeah, this function does quite a bit. That's probably a bad thing.\n *\n * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.\n * @param {Function[]} [listeners] An optional array of listener functions to add.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n\n proto.addListeners = function addListeners(evt, listeners) {\n // Pass through to manipulateListeners\n return this.manipulateListeners(false, evt, listeners);\n };\n /**\n * Removes listeners in bulk using the manipulateListeners method.\n * If you pass an object as the first argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n * You can also pass it an event name and an array of listeners to be removed.\n * You can also pass it a regular expression to remove the listeners from all events that match it.\n *\n * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.\n * @param {Function[]} [listeners] An optional array of listener functions to remove.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n\n\n proto.removeListeners = function removeListeners(evt, listeners) {\n // Pass through to manipulateListeners\n return this.manipulateListeners(true, evt, listeners);\n };\n /**\n * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.\n * The first argument will determine if the listeners are removed (true) or added (false).\n * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.\n * You can also pass it an event name and an array of listeners to be added/removed.\n * You can also pass it a regular expression to manipulate the listeners of all events that match it.\n *\n * @param {Boolean} remove True if you want to remove listeners, false if you want to add.\n * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.\n * @param {Function[]} [listeners] An optional array of listener functions to add/remove.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n\n\n proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {\n var i;\n var value;\n var single = remove ? this.removeListener : this.addListener;\n var multiple = remove ? this.removeListeners : this.addListeners; // If evt is an object then pass each of its properties to this method\n\n if (_typeof(evt) === 'object' && !(evt instanceof RegExp)) {\n for (i in evt) {\n if (evt.hasOwnProperty(i) && (value = evt[i])) {\n // Pass the single listener straight through to the singular method\n if (typeof value === 'function') {\n single.call(this, i, value);\n } else {\n // Otherwise pass back to the multiple function\n multiple.call(this, i, value);\n }\n }\n }\n } else {\n // So evt must be a string\n // And listeners must be an array of listeners\n // Loop over it and pass each one to the multiple method\n i = listeners.length;\n\n while (i--) {\n single.call(this, evt, listeners[i]);\n }\n }\n\n return this;\n };\n /**\n * Removes all listeners from a specified event.\n * If you do not specify an event then all listeners will be removed.\n * That means every event will be emptied.\n * You can also pass a regex to remove all events that match it.\n *\n * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n\n\n proto.removeEvent = function removeEvent(evt) {\n var type = _typeof(evt);\n\n var events = this._getEvents();\n\n var key; // Remove different things depending on the state of evt\n\n if (type === 'string') {\n // Remove all listeners for the specified event\n delete events[evt];\n } else if (evt instanceof RegExp) {\n // Remove all events matching the regex.\n for (key in events) {\n if (events.hasOwnProperty(key) && evt.test(key)) {\n delete events[key];\n }\n }\n } else {\n // Remove all listeners in all events\n delete this._events;\n }\n\n return this;\n };\n /**\n * Alias of removeEvent.\n *\n * Added to mirror the node API.\n */\n\n\n proto.removeAllListeners = alias('removeEvent');\n /**\n * Emits an event of your choice.\n * When emitted, every listener attached to that event will be executed.\n * If you pass the optional argument array then those arguments will be passed to every listener upon execution.\n * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.\n * So they will not arrive within the array on the other side, they will be separate.\n * You can also pass a regular expression to emit to all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n * @param {Array} [args] Optional array of arguments to be passed to each listener.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n\n proto.emitEvent = function emitEvent(evt, args) {\n var listenersMap = this.getListenersAsObject(evt);\n var listeners;\n var listener;\n var i;\n var key;\n var response;\n\n for (key in listenersMap) {\n if (listenersMap.hasOwnProperty(key)) {\n listeners = listenersMap[key].slice(0);\n\n for (i = 0; i < listeners.length; i++) {\n // If the listener returns true then it shall be removed from the event\n // The function is executed either with a basic call or an apply if there is an args array\n listener = listeners[i];\n\n if (listener.once === true) {\n this.removeListener(evt, listener.listener);\n }\n\n response = listener.listener.apply(this, args || []);\n\n if (response === this._getOnceReturnValue()) {\n this.removeListener(evt, listener.listener);\n }\n }\n }\n }\n\n return this;\n };\n /**\n * Alias of emitEvent\n */\n\n\n proto.trigger = alias('emitEvent');\n /**\n * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.\n * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.\n *\n * @param {String|RegExp} evt Name of the event to emit and execute listeners for.\n * @param {...*} Optional additional arguments to be passed to each listener.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n\n proto.emit = function emit(evt) {\n var args = Array.prototype.slice.call(arguments, 1);\n return this.emitEvent(evt, args);\n };\n /**\n * Sets the current value to check against when executing listeners. If a\n * listeners return value matches the one set here then it will be removed\n * after execution. This value defaults to true.\n *\n * @param {*} value The new value to check for when executing listeners.\n * @return {Object} Current instance of EventEmitter for chaining.\n */\n\n\n proto.setOnceReturnValue = function setOnceReturnValue(value) {\n this._onceReturnValue = value;\n return this;\n };\n /**\n * Fetches the current value to check against when executing listeners. If\n * the listeners return value matches this one then it should be removed\n * automatically. It will return true by default.\n *\n * @return {*|Boolean} The current value to check for or the default, true.\n * @api private\n */\n\n\n proto._getOnceReturnValue = function _getOnceReturnValue() {\n if (this.hasOwnProperty('_onceReturnValue')) {\n return this._onceReturnValue;\n } else {\n return true;\n }\n };\n /**\n * Fetches the events object and creates one if required.\n *\n * @return {Object} The events storage object.\n * @api private\n */\n\n\n proto._getEvents = function _getEvents() {\n return this._events || (this._events = {});\n };\n /**\n * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.\n *\n * @return {Function} Non conflicting EventEmitter class.\n */\n\n\n EventEmitter.noConflict = function noConflict() {\n exports.EventEmitter = originalGlobalValue;\n return EventEmitter;\n }; // Expose the class either via AMD, CommonJS or the global object\n\n\n if (true) {\n !(__WEBPACK_AMD_DEFINE_RESULT__ = (function () {\n return EventEmitter;\n }).call(exports, __webpack_require__, exports, module),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else {}\n})(typeof window !== 'undefined' ? window : this || {});\n\n//# sourceURL=webpack:///./node_modules/wolfy87-eventemitter/EventEmitter.js?"); - -/***/ }), - -/***/ "./src/scripts/components/copy-to-clipboard.js": -/*!*****************************************************!*\ - !*** ./src/scripts/components/copy-to-clipboard.js ***! - \*****************************************************/ -/*! no exports provided */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var clipboard__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! clipboard */ \"./node_modules/clipboard/dist/clipboard.js\");\n/* harmony import */ var clipboard__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(clipboard__WEBPACK_IMPORTED_MODULE_0__);\n/**\n * Copy to clipboard functionality for code snippet examples\n */\n\nvar clipboard = new clipboard__WEBPACK_IMPORTED_MODULE_0___default.a('.pl-js-code-copy-btn');\nclipboard.on('success', function (e) {\n var copyButton = document.querySelectorAll('.pl-js-code-copy-btn');\n\n for (var i = 0; i < copyButton.length; i++) {\n copyButton[i].innerText = 'Copy';\n }\n\n e.trigger.textContent = 'Copied';\n});\n\n//# sourceURL=webpack:///./src/scripts/components/copy-to-clipboard.js?"); - -/***/ }), - -/***/ "./src/scripts/components/panels-util.js": -/*!***********************************************!*\ - !*** ./src/scripts/components/panels-util.js ***! - \***********************************************/ -/*! exports provided: panelsUtil */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"panelsUtil\", function() { return panelsUtil; });\n/**\n * Panels Util - for both styleguide and viewer\n */\nvar panelsUtil = {\n /**\n * Add click events to the template that was rendered\n * @param {String} the rendered template for the modal\n * @param {String} the pattern partial for the modal\n */\n addClickEvents: function addClickEvents(templateRendered, patternPartial) {\n var els = templateRendered.querySelectorAll('.pl-js-tab-link');\n\n for (var i = 0; i < els.length; ++i) {\n els[i].onclick = function (e) {\n e.preventDefault();\n var partial = this.getAttribute('data-patternpartial');\n var panelID = this.getAttribute('data-panelid');\n panelsUtil.show(partial, panelID);\n };\n }\n\n return templateRendered;\n },\n\n /**\n * Show a specific modal\n * @param {String} the pattern partial for the modal\n * @param {String} the ID of the panel to be shown\n */\n show: function show(patternPartial, panelID) {\n var activeTabClass = 'pl-is-active-tab'; // turn off all of the active tabs\n\n var allTabLinks = document.querySelectorAll(\".pl-js-tab-link\"); // hide all of the panels\n\n var allTabPanels = document.querySelectorAll(\".pl-js-tab-panel\"); // tabLink about to become active\n\n var activeTabLink = document.querySelector(\"#pl-\".concat(patternPartial, \"-\").concat(panelID, \"-tab\")); // tabPanelabout to become active\n\n var activeTabPanel = document.querySelector(\"#pl-\".concat(patternPartial, \"-\").concat(panelID, \"-panel\"));\n\n for (var i = 0; i < allTabLinks.length; ++i) {\n allTabLinks[i].classList.remove(activeTabClass);\n }\n\n for (var _i = 0; _i < allTabPanels.length; ++_i) {\n allTabPanels[_i].classList.remove(activeTabClass);\n }\n\n activeTabLink.classList.add(activeTabClass);\n activeTabPanel.classList.add(activeTabClass);\n }\n};\n\n//# sourceURL=webpack:///./src/scripts/components/panels-util.js?"); - -/***/ }), - -/***/ "./src/scripts/patternlab-pattern.js": -/*!*******************************************************!*\ - !*** ./src/scripts/patternlab-pattern.js + 2 modules ***! - \*******************************************************/ -/*! no exports provided */ -/*! ModuleConcatenation bailout: Cannot concat with ./node_modules/mousetrap/mousetrap.js (<- Module is not an ECMAScript module) */ -/*! ModuleConcatenation bailout: Cannot concat with ./src/scripts/components/copy-to-clipboard.js */ -/*! ModuleConcatenation bailout: Cannot concat with ./src/scripts/components/panels-util.js */ -/*! ModuleConcatenation bailout: Cannot concat with ./src/scripts/utils/index.js */ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -eval("\n// EXTERNAL MODULE: ./src/scripts/utils/postmessage.js\nvar postmessage = __webpack_require__(\"./src/scripts/utils/postmessage.js\");\n\n// EXTERNAL MODULE: ./src/scripts/components/panels-util.js\nvar panels_util = __webpack_require__(\"./src/scripts/components/panels-util.js\");\n\n// EXTERNAL MODULE: ./src/scripts/components/copy-to-clipboard.js\nvar copy_to_clipboard = __webpack_require__(\"./src/scripts/components/copy-to-clipboard.js\");\n\n// CONCATENATED MODULE: ./src/scripts/components/modal-styleguide.js\n/**\n * \"Modal\" (aka Panel UI) for the Styleguide Layer - for both annotations and code/info\n */\n\n\nvar modalStyleguide = {\n // set up some defaults\n active: [],\n targetOrigin: window.location.protocol === 'file:' ? '*' : window.location.protocol + '//' + window.location.host,\n\n /**\n * initialize the modal window\n */\n onReady: function onReady() {\n // go through the panel toggles and add click event to the pattern extra toggle button\n var els = document.querySelectorAll('.pl-js-pattern-extra-toggle');\n\n for (var i = 0; i < els.length; ++i) {\n els[i].onclick = function (e) {\n var patternPartial = this.getAttribute('data-patternpartial');\n modalStyleguide.toggle(patternPartial);\n };\n }\n },\n\n /**\n * toggle the modal window open and closed based on clicking the pip\n * @param {String} the patternPartial that identifies what needs to be toggled\n */\n toggle: function toggle(patternPartial) {\n if (modalStyleguide.active[patternPartial] === undefined || !modalStyleguide.active[patternPartial]) {\n var el = document.getElementById('pl-pattern-data-' + patternPartial);\n modalStyleguide.collectAndSend(el, true, false);\n } else {\n modalStyleguide.highlightsHide();\n modalStyleguide.close(patternPartial);\n }\n },\n\n /**\n * open the modal window for a view-all entry\n * @param {String} the patternPartial that identifies what needs to be opened\n * @param {String} the content that should be inserted\n */\n open: function open(patternPartial, content) {\n // make sure templateRendered is modified to be an HTML element\n var div = document.createElement('div');\n div.innerHTML = content;\n content = document.createElement('div').appendChild(div).querySelector('div'); // add click events\n\n content = panels_util[\"panelsUtil\"].addClickEvents(content, patternPartial); // make sure the modal viewer and other options are off just in case\n\n modalStyleguide.close(patternPartial); // note it's turned on in the viewer\n\n modalStyleguide.active[patternPartial] = true; // make sure there's no content\n\n div = document.getElementById('pl-pattern-extra-' + patternPartial);\n\n if (div.childNodes.length > 0) {\n div.removeChild(div.childNodes[0]);\n } // add the content\n\n\n document.getElementById('pl-pattern-extra-' + patternPartial).appendChild(content); // show the modal\n\n document.getElementById('pl-pattern-extra-toggle-' + patternPartial).classList.add('pl-is-active');\n document.getElementById('pl-pattern-extra-' + patternPartial).classList.add('pl-is-active');\n },\n\n /**\n * close the modal window for a view-all entry\n * @param {String} the patternPartial that identifies what needs to be closed\n */\n close: function close(patternPartial) {\n // note that the modal viewer is no longer active\n modalStyleguide.active[patternPartial] = false; // hide the modal, look at info-panel.js\n\n document.getElementById('pl-pattern-extra-toggle-' + patternPartial).classList.remove('pl-is-active');\n document.getElementById('pl-pattern-extra-' + patternPartial).classList.remove('pl-is-active');\n },\n\n /**\n * get the data that needs to be send to the viewer for rendering\n * @param {Element} the identifier for the element that needs to be collected\n * @param {Boolean} if the refresh is of a view-all view and the content should be sent back\n * @param {Boolean} if the text in the dropdown should be switched\n */\n collectAndSend: function collectAndSend(el, iframePassback, switchText) {\n /**\n * Verify - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + + Pattern Lab + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/uikit-workshop/src/html/partials/controls.html b/packages/uikit-workshop/src/html/partials/controls.html deleted file mode 100644 index 533752058..000000000 --- a/packages/uikit-workshop/src/html/partials/controls.html +++ /dev/null @@ -1,87 +0,0 @@ - -
- - -
- -
    - {{^ ishControlsHide.s }} -
  • - -
  • - {{/ ishControlsHide.s }} - - {{^ ishControlsHide.m }} -
  • - -
  • - {{/ ishControlsHide.m }} - - {{^ ishControlsHide.l }} -
  • - -
  • - {{/ ishControlsHide.l }} - - {{^ ishControlsHide.full }} -
  • - -
  • - {{/ ishControlsHide.full }} - - {{^ ishControlsHide.random }} -
  • - -
  • - {{/ ishControlsHide.random }} - - {{^ ishControlsHide.disco }} -
  • - -
  • - {{/ ishControlsHide.disco }} - - {{^ ishControlsHide.hay }} -
  • - -
  • - {{/ ishControlsHide.hay }} -
- -{{^ ishControlsHide.tools-all }} -
- - -
    -
  • - - - -
  • -
  • - -
  • -
  • - -
  • - {{^ ishControlsHide.views-new }} -
  • - Open In New Tab -
  • - {{/ ishControlsHide.views-new }} - - {{^ ishControlsHide.tools-docs }} -
  • - Pattern Lab Docs -
  • - {{/ ishControlsHide.tools-docs }} -
-
-{{/ ishControlsHide.tools-all }} \ No newline at end of file diff --git a/packages/uikit-workshop/src/html/partials/header.html b/packages/uikit-workshop/src/html/partials/header.html deleted file mode 100644 index da990cf32..000000000 --- a/packages/uikit-workshop/src/html/partials/header.html +++ /dev/null @@ -1,25 +0,0 @@ - diff --git a/packages/uikit-workshop/src/html/partials/iframe-loader.html b/packages/uikit-workshop/src/html/partials/iframe-loader.html deleted file mode 100644 index 40086f8aa..000000000 --- a/packages/uikit-workshop/src/html/partials/iframe-loader.html +++ /dev/null @@ -1,15 +0,0 @@ - - -
-
-
Loading Pattern Lab
-
- - - - - -
-
-
diff --git a/packages/uikit-workshop/src/html/partials/iframe.html b/packages/uikit-workshop/src/html/partials/iframe.html deleted file mode 100644 index 0ae6a5752..000000000 --- a/packages/uikit-workshop/src/html/partials/iframe.html +++ /dev/null @@ -1,20 +0,0 @@ -
- -
- -
- - - -
- -
- -
- - -
- - -
- \ No newline at end of file diff --git a/packages/uikit-workshop/src/html/partials/modal.html b/packages/uikit-workshop/src/html/partials/modal.html deleted file mode 100644 index 724e6c667..000000000 --- a/packages/uikit-workshop/src/html/partials/modal.html +++ /dev/null @@ -1,20 +0,0 @@ -
-
-
-
-
- - - - -
-
-
-
-
-
diff --git a/packages/uikit-workshop/src/html/partials/pattern-nav.html b/packages/uikit-workshop/src/html/partials/pattern-nav.html deleted file mode 100644 index a3b17fae2..000000000 --- a/packages/uikit-workshop/src/html/partials/pattern-nav.html +++ /dev/null @@ -1,59 +0,0 @@ -{{# patternTypes }} -
  • - - - -
      - - {{# patternTypeItems }} -
    1. - - - -
        - - {{# patternSubtypeItems }} -
      1. - - - {{ patternName }} - - {{# patternState }} - - {{/ patternState }} - - - -
      2. - {{/ patternSubtypeItems }} - -
      - -
    2. - {{/ patternTypeItems }} - {{# patternItems }} -
    3. - - - {{ patternName }} - - {{# patternState }} - - {{/ patternState }} - - - -
    4. - {{/ patternItems }} - -
    - -
  • -{{/ patternTypes }} - -
  • - - All - -
  • - diff --git a/packages/uikit-workshop/src/icons/arrow-down.svg b/packages/uikit-workshop/src/icons/arrow-down.svg new file mode 100755 index 000000000..e37dff879 --- /dev/null +++ b/packages/uikit-workshop/src/icons/arrow-down.svg @@ -0,0 +1,5 @@ + + +arrow_drop_down + + diff --git a/packages/uikit-workshop/src/icons/close.svg b/packages/uikit-workshop/src/icons/close.svg new file mode 100755 index 000000000..fb4be45bb --- /dev/null +++ b/packages/uikit-workshop/src/icons/close.svg @@ -0,0 +1,5 @@ + + +close + + diff --git a/packages/uikit-workshop/src/icons/desktop.svg b/packages/uikit-workshop/src/icons/desktop.svg new file mode 100755 index 000000000..c175122e6 --- /dev/null +++ b/packages/uikit-workshop/src/icons/desktop.svg @@ -0,0 +1,5 @@ + + +desktop_mac + + diff --git a/packages/uikit-workshop/src/icons/disco-ball.svg b/packages/uikit-workshop/src/icons/disco-ball.svg new file mode 100755 index 000000000..9b5e75430 --- /dev/null +++ b/packages/uikit-workshop/src/icons/disco-ball.svg @@ -0,0 +1,15 @@ + + + + Artboard + Created with Sketch. + + + + + + + + + + \ No newline at end of file diff --git a/packages/uikit-workshop/src/icons/help.svg b/packages/uikit-workshop/src/icons/help.svg new file mode 100755 index 000000000..5289573ca --- /dev/null +++ b/packages/uikit-workshop/src/icons/help.svg @@ -0,0 +1,5 @@ + + +help_outline + + diff --git a/packages/uikit-workshop/src/icons/hide.svg b/packages/uikit-workshop/src/icons/hide.svg new file mode 100755 index 000000000..fd370e451 --- /dev/null +++ b/packages/uikit-workshop/src/icons/hide.svg @@ -0,0 +1,5 @@ + + +view-hide + + diff --git a/packages/uikit-workshop/src/icons/laptop.svg b/packages/uikit-workshop/src/icons/laptop.svg new file mode 100755 index 000000000..9ad3077f7 --- /dev/null +++ b/packages/uikit-workshop/src/icons/laptop.svg @@ -0,0 +1,5 @@ + + +laptop_mac + + diff --git a/packages/uikit-workshop/src/icons/menu.svg b/packages/uikit-workshop/src/icons/menu.svg new file mode 100755 index 000000000..620494ef8 --- /dev/null +++ b/packages/uikit-workshop/src/icons/menu.svg @@ -0,0 +1,5 @@ + + +menu + + diff --git a/packages/uikit-workshop/src/icons/new-tab.svg b/packages/uikit-workshop/src/icons/new-tab.svg new file mode 100755 index 000000000..ea59a1cb2 --- /dev/null +++ b/packages/uikit-workshop/src/icons/new-tab.svg @@ -0,0 +1,5 @@ + + +open_in_new + + diff --git a/packages/uikit-workshop/src/icons/phone.svg b/packages/uikit-workshop/src/icons/phone.svg new file mode 100755 index 000000000..b47123560 --- /dev/null +++ b/packages/uikit-workshop/src/icons/phone.svg @@ -0,0 +1,5 @@ + + +phone_iphone + + diff --git a/packages/uikit-workshop/src/icons/random.svg b/packages/uikit-workshop/src/icons/random.svg new file mode 100755 index 000000000..c42db187a --- /dev/null +++ b/packages/uikit-workshop/src/icons/random.svg @@ -0,0 +1,11 @@ + + + + casino + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/packages/uikit-workshop/src/icons/settings.svg b/packages/uikit-workshop/src/icons/settings.svg new file mode 100755 index 000000000..0ffd7ff4a --- /dev/null +++ b/packages/uikit-workshop/src/icons/settings.svg @@ -0,0 +1,5 @@ + + +settings + + diff --git a/packages/uikit-workshop/src/icons/show.svg b/packages/uikit-workshop/src/icons/show.svg new file mode 100755 index 000000000..3b4bcfcb3 --- /dev/null +++ b/packages/uikit-workshop/src/icons/show.svg @@ -0,0 +1,5 @@ + + +view-show + + diff --git a/packages/uikit-workshop/src/icons/tablet.svg b/packages/uikit-workshop/src/icons/tablet.svg new file mode 100755 index 000000000..8a2174385 --- /dev/null +++ b/packages/uikit-workshop/src/icons/tablet.svg @@ -0,0 +1,5 @@ + + +tablet_mac + + diff --git a/packages/uikit-workshop/src/images/pattern-lab-logo--on-dark.svg b/packages/uikit-workshop/src/images/pattern-lab-logo--on-dark.svg new file mode 100644 index 000000000..59cc46b0a --- /dev/null +++ b/packages/uikit-workshop/src/images/pattern-lab-logo--on-dark.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/uikit-workshop/src/images/pattern-lab-logo--on-light.svg b/packages/uikit-workshop/src/images/pattern-lab-logo--on-light.svg new file mode 100644 index 000000000..549f60c02 --- /dev/null +++ b/packages/uikit-workshop/src/images/pattern-lab-logo--on-light.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/uikit-workshop/src/sass/pattern-lab.scss b/packages/uikit-workshop/src/sass/pattern-lab.scss index d38ba1515..25cecaa39 100755 --- a/packages/uikit-workshop/src/sass/pattern-lab.scss +++ b/packages/uikit-workshop/src/sass/pattern-lab.scss @@ -44,36 +44,29 @@ #COMPONENTS \*------------------------------------*/ -/** - * Pattern Lab Header - */ -@import '../scripts/components/pl-search/pl-search.scss'; +@import '../scripts/components/pl-controls/pl-controls.scss'; +@import '../scripts/components/pl-drawer/pl-drawer.scss'; +@import '../scripts/components/pl-header/pl-header.scss'; @import '../scripts/components/pl-layout/pl-layout.scss'; -@import 'scss/04-components/header'; -@import 'scss/04-components/logo'; -@import 'scss/04-components/navigation'; -@import 'scss/04-components/ish-sizing'; -@import 'scss/04-components/controls'; -@import 'scss/04-components/tools'; - -/** - * Viewport - */ -@import 'scss/04-components/viewport'; - -/** - * Pattern Styles - */ -@import 'scss/04-components/pattern'; +@import '../scripts/components/pl-nav/pl-nav.scss'; +@import '../scripts/components/pl-logo/pl-logo.scss'; +@import '../scripts/components/pl-tooltip/pl-tooltip.scss'; +@import '../scripts/components/pl-search/pl-search.scss'; +@import '../scripts/components/pl-toggle-info/pl-toggle-info.scss'; +@import '../scripts/components/pl-toggle-layout/pl-toggle-layout.scss'; +@import '../scripts/components/pl-toggle-theme/pl-toggle-theme.scss'; +@import '../scripts/components/pl-tools-menu/pl-tools-menu.scss'; +@import '../scripts/components/pl-viewport/pl-viewport.scss'; +@import '../scripts/components/pl-viewport-size/pl-viewport-size.scss'; +@import '../scripts/components/pl-viewport-size-list/pl-viewport-size-list.scss'; +@import 'scss/04-components/annotations'; +@import 'scss/04-components/breadcrumbs'; @import 'scss/04-components/pattern-category'; @import 'scss/04-components/pattern-info'; -@import 'scss/04-components/pattern-states'; @import 'scss/04-components/pattern-lineage'; -@import 'scss/04-components/breadcrumbs'; +@import 'scss/04-components/pattern-states'; +@import 'scss/04-components/pattern'; @import 'scss/04-components/tabs'; -@import 'scss/04-components/tools'; -@import 'scss/04-components/annotations'; -@import 'scss/04-components/modal'; @import 'scss/04-components/text-passage'; /*------------------------------------*\ diff --git a/packages/uikit-workshop/src/sass/scss/01-abstracts/_mixins.scss b/packages/uikit-workshop/src/sass/scss/01-abstracts/_mixins.scss index c06101c06..6b1dfb5b9 100644 --- a/packages/uikit-workshop/src/sass/scss/01-abstracts/_mixins.scss +++ b/packages/uikit-workshop/src/sass/scss/01-abstracts/_mixins.scss @@ -27,8 +27,8 @@ * Header Link Style */ @mixin linkStyle() { - background-color: $pl-color-black; - color: $pl-color-gray-50; + @include noSelect; + color: inherit; text-decoration: none; line-height: 1; padding: 0.7rem 0.5rem; @@ -37,38 +37,19 @@ transition: background-color $pl-animate-quick ease-out, color $pl-animate-quick ease-out; cursor: pointer; - outline-offset: -3px; - outline-width: 2px; + outline: 0; - &:hover { - color: $pl-color-white; - background-color: $pl-color-gray-87; + &:hover, + &.pl-is-active:hover { + background-color: rgba(0, 0, 0, .1); } - &.pl-is-active, - &:active { - color: $pl-color-white; - background-color: $pl-color-gray-87; - outline: 1px dotted $pl-color-gray-50; - outline-offset: -1px; - } /** * Header link styles inside light theme */ - .pl-c-body--theme-light & { - background-color: $pl-color-white; - color: $pl-color-gray-70; - &:hover { - background-color: $pl-color-gray-07; - } - &:active, - &:focus { - background-color: $pl-color-gray-13; - } - } /** * Header link styles inside cozy theme diff --git a/packages/uikit-workshop/src/sass/scss/01-abstracts/_variables.scss b/packages/uikit-workshop/src/sass/scss/01-abstracts/_variables.scss index 364b3aab4..fb8499ec4 100644 --- a/packages/uikit-workshop/src/sass/scss/01-abstracts/_variables.scss +++ b/packages/uikit-workshop/src/sass/scss/01-abstracts/_variables.scss @@ -26,10 +26,10 @@ $pl-color-state-inreview: #c7a118; $pl-color-state-deprecated: #b00b02; // Font Family -$pl-font: 'HelveticaNeue', 'Helvetica', 'Arial', sans-serif; +$pl-font: 'Open Sans', 'HelveticaNeue', 'Helvetica', 'Arial', sans-serif !default; // Font sizes -$pl-font-size-sm: 0.7rem; +$pl-font-size-sm: 0.9rem; $pl-font-size-sm-2: 0.85rem; $pl-font-size-norm: 1rem; $pl-font-size-large: 1.2rem; @@ -55,4 +55,4 @@ $pl-border-radius: 3px; $pl-border-radius-med: 6px; -$pl-sidebar-width: 14rem; //Define sidebar width for calculating dimensions \ No newline at end of file +$pl-sidebar-width: 16rem; //Define sidebar width for calculating dimensions \ No newline at end of file diff --git a/packages/uikit-workshop/src/sass/scss/02-base/_body.scss b/packages/uikit-workshop/src/sass/scss/02-base/_body.scss index 90bc557f0..bda277ca3 100644 --- a/packages/uikit-workshop/src/sass/scss/02-base/_body.scss +++ b/packages/uikit-workshop/src/sass/scss/02-base/_body.scss @@ -17,3 +17,23 @@ -webkit-text-size-adjust: 100%; display: flex; // Required for IE 11 to display overall PL layout correctly } + +// @todo: refactor to make colors more generic to PL: +.pl-c-body--theme-dark, +:root { + --theme-bg: #161b3c; + --theme-primary: #464a6d; + --theme-secondary: #161f50; + --theme-text: white; + --theme-text-rgb: 255,255,255; + --theme-border: rgba(255, 255, 255, 0.2); +} + +.pl-c-body--theme-light { + --theme-bg: white; + --theme-secondary: white; + --theme-text: #262829; + --theme-text-rgb: 38, 40, 41; + --theme-primary: white; + --theme-border: #ddd; +} \ No newline at end of file diff --git a/packages/uikit-workshop/src/sass/scss/03-vendor/_prism.scss b/packages/uikit-workshop/src/sass/scss/03-vendor/_prism.scss index 6ab0ba455..bdada7401 100644 --- a/packages/uikit-workshop/src/sass/scss/03-vendor/_prism.scss +++ b/packages/uikit-workshop/src/sass/scss/03-vendor/_prism.scss @@ -5,180 +5,208 @@ * @author Lea Verou */ -code[class*='language-'], -pre[class*='language-'] { - color: black; - text-shadow: 0 1px white; - font-family: Consolas, Monaco, 'Andale Mono', monospace; - direction: ltr; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - line-height: 1.5; - word-wrap: normal; // fixes issue in Safari where code blocks can't scroll due to the code breaking into multiple lines unexpectedly - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; -} - -pre[class*='language-']::-moz-selection, -pre[class*='language-'] ::-moz-selection, -code[class*='language-']::-moz-selection, -code[class*='language-'] ::-moz-selection { - text-shadow: none; - background-color: #b3d4fc; -} - -pre[class*='language-']::selection, -pre[class*='language-'] ::selection, -code[class*='language-']::selection, -code[class*='language-'] ::selection { - text-shadow: none; - background-color: #b3d4fc; -} + // @todo: remove scoped selector when these are rendering via component-specific styles (ex. https://boltdesignsystem.com/pattern-lab/patterns/02-components-code-snippet/index.html) +.pl-c-tabs__panel { + pre[class*='language-'] { + background-image: linear-gradient( + to right, + $pl-color-white, + rgba($pl-color-white, 0) + ), + linear-gradient(to left, $pl-color-white, rgba($pl-color-white, 0)), + linear-gradient(to right, #eaf0f6, rgba($pl-color-gray-07, 0)), + linear-gradient(to left, #eaf0f6, rgba($pl-color-gray-07, 0)), + linear-gradient(to bottom, $pl-color-white, rgba($pl-color-white, 0)), + linear-gradient(to top, $pl-color-white, rgba($pl-color-white, 0)), + linear-gradient(to bottom, #eaf0f6, rgba($pl-color-gray-07, 0)), + linear-gradient(to top, #eaf0f6, rgba($pl-color-gray-07, 0)); + background-color: $pl-color-white; + background-attachment: local, local, scroll, scroll, local, local, scroll, + scroll; + background-position: 0 0, 100% 0, 0 0, 100% 0, 0 0, 0 100%, 0 0, 0 100%; + background-size: 4em 100%, 4em 100%, 1em 100%, 1em 100%, 100% 4em, 100% 4em, + 100% 1em, 100% 1em; + background-repeat: no-repeat; + -ms-overflow-style: -ms-autohiding-scrollbar; + -webkit-overflow-scrolling: touch; + overflow: auto; + } -@media print { code[class*='language-'], pre[class*='language-'] { + color: black; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + line-height: 1.5; + word-wrap: normal; // fixes issue in Safari where code blocks can't scroll due to the code breaking into multiple lines unexpectedly + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; + } + + pre[class*='language-']::-moz-selection, + pre[class*='language-'] ::-moz-selection, + code[class*='language-']::-moz-selection, + code[class*='language-'] ::-moz-selection { text-shadow: none; + background-color: #b3d4fc; } -} -/* Code blocks */ -pre[class*='language-'] { - padding: 1em; - margin: 0.5em 0; - overflow: auto; -} + pre[class*='language-']::selection, + pre[class*='language-'] ::selection, + code[class*='language-']::selection, + code[class*='language-'] ::selection { + text-shadow: none; + background-color: #b3d4fc; + } -:not(pre) > code[class*='language-'], -pre[class*='language-'] { - background-color: #f5f2f0; -} + @media print { + code[class*='language-'], + pre[class*='language-'] { + text-shadow: none; + } + } -/* Inline code */ -:not(pre) > code[class*='language-'] { - padding: 0.1em; - border-radius: 0.3em; -} + /* Code blocks */ + pre[class*='language-'] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + } -.token.comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: slategray; -} + :not(pre) > code[class*='language-'], + pre[class*='language-'] { + background-color: #f5f2f0; + } -.token.punctuation { - color: #999; -} + /* Inline code */ + :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; + } -.namespace { - opacity: 0.7; -} + .token.comment, + .token.prolog, + .token.doctype, + .token.cdata { + color: slategray; + } -.token.property, -.token.tag, -.token.boolean, -.token.number, -.token.constant, -.token.symbol, -.token.deleted { - color: #905; -} + .token.punctuation { + color: #999; + } -.token.selector, -.token.attr-name, -.token.string, -.token.char, -.token.builtin, -.token.inserted { - color: #690; -} + .namespace { + opacity: 0.7; + } -.token.operator, -.token.entity, -.token.url, -.language-css .token.string, -.style .token.string { - color: #a67f59; - background-color: hsla(0, 0%, 100%, 0.5); -} + .token.property, + .token.tag, + .token.boolean, + .token.number, + .token.constant, + .token.symbol, + .token.deleted { + color: #905; + } -.token.atrule, -.token.attr-value, -.token.keyword { - color: #07a; -} + .token.selector, + .token.attr-name, + .token.string, + .token.char, + .token.builtin, + .token.inserted { + color: #690; + } -.token.function { - color: #dd4a68; -} + .token.operator, + .token.entity, + .token.url, + .language-css .token.string, + .style .token.string { + color: #a67f59; + background-color: hsla(0, 0%, 100%, 0.5); + } -.token.regex, -.token.important, -.token.variable { - color: #e90; -} + .token.atrule, + .token.attr-value, + .token.keyword { + color: #07a; + } -.token.important, -.token.bold { - font-weight: bold; -} -.token.italic { - font-style: italic; -} + .token.function { + color: #dd4a68; + } -.token.entity { - cursor: help; -} + .token.regex, + .token.important, + .token.variable { + color: #e90; + } -pre.line-numbers { - position: relative; - padding-left: 3.8em; - counter-reset: linenumber; -} + .token.important, + .token.bold { + font-weight: bold; + } + .token.italic { + font-style: italic; + } -pre.line-numbers > code { - position: relative; -} + .token.entity { + cursor: help; + } -.line-numbers .line-numbers-rows { - position: absolute; - pointer-events: none; - top: 0; - font-size: 100%; - left: -3.8em; - width: 3em; /* works for line-numbers below 1000 lines */ - letter-spacing: -1px; - border-right: 1px solid #999; - - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} + pre.line-numbers { + position: relative; + padding-left: 3.8em; + counter-reset: linenumber; + } -.line-numbers-rows > span { - pointer-events: none; - display: block; - counter-increment: linenumber; -} + pre.line-numbers > code { + position: relative; + } -.line-numbers-rows > span:before { - content: counter(linenumber); - color: #999; - display: block; - padding-right: 0.8em; - text-align: right; -} -.token a { - color: inherit; + .line-numbers .line-numbers-rows { + position: absolute; + pointer-events: none; + top: 0; + font-size: 100%; + left: -3.8em; + width: 3em; /* works for line-numbers below 1000 lines */ + letter-spacing: -1px; + border-right: 1px solid #999; + + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + + .line-numbers-rows > span { + pointer-events: none; + display: block; + counter-increment: linenumber; + } + + .line-numbers-rows > span:before { + content: counter(linenumber); + color: #999; + display: block; + padding-right: 0.8em; + text-align: right; + } + .token a { + color: inherit; + } } diff --git a/packages/uikit-workshop/src/sass/scss/04-components/_header.scss b/packages/uikit-workshop/src/sass/scss/04-components/_header.scss index 2616b678f..19295a5ff 100644 --- a/packages/uikit-workshop/src/sass/scss/04-components/_header.scss +++ b/packages/uikit-workshop/src/sass/scss/04-components/_header.scss @@ -20,7 +20,6 @@ color: $pl-color-gray-50; font-family: $pl-font; font-size: $pl-font-size-sm; - min-height: 30px; // magic number -- needed for initial skeleton screen styles used in the critical CSS @supports(padding: max(0px)) { padding-left: env(safe-area-inset-left); diff --git a/packages/uikit-workshop/src/sass/scss/04-components/_pattern-info.scss b/packages/uikit-workshop/src/sass/scss/04-components/_pattern-info.scss index 606ad8055..6849402cf 100644 --- a/packages/uikit-workshop/src/sass/scss/04-components/_pattern-info.scss +++ b/packages/uikit-workshop/src/sass/scss/04-components/_pattern-info.scss @@ -9,12 +9,10 @@ */ .pl-c-pattern-info { flex-grow: 1; // fills space available when placed in the parent flex container - display: flex; - flex-direction: row; - flex-flow: row wrap; - width: 100%; - overflow: auto; - -webkit-overflow-scrolling: touch; + + @media all and (min-width: $pl-bp-large) { + display: flex; + } /** * Pattern info inside the "view all" template @@ -33,6 +31,30 @@ overflow: visible; } } + + /** + * Pattern info inside modal + */ + .pl-c-drawer & { + position: absolute; + top: 0; + right: 0.8rem; + bottom: 0; + left: 0; + overflow: scroll; + @include hideScrollBar(); + -webkit-overflow-scrolling: touch; + flex-grow: 1; + + @supports (padding: env(safe-area-inset-right)){ + right: calc(env(safe-area-inset-right) + 0.8rem); + } + + @media all and (min-width: $pl-bp-large) { + position: static; + overflow: visible; + } + } } /** @@ -41,19 +63,65 @@ * Right side contains pattern code */ .pl-c-pattern-info__panel { - flex-basis: 40%; // fills up 100% if only one panel exists. using 40% vs 50% due to quirky behavior in IE 11 - padding-top: 1rem; - padding-right: 1rem; - padding-bottom: 0; - padding-left: 1rem; - margin-bottom: 1rem; - flex-grow: 1; - max-width: 100%; - min-width: 300px; // so panels stack automatically - display: inline-flex; - flex-direction: column; - overflow: auto; - -webkit-overflow-scrolling: touch; + padding: 1rem; + width: 100%; + + @media all and (min-width: $pl-bp-large) { + flex: auto; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + } + + .pl-c-drawer & { + padding-right: 1.3rem; + + @supports (padding: env(safe-area-inset-right)){ + padding-right: calc(env(safe-area-inset-right) + 1.3rem); + } + } +} + +/** + * Pattern Info Panel + * 1) Left panel that contains pattern title, lineage, description, annotations + */ +.pl-c-pattern-info__panel--info { + padding-top: 2rem; + + @media all and (min-width: $pl-bp-large) { + left: 0; + right: 50%; + overflow: auto; + @include hideScrollBar(); + -webkit-overflow-scrolling: touch; + } + + @media all and (min-width: $pl-bp-xl) { + right: 55%; + } +} + +/** + * Pattern Code Panel + * 1) Right panel that displays the pattern's code (found in _tabs.scss) + * 2) Using a sibling selector because the pattern info isn't always present. + * The sibling selector allows the code panel to occupy the full width of + * the modal + * 1) Cap the height of the code panel in the modal + */ +.pl-c-pattern-info__panel--info + .pl-c-pattern-info__panel--code { + @media all and (min-width: $pl-bp-large) { + right: 0; + left: 50%; + top: 1.2rem; + } + + @media all and (min-width: $pl-bp-xl) { + left: 45%; + } } /** diff --git a/packages/uikit-workshop/src/sass/scss/04-components/_tabs.scss b/packages/uikit-workshop/src/sass/scss/04-components/_tabs.scss index d1458283f..548397b52 100644 --- a/packages/uikit-workshop/src/sass/scss/04-components/_tabs.scss +++ b/packages/uikit-workshop/src/sass/scss/04-components/_tabs.scss @@ -18,6 +18,42 @@ flex-direction: column; overflow: hidden; flex-grow: 1; + + /** + * Tabs inside a code panel + */ + + .pl-c-pattern-info__panel--code & { + position: absolute; + top: 1rem; + bottom: 1rem; + left: 1rem; + right: 1rem; + } + + .pl-c-drawer & { + // adjusts the absolutely positioned tabs container when nested inside the PL drawer + // @todo: refactor to eliminate the need for this + @media all and (min-width: $pl-bp-med) { + right: 1.5rem; + + @supports(padding: unquote('max(0px, env(safe-area-inset-right))')) { + right: unquote('max(1.5rem, env(safe-area-inset-right))'); + } + } + + @media all and (min-width: 848px) { + right: 2.3rem; + + @supports(padding: unquote('max(0px, env(safe-area-inset-right))')) { + right: unquote('max(2.3rem, calc(env(safe-area-inset-right) + 1.4rem))'); + } + } + + @media all and (min-width: $pl-bp-xl) { + left: 2rem; + } + } } /** @@ -70,9 +106,19 @@ * 1) Tab content contains the tab panels */ .pl-c-tabs__content { - overflow: auto; + flex-grow: 1; + flex-shrink: 1; + flex-basis: 0; + overflow: hidden; -webkit-overflow-scrolling: touch; - padding-top: 0.5rem; + height: 100%; + + /** + * Tab content inside modal + */ + .pl-c-drawer & { + border: 0; + } } /** @@ -82,10 +128,12 @@ */ .pl-c-tabs__panel { display: none; - // min-height: 12rem; + min-height: 12rem; + height: 100%; &.pl-is-active-tab { display: block; + display: flex; } /** @@ -100,6 +148,7 @@ padding: 0; border: 0; display: block; + width: 100%; } code[class*='language-'] { diff --git a/packages/uikit-workshop/src/sass/scss/05-themes/_light-theme.scss b/packages/uikit-workshop/src/sass/scss/05-themes/_light-theme.scss index 038ae4390..0cca86f93 100644 --- a/packages/uikit-workshop/src/sass/scss/05-themes/_light-theme.scss +++ b/packages/uikit-workshop/src/sass/scss/05-themes/_light-theme.scss @@ -38,11 +38,10 @@ * Nav link dropdown */ .pl-c-nav__link--dropdown { - color: $pl-color-gray-70; - background-color: $pl-color-white; + color: inherit; &:after { - color: $pl-color-gray-20; + color: inherit; } } @@ -104,7 +103,7 @@ /** * Modal inside a light theme */ - .pl-c-modal { + .pl-c-drawer { background-color: $pl-color-white; color: $pl-color-gray-70; border-top: 1px solid $pl-color-gray-20; @@ -114,7 +113,7 @@ * Modal close button * 1) Closes the modal popup */ - .pl-c-modal__close-btn, + .pl-c-drawer__close-btn, .pl-c-tools__action { background-color: $pl-color-white; diff --git a/packages/uikit-workshop/src/sass/scss/05-themes/_sidebar-theme.scss b/packages/uikit-workshop/src/sass/scss/05-themes/_sidebar-theme.scss index c271ad06a..fe80035a5 100644 --- a/packages/uikit-workshop/src/sass/scss/05-themes/_sidebar-theme.scss +++ b/packages/uikit-workshop/src/sass/scss/05-themes/_sidebar-theme.scss @@ -19,35 +19,16 @@ height: 100vh; /* 2 */ flex-direction: column; /* 3 */ border-bottom: 0; /* 4 */ - padding: 1rem; - overflow: auto; - -webkit-overflow-scrolling: touch; justify-content: space-between; } - /** - * Header within light theme - */ - &.pl-c-body--theme-light { - .pl-c-header { - border-right: 1px solid $pl-color-gray-20; - } - } - - /** - * Logo - */ - .pl-c-logo { - max-width: 7rem; - margin: 0 auto 1rem; - } - /** * Nav sub sub list */ .pl-c-nav { - display: block; + flex-grow: 1; flex-direction: column; + flex-flow: column-reverse; } /** @@ -68,43 +49,6 @@ border-radius: 0; } - /** - * Nav sublist - */ - .pl-c-nav__sublist .pl-c-nav__link { - padding-left: 1rem; - } - - /** - * Nav sublist - */ - .pl-c-nav__sublist--dropdown.pl-is-active { - border: 0; - border-left: 1px solid $pl-color-gray-70; - } - - /** - * Nav sublist inside the light theme - */ - &.pl-c-body--theme-light { - .pl-c-nav__sublist--dropdown.pl-is-active { - border-left-color: $pl-color-gray-07; - } - } - - /** - * Dropdown sublist - * 1) Undo fixed height - */ - - /** - * Nav sub sub list - */ - .pl-c-nav__subsublist { - border-left: 1px solid $pl-color-gray-70; - margin-left: 1rem; - } - /** * Nav sublist inside the light theme */ @@ -145,10 +89,6 @@ margin-left: 0; } - .pl-c-viewport-size { - display: none; - } - /** * Tools toggle button */ @@ -175,7 +115,7 @@ * so it fits in remaining available space * TODO: revisit to find ways to resize */ - .pl-c-modal { + .pl-c-drawer { right: 0; /* 1 */ width: auto; } diff --git a/packages/uikit-workshop/src/scripts/actions/app.js b/packages/uikit-workshop/src/scripts/actions/app.js old mode 100644 new mode 100755 index fa453303a..2b2f9813c --- a/packages/uikit-workshop/src/scripts/actions/app.js +++ b/packages/uikit-workshop/src/scripts/actions/app.js @@ -1,5 +1,31 @@ export const UPDATE_THEME_MODE = 'UPDATE_THEME_MODE'; export const UPDATE_LAYOUT_MODE = 'UPDATE_LAYOUT_MODE'; +export const UPDATE_DRAWER_ANIMATION_STATE = 'UPDATE_DRAWER_ANIMATION_STATE'; +export const UPDATE_DRAWER_STATE = 'UPDATE_DRAWER_STATE'; +export const UPDATE_VIEWPORT_PX = 'UPDATE_VIEWPORT_PX'; +export const UPDATE_VIEWPORT_EM = 'UPDATE_VIEWPORT_EM'; +export const UPDATE_DRAWER_HEIGHT = 'UPDATE_DRAWER_HEIGHT'; +export const UPDATE_CURRENT_URL = 'UPDATE_CURRENT_URL'; +export const UPDATE_CURRENT_PATTERN = 'UPDATE_CURRENT_PATTERN'; +export const IS_VIEWALL_PAGE = 'IS_VIEWALL_PAGE'; + +export const updateCurrentPattern = currentPattern => (dispatch, getState) => { + if (getState().app.currentPattern !== currentPattern) { + dispatch({ + type: UPDATE_CURRENT_PATTERN, + currentPattern, + }); + } +}; + +export const updateCurrentUrl = currentUrl => (dispatch, getState) => { + if (getState().app.currentUrl !== currentUrl) { + dispatch({ + type: UPDATE_CURRENT_URL, + currentUrl, + }); + } +}; export const updateLayoutMode = layoutMode => (dispatch, getState) => { if (getState().app.layoutMode !== layoutMode) { @@ -10,6 +36,24 @@ export const updateLayoutMode = layoutMode => (dispatch, getState) => { } }; +export const updateViewportPx = viewportPx => (dispatch, getState) => { + if (getState().app.viewportPx !== viewportPx) { + dispatch({ + type: UPDATE_VIEWPORT_PX, + viewportPx, + }); + } +}; + +export const updateViewportEm = viewportEm => (dispatch, getState) => { + if (getState().app.viewportEm !== viewportEm) { + dispatch({ + type: UPDATE_VIEWPORT_EM, + viewportEm, + }); + } +}; + export const updateThemeMode = themeMode => (dispatch, getState) => { if (getState().app.themeMode !== themeMode) { dispatch({ @@ -18,3 +62,42 @@ export const updateThemeMode = themeMode => (dispatch, getState) => { }); } }; + +export const updateDrawerState = opened => (dispatch, getState) => { + if (getState().app.drawerOpened !== opened) { + dispatch({ + type: UPDATE_DRAWER_STATE, + opened, + }); + } +}; + +export const updateDrawerAnimationState = drawerIsAnimating => ( + dispatch, + getState +) => { + if (getState().app.drawerIsAnimating !== drawerIsAnimating) { + dispatch({ + type: UPDATE_DRAWER_ANIMATION_STATE, + drawerIsAnimating, + }); + } +}; + +export const updateDrawerHeight = height => (dispatch, getState) => { + if (getState().app.drawerHeight !== height) { + dispatch({ + type: UPDATE_DRAWER_HEIGHT, + height, + }); + } +}; + +export const isViewallPage = isViewall => (dispatch, getState) => { + if (getState().app.isViewallPage !== isViewall) { + dispatch({ + type: IS_VIEWALL_PAGE, + isViewall, + }); + } +}; diff --git a/packages/uikit-workshop/src/scripts/components/base-component.js b/packages/uikit-workshop/src/scripts/components/base-component.js old mode 100644 new mode 100755 index 1e1594993..172a12197 --- a/packages/uikit-workshop/src/scripts/components/base-component.js +++ b/packages/uikit-workshop/src/scripts/components/base-component.js @@ -3,18 +3,21 @@ import withPreact from '@skatejs/renderer-preact'; import { store } from '../store.js'; import { extend, supportsShadowDom } from '../utils/index.js'; import { h } from 'preact'; +import withLitHtml from '@skatejs/renderer-lit-html'; export class BaseComponent extends withComponent(withPreact()) { get renderRoot() { - if (this.useShadow === true && supportsShadowDom) { - return super.renderRoot || shadow(this); - } else { - return this; - } + return this; + // @todo: re-enable Shadow DOM conditionally after further testing + making sure PL components have inline styles needed + // if (this.useShadow === true && supportsShadowDom) { + // return super.renderRoot || shadow(this); + // } else { + // return this; + // } } disconnectedCallback() { - this.__storeUnsubscribe(); + this.__storeUnsubscribe && this.__storeUnsubscribe(); if (super.disconnectedCallback) { super.disconnectedCallback(); @@ -32,7 +35,8 @@ export class BaseComponent extends withComponent(withPreact()) { } _stateChanged(state) { - throw new Error('_stateChanged() not implemented', this); + // throw new Error('_stateChanged() not implemented', this); + this.triggerUpdate(); } /** @@ -44,20 +48,7 @@ export class BaseComponent extends withComponent(withPreact()) { * updated */ setState(state, callback) { - if (!this._prevState) { - this._prevState = this.state; - } - - this.state = extend( - extend({}, this.state), - typeof state === 'function' ? state(this.state, this.props) : state - ); - - if (callback) { - this._renderCallbacks.push(callback); - } - - this.triggerUpdate(); + this.state = Object.assign({}, this.state, state); } _renderStyles(stylesheets) { @@ -71,3 +62,43 @@ export class BaseComponent extends withComponent(withPreact()) { } } } + +export class BaseLitComponent extends withComponent(withLitHtml()) { + get renderRoot() { + return this; + } + + disconnectedCallback() { + this.__storeUnsubscribe(); + + if (super.disconnectedCallback) { + super.disconnectedCallback(); + } + } + + connectedCallback() { + this.__storeUnsubscribe = store.subscribe(() => + this._stateChanged(store.getState()) + ); + this._stateChanged(store.getState()); + if (super.connectedCallback) { + super.connectedCallback(); + } + } + + _stateChanged(state) { + this.triggerUpdate(); + } + + /** + * Update component state and schedule a re-render. + * @param {object} state A dict of state properties to be shallowly merged + * into the current state, or a function that will produce such a dict. The + * function is called with the current state and props. + * @param {() => void} callback A function to be called once component state is + * updated + */ + setState(state, callback) { + this.state = Object.assign({}, this.state, state); + } +} diff --git a/packages/uikit-workshop/src/scripts/components/modal-styleguide.js b/packages/uikit-workshop/src/scripts/components/modal-styleguide.js old mode 100644 new mode 100755 index a7a8e8254..7c31a3eba --- a/packages/uikit-workshop/src/scripts/components/modal-styleguide.js +++ b/packages/uikit-workshop/src/scripts/components/modal-styleguide.js @@ -3,7 +3,7 @@ */ import { panelsUtil } from './panels-util'; -import './copy-to-clipboard'; +import './pl-copy-to-clipboard/pl-copy-to-clipboard'; export const modalStyleguide = { // set up some defaults diff --git a/packages/uikit-workshop/src/scripts/components/modal-viewer.js b/packages/uikit-workshop/src/scripts/components/modal-viewer.js index c099711c8..f639b9426 100644 --- a/packages/uikit-workshop/src/scripts/components/modal-viewer.js +++ b/packages/uikit-workshop/src/scripts/components/modal-viewer.js @@ -2,12 +2,17 @@ * "Modal" (aka Panel UI) for the Viewer Layer - for both annotations and code/info */ -import $ from 'jquery'; -import { urlHandler, DataSaver, Dispatcher } from '../utils'; +import { scrollTo } from 'scroll-js'; +import { urlHandler, Dispatcher } from '../utils'; import { panelsViewer } from './panels-viewer'; +import { store } from '../store.js'; +// These are the actions needed by this element. +import { updateDrawerState, isViewallPage } from '../actions/app.js'; export const modalViewer = { // set up some defaults + delayCheckingModalViewer: false, + iframeElement: document.querySelector('.pl-js-iframe'), active: false, switchText: true, template: 'info', @@ -21,54 +26,27 @@ export const modalViewer = { * initialize the modal window */ onReady() { + window.addEventListener('message', modalViewer.receiveIframeMessage, false); // make sure the listener for checkpanels is set-up Dispatcher.addListener('insertPanels', modalViewer.insert); - // add the info/code panel onclick handler - $('.pl-js-pattern-info-toggle').click(function(e) { - modalViewer.toggle(); - }); - - // make sure the close button handles the click - $('.pl-js-modal-close-btn').on('click', function(e) { - // hide any open annotations - const obj = JSON.stringify({ - event: 'patternLab.annotationsHighlightHide', - }); - document - .querySelector('.pl-js-iframe') - .contentWindow.postMessage(obj, modalViewer.targetOrigin); + modalViewer.__storeUnsubscribe = store.subscribe(() => + modalViewer._stateChanged(store.getState()) + ); + modalViewer._stateChanged(store.getState()); - // hide the viewer - modalViewer.close(); - }); - - // see if the modal is already active, if so update attributes as appropriate - if (DataSaver.findValue('modalActive') === 'true') { - modalViewer.active = true; - $('.pl-js-pattern-info-toggle').html('Hide Pattern Info'); - } - - // make sure the modal viewer is not viewable, it's always hidden by default. the pageLoad event determines when it actually opens - modalViewer.hide(); - - // review the query strings in case there is something the modal viewer is supposed to handle by default + // check query strings to handle auto-opening behavior const queryStringVars = urlHandler.getRequestVars(); // show the modal if code view is called via query string if ( queryStringVars.view !== undefined && - (queryStringVars.view === 'code' || queryStringVars.view === 'c') + (queryStringVars.view === 'code' || + queryStringVars.view === 'c' || + queryStringVars.view === 'annotations' || + queryStringVars.view === 'a') ) { - modalViewer.queryPattern(); - } - - // show the modal if the old annotations view is called via query string - if ( - queryStringVars.view !== undefined && - (queryStringVars.view === 'annotations' || queryStringVars.view === 'a') - ) { - modalViewer.queryPattern(); + store.dispatch(updateDrawerState(true)); } }, @@ -76,16 +54,10 @@ export const modalViewer = { * toggle the modal window open and closed */ toggle() { - if (modalViewer.active === false) { - modalViewer.queryPattern(); + if (modalViewer.active) { + store.dispatch(updateDrawerState(false)); } else { - const obj = JSON.stringify({ - event: 'patternLab.annotationsHighlightHide', - }); - document - .querySelector('.pl-js-iframe') - .contentWindow.postMessage(obj, modalViewer.targetOrigin); - modalViewer.close(); + store.dispatch(updateDrawerState(true)); } }, @@ -93,50 +65,70 @@ export const modalViewer = { * open the modal window */ open() { - // make sure the modal viewer and other options are off just in case - modalViewer.close(); - - // note it's turned on in the viewer - DataSaver.updateValue('modalActive', 'true'); - modalViewer.active = true; + modalViewer.queryPattern(); - // show the modal - modalViewer.show(); + // Show annotations if data is available and modal is open + if (modalViewer.patternData) { + if ( + modalViewer.patternData.annotations && + modalViewer.patternData.annotations.length > 0 + ) { + const obj = JSON.stringify({ + event: 'patternLab.annotationsHighlightShow', + annotations: modalViewer.patternData.annotations, + }); + + if (modalViewer.iframeElement.contentWindow) { + modalViewer.iframeElement.contentWindow.postMessage( + obj, + modalViewer.targetOrigin + ); + } else { + modalViewer.iframeElement = document.querySelector('.pl-js-iframe'); + + if (modalViewer.iframeElement.contentWindow) { + modalViewer.open(); + } else { + console.log('modelViewer open cannot find the iframeElement...'); + } + } + } + } }, /** * close the modal window */ close() { - // note that the modal viewer is no longer active - DataSaver.updateValue('modalActive', 'false'); - modalViewer.active = false; - - //Remove active class to modal - $('.pl-js-modal').removeClass('pl-is-active'); - $('.pl-js-modal').removeAttr('style'); // remove inline height CSS - - // WIP: refactoring viewport panel to use CSS vars to resize - // $('html').css('--pl-viewport-height', window.innerHeight - 32 + 'px'); - - // update the wording - $('.pl-js-pattern-info-toggle').html('Show Pattern Info'); - // tell the styleguide to close const obj = JSON.stringify({ event: 'patternLab.patternModalClose', }); - document - .querySelector('.pl-js-iframe') - .contentWindow.postMessage(obj, modalViewer.targetOrigin); - }, - /** - * hide the modal window - */ - hide() { - $('.pl-js-modal').removeClass('pl-is-active'); - $('.pl-js-modal').removeAttr('style'); // remove inline height CSS + if (modalViewer.iframeElement) { + if (modalViewer.iframeElement.contentWindow) { + modalViewer.iframeElement.contentWindow.postMessage( + obj, + modalViewer.targetOrigin + ); + + const obj2 = JSON.stringify({ + event: 'patternLab.annotationsHighlightHide', + }); + modalViewer.iframeElement.contentWindow.postMessage( + obj2, + modalViewer.targetOrigin + ); + } else { + modalViewer.iframeElement = document.querySelector('.pl-js-iframe'); + + if (modalViewer.iframeElement.contentWindow) { + modalViewer.close(); + } else { + console.log('modelViewer close cannot find the iframeElement...'); + } + } + } }, /** @@ -154,18 +146,29 @@ export const modalViewer = { patternPartial, modalContent: templateRendered.outerHTML, }); - document - .querySelector('.pl-js-iframe') - .contentWindow.postMessage(obj, modalViewer.targetOrigin); + if (modalViewer.iframeElement.contentWindow) { + modalViewer.iframeElement.contentWindow.postMessage( + obj, + modalViewer.targetOrigin + ); + } else { + modalViewer.iframeElement = document.querySelector('.pl-js-iframe'); + + if (modalViewer.iframeElement.contentWindow) { + modalViewer.insert(templateRendered, patternPartial, iframePassback); + } else { + console.log('modelViewer insert cannot find the iframeElement...'); + } + } } else { - // insert the panels and open the viewer - $('.pl-js-modal-content').html(templateRendered); - modalViewer.open(); - } + const contentContainer = document.querySelector('.pl-js-drawer-content'); - // update the wording unless this is a default viewall opening - if (switchText === true) { - $('.pl-js-pattern-info-toggle').html('Hide Pattern Info'); + // Clear out any existing children before appending the new panel content + if (contentContainer.firstChild !== null) { + contentContainer.removeChild(contentContainer.firstChild); + } + + contentContainer.appendChild(templateRendered); } }, @@ -178,9 +181,11 @@ export const modalViewer = { refresh(patternData, iframePassback, switchText) { // if this is a styleguide view close the modal if (iframePassback) { - modalViewer.hide(); + modalViewer.close(); } + modalViewer.patternData = patternData; + // gather the data that will fill the modal window panelsViewer.gatherPanels(patternData, iframePassback, switchText); }, @@ -190,7 +195,7 @@ export const modalViewer = { * @param {Integer} where the modal window should be slide to */ slide(pos) { - $('.pl-js-modal').toggleClass('pl-is-active'); + modalViewer.toggle(); }, /** @@ -204,47 +209,62 @@ export const modalViewer = { els[i].classList.remove('pl-is-active'); } + const patternInfoElem = document.querySelector('.pl-js-pattern-info'); + // const scroll = new Scroll(patternInfoElem); + // add active class to called element and scroll to it for (let i = 0; i < els.length; ++i) { if (i + 1 === pos) { els[i].classList.add('pl-is-active'); - $('.pl-js-pattern-info').animate( - { - scrollTop: els[i].offsetTop - 10, - }, - 600 - ); + + scrollTo(patternInfoElem, document.body, { + top: els[i].offsetTop - 14, + behavior: 'smooth', + }).then(function() { + // console.log('finished scrolling'); + }); } } }, - /** - * Show modal - */ - show() { - $('.pl-js-modal').addClass('pl-is-active'); - }, - /** * ask the pattern for info so we can open the modal window and populate it * @param {Boolean} if the dropdown text should be changed */ queryPattern(switchText) { - // note that the modal is active and set switchText - if (switchText === undefined || switchText) { - switchText = true; - DataSaver.updateValue('modalActive', 'true'); - modalViewer.active = true; - } - // send a message to the pattern const obj = JSON.stringify({ event: 'patternLab.patternQuery', switchText, }); - document - .querySelector('.pl-js-iframe') - .contentWindow.postMessage(obj, modalViewer.targetOrigin); + + // only emit this when the iframe element exists. + // @todo: refactor to better handle async UI rendering + if (modalViewer.iframeElement) { + if (modalViewer.iframeElement.contentWindow) { + modalViewer.iframeElement.contentWindow.postMessage( + obj, + modalViewer.targetOrigin + ); + } else { + modalViewer.iframeElement = document.querySelector('.pl-js-iframe'); + + if (modalViewer.iframeElement.contentWindow) { + modalViewer.queryPattern(switchText); + } else { + console.log('queryPattern cannot find the iframeElement...'); + } + } + } else { + modalViewer.iframeElement = document.querySelector('.pl-js-iframe'); + + if (modalViewer.iframeElement.contentWindow) { + modalViewer.iframeElement.contentWindow.postMessage( + obj, + modalViewer.targetOrigin + ); + } + } }, /** @@ -271,6 +291,21 @@ export const modalViewer = { } if (data.event !== undefined && data.event === 'patternLab.pageLoad') { + // @todo: refactor to better handle async iframe loading + // extra check to make sure the PL drawer will always render even if the iframe gets async loaded / rendered. + if (modalViewer.delayCheckingModalViewer) { + modalViewer._handleInitialModalViewerState(); + } + + if ( + data.patternpartial.indexOf('viewall-') === 0 || + data.patternpartial.indexOf('all') === 0 + ) { + store.dispatch(isViewallPage(true)); + } else { + store.dispatch(isViewallPage(false)); + } + if ( modalViewer.active === false && data.patternpartial !== undefined && @@ -286,12 +321,21 @@ export const modalViewer = { data.event !== undefined && data.event === 'patternLab.patternQueryInfo' ) { - // refresh the modal if a new pattern is loaded and the modal is active - modalViewer.refresh( - data.patternData, - data.iframePassback, - data.switchText - ); + if ( + !modalViewer.panelRendered || + modalViewer.previouslyRenderedPattern !== + data.patternData.patternPartial + ) { + // refresh the modal contents, but only when necessary (ex. when the page changes) -- prevents extra, unnecessary re-renders of content. + modalViewer.refresh( + data.patternData, + data.iframePassback, + data.switchText + ); + + modalViewer.panelRendered = true; + modalViewer.previouslyRenderedPattern = data.patternData.patternPartial; + } } else if ( data.event !== undefined && data.event === 'patternLab.annotationNumberClicked' @@ -300,11 +344,33 @@ export const modalViewer = { modalViewer.slideToAnnotation(data.displayNumber); } }, -}; -// when the document is ready make sure the modal is ready -$(document).ready(function() { - modalViewer.onReady(); -}); + _handleInitialModalViewerState() { + // try to re-locate the iframe element if this UI logic ran too early and the iframe component wasn't yet rendered + if (!modalViewer.iframeElement) { + modalViewer.iframeElement = document.querySelector('.pl-js-iframe'); + } + + // only try to auto-open / auto-close the drawer UI if the iframe element exists + // @todo: refactor to better handle async UI rendering + if (modalViewer.iframeElement) { + modalViewer.delayCheckingModalViewer = false; + if (modalViewer.active) { + modalViewer.open(); + } else { + modalViewer.close(); + } + } else { + modalViewer.delayCheckingModalViewer = true; + } + }, + + _stateChanged(state) { + modalViewer.active = state.app.drawerOpened; + if (modalViewer.iframeElement) { + modalViewer._handleInitialModalViewerState(); + } + }, +}; -window.addEventListener('message', modalViewer.receiveIframeMessage, false); +modalViewer.onReady(); diff --git a/packages/uikit-workshop/src/scripts/components/panels-viewer.js b/packages/uikit-workshop/src/scripts/components/panels-viewer.js old mode 100644 new mode 100755 index 273d17a5c..bad2d0968 --- a/packages/uikit-workshop/src/scripts/components/panels-viewer.js +++ b/packages/uikit-workshop/src/scripts/components/panels-viewer.js @@ -2,13 +2,22 @@ * Panel Builder - supports building the panels to be included in the modal or styleguide */ -import $ from 'jquery'; import Hogan from 'hogan.js'; import Prism from 'prismjs'; +import Normalizer from 'prismjs/plugins/normalize-whitespace/prism-normalize-whitespace.js'; import { Panels } from './panels'; import { panelsUtil } from './panels-util'; import { urlHandler, Dispatcher } from '../utils'; -import './copy-to-clipboard'; +import './pl-copy-to-clipboard/pl-copy-to-clipboard'; + +const normalizeWhitespace = new Normalizer({ + 'remove-trailing': true, + 'remove-indent': true, + 'left-trim': true, + 'right-trim': true, + 'break-lines': 80, + 'tabs-to-spaces': 2, +}); export const panelsViewer = { // set up some defaults @@ -88,8 +97,11 @@ export const panelsViewer = { /* eslint-disable */ e.onload = (function(i, panels, patternData, iframeRequest) { return function() { + let normalizedCode = normalizeWhitespace.normalize( + this.responseText + ); const prismedContent = Prism.highlight( - this.responseText, + normalizedCode, Prism.languages.html ); template = document.getElementById(panels[i].templateID); @@ -98,6 +110,9 @@ export const panelsViewer = { language: 'html', code: prismedContent, }); + templateRendered = normalizeWhitespace.normalize( + templateRendered + ); panels[i].content = templateRendered; Dispatcher.trigger('checkPanels', [ panels, @@ -119,7 +134,15 @@ export const panelsViewer = { template = document.getElementById(panel.templateID); templateCompiled = Hogan.compile(template.innerHTML); templateRendered = templateCompiled.render(patternData); - panels[i].content = templateRendered; + const normalizedCode = normalizeWhitespace.normalize( + templateRendered + ); + normalizedCode.replace(/[\r\n]+/g, '\n\n'); + const highlightedCode = Prism.highlight( + normalizedCode, + Prism.languages.html + ); + panels[i].content = highlightedCode; Dispatcher.trigger('checkPanels', [ panels, patternData, @@ -274,16 +297,17 @@ export const panelsViewer = { } // find lineage links in the rendered content and add postmessage handlers in case it's in the modal - $('.pl-js-lineage-link', templateRendered).on('click', function(e) { - e.preventDefault(); - const obj = JSON.stringify({ - event: 'patternLab.updatePath', - path: urlHandler.getFileName($(this).attr('data-patternpartial')), - }); - document - .querySelector('.pl-js-iframe') - .contentWindow.postMessage(obj, panelsViewer.targetOrigin); - }); + // @todo: refactor and re-enable + // $('.pl-js-lineage-link', templateRendered).on('click', function(e) { + // e.preventDefault(); + // const obj = JSON.stringify({ + // event: 'patternLab.updatePath', + // path: urlHandler.getFileName($(this).attr('data-patternpartial')), + // }); + // document + // .querySelector('.pl-js-iframe') + // .contentWindow.postMessage(obj, panelsViewer.targetOrigin); + // }); // gather panels from plugins Dispatcher.trigger('insertPanels', [ @@ -307,19 +331,3 @@ export const panelsViewer = { * 5) Add mouseup event to the body so that when drag is released, the modal * stops resizing and modal cover doesn't display anymore. */ -$('.pl-js-modal-resizer').mousedown(function(event) { - /* 1 */ - - $('.pl-js-modal-cover').css('display', 'block'); /* 2 */ - - $('.pl-js-modal-cover').mousemove(function(e) { - /* 3 */ - const panelHeight = window.innerHeight - e.clientY + 32; /* 4 */ - $('.pl-js-modal').css('height', panelHeight + 'px'); /* 4 */ - }); -}); - -$('body').mouseup(function() { - $('.pl-js-modal').unbind('mousemove'); /* 5 */ - $('.pl-js-modal-cover').css('display', 'none'); /* 5 */ -}); diff --git a/packages/uikit-workshop/src/scripts/components/panels.js b/packages/uikit-workshop/src/scripts/components/panels.js index 1b37959aa..7eb44a1cd 100644 --- a/packages/uikit-workshop/src/scripts/components/panels.js +++ b/packages/uikit-workshop/src/scripts/components/panels.js @@ -15,7 +15,7 @@ export const Panels = { }, get() { - return JSON.parse(JSON.stringify(this.panels)); + return JSON.parse(JSON.stringify(Panels.panels)); }, add(panel) { @@ -46,45 +46,71 @@ export const Panels = { }, }; -const fileSuffixPattern = - window.config.outputFileSuffixes !== undefined && - window.config.outputFileSuffixes.rawTemplate !== undefined - ? window.config.outputFileSuffixes.rawTemplate - : ''; -const fileSuffixMarkup = - window.config.outputFileSuffixes !== undefined && - window.config.outputFileSuffixes.markupOnly !== undefined - ? window.config.outputFileSuffixes.markupOnly - : '.markup-only'; +function receiveIframeMessage(event) { + // does the origin sending the message match the current host? if not dev/null the request + if ( + (window.location.protocol !== 'file:' && + event.origin !== + window.location.protocol + '//' + window.location.host) || + event.data === '' // message received, but no data included; prevents JSON.parse error below + ) { + return; + } -// add the default panels -// Panels.add({ 'id': 'pl-panel-info', 'name': 'info', 'default': true, 'templateID': 'pl-panel-template-info', 'httpRequest': false, 'prismHighlight': false, 'keyCombo': '' }); -// TODO: sort out pl-panel-html -Panels.add({ - id: 'pl-panel-pattern', - name: window.config.patternExtension.toUpperCase(), - default: true, - templateID: 'pl-panel-template-code', - httpRequest: true, - httpRequestReplace: fileSuffixPattern, - httpRequestCompleted: false, - prismHighlight: true, - language: PrismLanguages.get(window.config.patternExtension), - keyCombo: 'ctrl+shift+u', -}); + let data = {}; + try { + data = typeof event.data !== 'string' ? event.data : JSON.parse(event.data); + } catch (e) { + // @todo: how do we want to handle exceptions here? + } -Panels.add({ - id: 'pl-panel-html', - name: 'HTML', - default: false, - templateID: 'pl-panel-template-code', - httpRequest: true, - httpRequestReplace: fileSuffixMarkup + '.html', - httpRequestCompleted: false, - prismHighlight: true, - language: 'markup', - keyCombo: 'ctrl+shift+y', -}); + if (data.event !== undefined) { + if (data.event === 'patternLab.pageLoad') { + const fileSuffixPattern = + window.config.outputFileSuffixes !== undefined && + window.config.outputFileSuffixes.rawTemplate !== undefined + ? window.config.outputFileSuffixes.rawTemplate + : ''; + + const fileSuffixMarkup = + window.config.outputFileSuffixes !== undefined && + window.config.outputFileSuffixes.markupOnly !== undefined + ? window.config.outputFileSuffixes.markupOnly + : '.markup-only'; + + // add the default panels + // Panels.add({ 'id': 'pl-panel-info', 'name': 'info', 'default': true, 'templateID': 'pl-panel-template-info', 'httpRequest': false, 'prismHighlight': false, 'keyCombo': '' }); + // TODO: sort out pl-panel-html + Panels.add({ + id: 'pl-panel-pattern', + name: window.config.patternExtension.toUpperCase(), + default: true, + templateID: 'pl-panel-template-code', + httpRequest: true, + httpRequestReplace: fileSuffixPattern, + httpRequestCompleted: false, + prismHighlight: true, + language: PrismLanguages.get(window.config.patternExtension), + keyCombo: 'ctrl+shift+u', + }); + + Panels.add({ + id: 'pl-panel-html', + name: 'HTML', + default: false, + templateID: 'pl-panel-template-code', + httpRequest: true, + httpRequestReplace: fileSuffixMarkup + '.html', + httpRequestCompleted: false, + prismHighlight: true, + language: 'markup', + keyCombo: 'ctrl+shift+y', + }); + } + } +} // gather panels from plugins Dispatcher.trigger('setupPanels'); + +window.addEventListener('message', receiveIframeMessage, false); diff --git a/packages/uikit-workshop/src/scripts/components/pl-controls/pl-controls.js b/packages/uikit-workshop/src/scripts/components/pl-controls/pl-controls.js new file mode 100755 index 000000000..c9bc313db --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-controls/pl-controls.js @@ -0,0 +1,56 @@ +import { define, props } from 'skatejs'; +import { h } from 'preact'; + +const classNames = require('classnames'); +import { urlHandler, patternName } from '../../utils'; + +import { store } from '../../store.js'; // connect to redux +import { BaseComponent } from '../base-component.js'; + +import { ViewportSize } from '../pl-viewport-size/pl-viewport-size'; +import { ViewportSizes } from '../pl-viewport-size-list/pl-viewport-size-list'; + +@define +class Controls extends BaseComponent { + static is = 'pl-controls'; + + constructor(self) { + self = super(self); + self.useShadow = false; + self.state = { + pxSize: '', + emSize: '', + }; + return self; + } + + _stateChanged(state) { + this.setState({ + pxSize: state.app.viewportPx || '', + emSize: state.app.viewportEm || '', + }); + } + + connected() { + const state = store.getState(); + + this.setState({ + pxSize: state.app.viewportPx || '', + emSize: state.app.viewportEm || '', + }); + } + + render() { + const { pxSize, emSize } = this.state; + + return ( +
    + + + +
    + ); + } +} + +export { Controls }; diff --git a/packages/uikit-workshop/src/scripts/components/pl-controls/pl-controls.scss b/packages/uikit-workshop/src/scripts/components/pl-controls/pl-controls.scss new file mode 100755 index 000000000..61f23a368 --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-controls/pl-controls.scss @@ -0,0 +1,62 @@ +/*------------------------------------*\ + #CONTROLS +\*------------------------------------*/ + +pl-controls { + margin-left: auto; /* 2 */ + display: flex; + flex-wrap: nowrap; + align-self: center; + padding: 0 0.5rem; + + .pl-c-body--theme-sidebar & { + display: block; + + @media all and (min-width: $pl-bp-med) { + width: 100%; + position: relative; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + box-shadow: 0 -2px 5px rgba($pl-color-black, 0.1); + + &:before { + position: absolute; + left: 0; + right: 0; + top: 0; + border-top: 1px solid; + border-top-color: $pl-color-gray-20; + border-top-color: var(--theme-border, $pl-color-gray-20); + height: 1px; + content: ''; + width: auto; + } + } + } +} + +/** + * 1) Controls contains viewport resizer and tools dropdown + * 2) Right-align inside of header + */ +.pl-c-controls { + margin-left: auto; /* 2 */ + display: flex; + flex-wrap: nowrap; + + // IE 11 layout bug + @media all and (min-width: $pl-bp-med) { + .pl-c-body--theme-sidebar & { + display: block; + } + } +} + +/** +* Control list +*/ +.pl-c-controls__list { + @include listReset(); + display: flex; + flex-wrap: nowrap; +} diff --git a/packages/uikit-workshop/src/scripts/components/pl-copy-to-clipboard/pl-copy-to-clipboard.js b/packages/uikit-workshop/src/scripts/components/pl-copy-to-clipboard/pl-copy-to-clipboard.js new file mode 100755 index 000000000..3cc09ed68 --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-copy-to-clipboard/pl-copy-to-clipboard.js @@ -0,0 +1,14 @@ +/** + * Copy to clipboard functionality for code snippet examples + */ + +import Clipboard from 'clipboard'; + +const clipboard = new Clipboard('.pl-js-code-copy-btn'); +clipboard.on('success', function(e) { + const copyButton = document.querySelectorAll('.pl-js-code-copy-btn'); + for (let i = 0; i < copyButton.length; i++) { + copyButton[i].innerText = 'Copy'; + } + e.trigger.textContent = 'Copied'; +}); diff --git a/packages/uikit-workshop/src/scripts/components/pl-drawer/pl-drawer.js b/packages/uikit-workshop/src/scripts/components/pl-drawer/pl-drawer.js new file mode 100755 index 000000000..76a6c2d3a --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-drawer/pl-drawer.js @@ -0,0 +1,144 @@ +import { define, props } from 'skatejs'; +import { h } from 'preact'; + +import { store } from '../../store.js'; // redux store +import { + updateDrawerState, + updateDrawerHeight, + updateDrawerAnimationState, +} from '../../actions/app.js'; // redux actions needed by this element. +import { css } from '../../utils'; +import { BaseComponent } from '../base-component.js'; +import AnimateHeight from 'react-animate-height'; +import CloseIcon from '../../../icons/close.svg'; + +@define +export class Drawer extends BaseComponent { + static is = 'pl-drawer'; + + constructor(self) { + self = super(self); + self.onMouseDown = self.onMouseDown.bind(self); // fix bindings so "self" works properly + self.onMouseUp = self.onMouseUp.bind(self); // fix bindings so "self" works properly + self.onMouseMove = self.onMouseMove.bind(self); // fix bindings so "this" works properly + self.useShadow = false; + return self; + } + + state = { + isMouseDown: false, + isMouseUp: false, + isDragging: false, + hasDragged: false, + panelHeight: '50vh', + }; + + onMouseDown() { + this.setState({ + ...this.state, + isMouseDown: true, + }); + + store.dispatch(updateDrawerAnimationState(true)); + + document.addEventListener('mousemove', this.onMouseMove); + document.addEventListener('mouseup', this.onMouseUp); + } + + onMouseMove(event) { + // 1/2 the height of the UI being dragged. @todo: make sure this 7px is calculated + const clientHeight = event.targetTouches + ? event.targetTouches[0].clientY + : event.clientY; + const panelHeight = window.innerHeight - clientHeight + 7; + + store.dispatch(updateDrawerHeight(panelHeight)); + + this.setState({ + ...this.state, + isDragging: true, + panelHeight: `${panelHeight}px`, + }); + } + + onMouseUp() { + this.setState({ + ...this.state, + hasDragged: this.state.isDragging, + isDragging: false, + isMouseDown: false, + isMouseUp: true, + }); + + store.dispatch(updateDrawerAnimationState(false)); + + document.removeEventListener('mousemove', this.onMouseMove); + document.removeEventListener('mouseup', this.onMouseUp); + } + + static props = { + drawerOpened: props.boolean, + }; + + render({ drawerOpened, drawerHeight, isViewallPage }) { + const classes = css( + 'pl-c-drawer', + 'pl-js-drawer', + drawerOpened && !isViewallPage ? 'pl-is-active' : '' + ); + + const height = + drawerOpened && !isViewallPage + ? drawerHeight > 20 ? drawerHeight : 300 + : 0; + + return ( +
    +
    + +
    +
    +
    +
    + {/* */} + + +
    +
    +
    +
    + +
    + ); + } + + _stateChanged(state) { + this.drawerOpened = state.app.drawerOpened; + this.drawerHeight = state.app.drawerHeight; + this.isDragging = state.app.isDragging; + this.isViewallPage = state.app.isViewallPage; + } +} diff --git a/packages/uikit-workshop/src/sass/scss/04-components/_modal.scss b/packages/uikit-workshop/src/scripts/components/pl-drawer/pl-drawer.scss old mode 100644 new mode 100755 similarity index 70% rename from packages/uikit-workshop/src/sass/scss/04-components/_modal.scss rename to packages/uikit-workshop/src/scripts/components/pl-drawer/pl-drawer.scss index 384e44f86..a1d6b322d --- a/packages/uikit-workshop/src/sass/scss/04-components/_modal.scss +++ b/packages/uikit-workshop/src/scripts/components/pl-drawer/pl-drawer.scss @@ -1,46 +1,44 @@ /*------------------------------------*\ - #MODAL + #drawer \*------------------------------------*/ -$pl-resizer-height: 14px; +$pl-drawer-resizer-height: 14px; -pl-modal { +pl-drawer { display: flex; flex-direction: column; position: relative; position: sticky; + top: auto; + bottom: 0; + left: 0; + right: 0; z-index: 20; - max-height: 100vh; - box-shadow: 0 0 2px 0 $pl-color-gray-70; overflow: visible; + border-top: 1.1px solid $pl-color-gray-20; // sub-pixel bug in Chrome. border disappears sometimes when set to 1px + + border-top-color: $pl-color-gray-20; + border-top-color: var(--theme-border, $pl-color-gray-20); } /** - * 1) The modal slides up from the bottom of the viewport when + * 1) The drawer slides up from the bottom of the viewport when * "show pattern info" is selected on the pattern detail screen. */ -.pl-c-modal { +.pl-c-drawer { display: flex; flex-direction: column; font-family: $pl-font; background-color: $pl-color-gray-87; + background-color: var(--theme-secondary, $pl-color-gray-87); color: $pl-color-gray-20; - position: sticky; - top: auto; - bottom: 0; - left: 0; - right: 0; - z-index: 5; width: 100%; - height: 0; - transition: transform 0.3s ease, height 0.3s ease; - transform: translate3d(0, 100%, 0); + height: 100%; + transform: translate3d(0, 0, 0); pointer-events: none; - will-change: height, transform; overflow: hidden; max-width: 100vw; - box-shadow: 0 -1px 2px rgba($pl-color-gray-70, 0.1); .pl-c-body--theme-sidebar & { @media all and (min-width: $pl-bp-med) { @@ -48,61 +46,69 @@ pl-modal { } } + .pl-c-body--theme-light & { + // Modal / Drawer inside a light theme + background-color: $pl-color-white; + color: $pl-color-gray-70; + } + /** - * Active modal + * Active drawer */ &.pl-is-active { - transform: translate3d(0, 0, 0); - height: 40vh; // default height unless manually resized - transition: transform 0.3s ease; pointer-events: auto; } } -.pl-c-modal__wrapper { +.pl-c-drawer__wrapper { transform: translate3d(0, 0, 0); } -.pl-c-modal__wrapper > * { +.pl-c-drawer__wrapper > * { height: 100%; } -.pl-c-modal__content { +.pl-c-drawer__content { flex-grow: 1; display: flex; width: 100%; overflow: hidden; // needed for IE 11 so scrollbars show up } -.pl-c-modal__toolbar { +.pl-c-drawer__toolbar { display: flex; flex-direction: column; flex-shrink: 0; // so that the resizer height doesn't change unexpectedly } -.pl-c-modal__content-wrapper { +.pl-c-drawer__content-wrapper { display: flex; flex-direction: column; flex-grow: 1; overflow: hidden; // needed for IE 11 so scrollbars show up + + @supports (padding: env(safe-area-inset-top)){ + padding-right: calc(env(safe-area-inset-right) - 0.9rem); + } } -.pl-c-modal__toolbar-controls { +.pl-c-drawer__toolbar-controls { display: flex; flex-direction: row; align-self: flex-end; position: relative; z-index: 10; - flex-shrink: 0; + flex-shrink: 0; // fix for IE 11 squishing UI controls } /** - * Modal close button - * 1) Closes the modal popup + * drawer close button + * 1) Closes the drawer popup */ -.pl-c-modal__close-btn { +.pl-c-drawer__close-btn { @include linkStyle; margin: 0; + padding: 0.2rem; -webkit-appearance: none; flex-shrink: 0; // needed for IE 11 @@ -128,17 +134,18 @@ pl-modal { } } - -.pl-c-modal__cover { +.pl-c-drawer__cover { width: 100%; height: 100%; + top: 0; + left: 0; display: none; - position: absolute; + position: fixed; z-index: 20; cursor: move; } -.pl-c-modal__resizer { +.pl-c-drawer__resizer { display: flex; position: absolute; top: 0; @@ -146,8 +153,7 @@ pl-modal { right: 0; align-items: center; justify-content: center; - left: 0; - height: $pl-resizer-height; + height: $pl-drawer-resizer-height; width: 100%; background-color: inherit; z-index: 2; @@ -163,7 +169,7 @@ pl-modal { opacity: 0.5; background-color: currentColor; border-radius: 3px; - display: block; + display: block; // IE 11 bug fix } &:hover:after { @@ -180,9 +186,9 @@ pl-modal { * Close button icon * 1) Displayed as an e */ -.pl-c-modal__close-btn-icon { - width: 12px; - height: 12px; +.pl-c-drawer__close-btn-icon { + width: 20px; + height: 20px; color: currentColor; fill: currentColor; transition: fill $pl-animate-quick ease-out; diff --git a/packages/uikit-workshop/src/scripts/components/pl-header/pl-header.js b/packages/uikit-workshop/src/scripts/components/pl-header/pl-header.js new file mode 100755 index 000000000..d377609cc --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-header/pl-header.js @@ -0,0 +1,74 @@ +import { define, props } from 'skatejs'; +import { h } from 'preact'; +const classNames = require('classnames'); + +import { store } from '../../store.js'; // connect to redux +import { BaseComponent } from '../base-component.js'; +import MenuIcon from '../../../icons/menu.svg'; +import VisuallyHidden from '@reach/visually-hidden'; + +@define +class Header extends BaseComponent { + static is = 'pl-header'; + + constructor(self) { + self = super(self); + self.useShadow = false; + self.toggleNav = self.toggleNav.bind(self); + return self; + } + + connected() { + const state = store.getState(); + this.themeMode = state.app.themeMode || 'dark'; + } + + static props = { + themeMode: props.string, + }; + + _stateChanged(state) { + this.themeMode = state.app.themeMode || 'dark'; + this.triggerUpdate(); + } + + shouldUpdate(prevProps, prevState) { + return true; + } + + toggleNav() { + const navTarget = this.querySelector('.pl-js-nav-target'); + navTarget.classList.toggle('pl-is-active'); // @todo: refactor to have this add based on the component's state + } + + render({ themeMode }) { + return ( + + ); + } +} + +export { Header }; diff --git a/packages/uikit-workshop/src/scripts/components/pl-header/pl-header.scss b/packages/uikit-workshop/src/scripts/components/pl-header/pl-header.scss new file mode 100755 index 000000000..cde3b9f04 --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-header/pl-header.scss @@ -0,0 +1,93 @@ +/*------------------------------------*\ + #HEADER +\*------------------------------------*/ + +pl-header { + position: relative; + position: sticky; + top: 0; + left: 0; + z-index: 4; + display: flex; /* 2 */ + width: 100%; + background-color: $pl-color-black; + background-color: var(--theme-secondary, $pl-color-black); + max-height: 100vh; + + color: $pl-color-gray-20; + color: var(--theme-text, $pl-color-gray-20); + border-right: 1px solid; + border-bottom: 1px solid; + border-right-color: $pl-color-gray-20; + border-right-color: var(--theme-border, $pl-color-gray-20); + border-bottom-color: $pl-color-gray-20; + border-bottom-color: var(--theme-border, $pl-color-gray-20); + + .pl-c-body--theme-light & { + color: $pl-color-black; + background-color: $pl-color-white; + border-bottom: 1px solid $pl-color-gray-20; + } + + @media all and (min-width: $pl-bp-med) { + .pl-c-body--theme-sidebar & { + position: fixed; + position: sticky; + /** + * Header + * 1) Set width to sidebar width defined above + * 2) Make header 100% of the viewport height + * 3) Stack header content stack on top of each other + * 4) void bottom border for light theme + */ + width: $pl-sidebar-width; /* 1 */ + // padding: 1rem; + // overflow: auto; + // -webkit-overflow-scrolling: touch; + border-bottom: 0; /* 4 */ + } + } + +} + +/** +* 1) Pattern Lab's header is fixed across the top of the viewport and +* contains the primary pattern navigation, viewport resizing items, +* and tools. +* 2) Display nav and controls horizontally +*/ +.pl-c-header { + display: flex; /* 2 */ + flex-direction: row; + width: 100%; + font-family: $pl-font; + font-size: $pl-font-size-sm; + min-height: 30px; // magic number -- needed for initial skeleton screen styles used in the critical CSS + background-color: inherit; + + @supports(padding: max(0px)) { + padding-left: env(safe-area-inset-left); + padding-right: env(safe-area-inset-right); + } + + @media all and (min-width: $pl-bp-med) { + .pl-c-body--theme-sidebar & { + flex-direction: column; /* 3 */ + justify-content: space-between; + } + } +} + +/** + * Nav toggle button + * 1) Styles for the general nav toggle button, which + * only appears on small screens + */ +.pl-c-header__nav-toggle { + @include linkStyle(); + border: 0; + + @media all and (min-width: $pl-bp-med) { + display: none; + } +} diff --git a/packages/uikit-workshop/src/scripts/components/pl-layout/pl-layout.js b/packages/uikit-workshop/src/scripts/components/pl-layout/pl-layout.js old mode 100644 new mode 100755 index 7fa8b8e91..e41a0273a --- a/packages/uikit-workshop/src/scripts/components/pl-layout/pl-layout.js +++ b/packages/uikit-workshop/src/scripts/components/pl-layout/pl-layout.js @@ -1,10 +1,9 @@ import { define, props } from 'skatejs'; -import { h } from 'preact'; -import Hogan from 'hogan.js'; const classNames = require('classnames'); +import { html } from 'lit-html'; import { store } from '../../store.js'; // connect to redux -import { BaseComponent } from '../base-component.js'; +import { BaseLitComponent } from '../base-component.js'; import iFrameResize from 'iframe-resizer/js/iframeResizer.js'; iFrameResize({ @@ -17,40 +16,16 @@ iFrameResize({ }); @define -class Layout extends BaseComponent { +class Layout extends BaseLitComponent { static is = 'pl-layout'; constructor(self) { self = super(self); - try { - /* load pattern nav */ - const template = document.querySelector('.pl-js-pattern-nav-template'); - const templateCompiled = Hogan.compile(template.innerHTML); - const templateRendered = templateCompiled.render(window.navItems); - this.renderRoot.querySelector( - '.pl-js-pattern-nav-target' - ).innerHTML = templateRendered; - - /* load ish controls */ - const controlsTemplate = document.querySelector( - '.pl-js-ish-controls-template' - ); - const controlsTemplateCompiled = Hogan.compile( - controlsTemplate.innerHTML - ); - const controlsTemplateRendered = controlsTemplateCompiled.render( - window.ishControls - ); - this.renderRoot.querySelector( - '.pl-js-controls' - ).innerHTML = controlsTemplateRendered; - } catch (e) { - const message = - '

    Please generate your site before trying to view it.

    '; - this.renderRoot.querySelector( - '.pl-js-pattern-nav-target' - ).innerHTML = message; - } + self.useShadow = false; + self.targetOrigin = + window.location.protocol === 'file:' + ? '*' + : window.location.protocol + '//' + window.location.host; return self; } @@ -61,27 +36,44 @@ class Layout extends BaseComponent { connected() { const state = store.getState(); - this.layoutMode = state.app.layoutMode; + this.layoutMode = state.app.layoutMode || 'vertical'; this.themeMode = state.app.themeMode; } - get renderRoot() { - return this; + rendered() { + this.iframeElement = document.querySelector('.pl-js-iframe'); } _stateChanged(state) { - this.layoutMode = state.app.layoutMode; + this.layoutMode = state.app.layoutMode || 'vertical'; this.themeMode = state.app.themeMode; + this.iframeElement = document.querySelector('.pl-js-iframe'); + const layoutModeClass = + this.layoutMode === 'vertical' ? 'sidebar' : 'horizontal'; - const classes = classNames({ + const classes = classNames(`pl-c-body--theme-${layoutModeClass}`, { [`pl-c-body--theme-${this.themeMode}`]: this.themeMode !== undefined, - [`pl-c-body--theme-${ - this.layoutMode === 'vertical' ? 'sidebar' : 'horizontal' - }`]: - this.layoutMode !== undefined, }); this.className = classes; + + if (this.iframeElement) { + const obj = JSON.stringify({ + event: 'patternLab.stateChange', + state, + }); + this.iframeElement.contentWindow.postMessage(obj, this.targetOrigin); + } + } + + render() { + return html` + +
    + + +
    + `; } } diff --git a/packages/uikit-workshop/src/scripts/components/pl-layout/pl-layout.scss b/packages/uikit-workshop/src/scripts/components/pl-layout/pl-layout.scss old mode 100644 new mode 100755 index 00dde1208..d93ec01f6 --- a/packages/uikit-workshop/src/scripts/components/pl-layout/pl-layout.scss +++ b/packages/uikit-workshop/src/scripts/components/pl-layout/pl-layout.scss @@ -6,13 +6,17 @@ pl-layout { width: 100%; min-height: 100vh; max-width: 100vw; - background-color: $pl-color-gray-13; - + background-color: $pl-color-white; + // Prevent extra scrollbars in just IE 11 @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { overflow: hidden; } + .pl-c-layout { + flex-grow: 1; + } + &.pl-c-body--theme-sidebar { @media all and (min-width: $pl-bp-med) { flex-direction: row; diff --git a/packages/uikit-workshop/src/scripts/components/pl-logo/pl-logo.js b/packages/uikit-workshop/src/scripts/components/pl-logo/pl-logo.js new file mode 100755 index 000000000..be0f78155 --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-logo/pl-logo.js @@ -0,0 +1,44 @@ +import { define, props } from 'skatejs'; +import { h } from 'preact'; +import { store } from '../../store.js'; // connect to redux + +const classNames = require('classnames'); +import { BaseComponent } from '../base-component.js'; + +@define +class Logo extends BaseComponent { + static is = 'pl-logo'; + + constructor(self) { + self = super(self); + return self; + } + + connected() { + const state = store.getState(); + this.themeMode = state.app.themeMode || 'dark'; + } + + shouldUpdate(prevProps, prevState) { + return true; + } + + static props = { + url: props.string, + text: props.string, + src: props.string, + }; + + render({ themeMode }) { + return ( + + + {this.props.text && ( + {this.props.text} + )} + + ); + } +} + +export { Logo }; diff --git a/packages/uikit-workshop/src/scripts/components/pl-logo/pl-logo.scss b/packages/uikit-workshop/src/scripts/components/pl-logo/pl-logo.scss new file mode 100755 index 000000000..400a707e6 --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-logo/pl-logo.scss @@ -0,0 +1,65 @@ +/*------------------------------------*\ + #LOGO +\*------------------------------------*/ + +pl-logo { + max-width: 12rem; + align-self: center; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + flex-shrink: 0; + position: relative; + z-index: 100; + + @media all and (min-width: $pl-bp-med) { + .pl-c-body--theme-sidebar & { + max-width: none; + width: 12rem; + padding: 0.5rem; + } + } +} + +.pl-c-logo { + width: 12rem; + padding: 0.5rem; + display: flex; + align-items: center; + justify-content: center; + color: inherit; + text-decoration: none; + + @media all and (min-width: $pl-bp-med) { + .pl-c-body--theme-sidebar & { + width: 12rem; + } + } + outline: 0; + text-transform: lowercase; + font-size: 1.4rem; + font-weight: bold; + line-height: 1; + margin: 0; + transition: color .2s ease; + + &:focus { + outline: 1px dotted $pl-color-gray-50; + outline-offset: -1px; + } +} + +.pl-c-logo__img { + display: block; + height: auto; + max-height: 2.5rem; + + // @todo: remove if these styles are no longer needed + // width: 100%; + // max-width: 2.5rem; +} + +.pl-c-logo__text { + margin-left: 0.5rem; +} diff --git a/packages/uikit-workshop/src/scripts/components/pl-nav/pl-nav.js b/packages/uikit-workshop/src/scripts/components/pl-nav/pl-nav.js new file mode 100755 index 000000000..0f99ea5d9 --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-nav/pl-nav.js @@ -0,0 +1,596 @@ +import { define, props } from 'skatejs'; +import { h } from 'preact'; + +const classNames = require('classnames'); + +import { store } from '../../store.js'; // redux store +import ArrowIcon from '../../../icons/arrow-down.svg'; +import { BaseComponent } from '../base-component.js'; +import { scrollTo, scrollIntoView } from 'scroll-js'; +import 'url-search-params-polyfill'; + +const SubSubList = props => { + const { children, category, elem } = props; + const reorderedChildren = []; + + const nonViewAllItems = children.filter( + item => + item.patternName !== 'View All' && !item.patternName.includes(' Docs') + ); + // const nonViewAllItems = children.filter((item => (item.patternName !== 'View All'))); + const viewAllItems = children.filter(item => item.patternName === 'View All'); + + reorderedChildren.push(...viewAllItems, ...nonViewAllItems); + + return ( +
  • + {viewAllItems.length > 0 ? ( + viewAllItems.map(patternSubtypeItem => ( + + )) + ) : ( + + )} + + {((viewAllItems.length > 0 && nonViewAllItems.length > 1) || + viewAllItems.length === 0) && ( +
      + {nonViewAllItems.map(patternSubtypeItem => ( +
    1. + + elem.handleClick(e, patternSubtypeItem.patternPartial) + } + data-patternpartial={patternSubtypeItem.patternPartial} + > + {patternSubtypeItem.patternName === 'View All' + ? `${category} Overview` + : patternSubtypeItem.patternName} + {patternSubtypeItem.patternState && ( + + )} + +
    2. + ))} +
    + )} +
  • + ); +}; + +const SpecialButton = props => { + return ( + + ); +}; + +const Button = props => { + return ( + + ); +}; + +const ButtonTitle = props => { + return ( + + ); +}; + +@define +class Nav extends BaseComponent { + static is = 'pl-nav'; + + constructor(self) { + self = super(self); + self.toggleNavPanel = self.toggleNavPanel.bind(self); + self.toggleSpecialNavPanel = self.toggleSpecialNavPanel.bind(self); + self.handleClick = self.handleClick.bind(self); + self.handleURLChange = self.handleURLChange.bind(self); + self._hasInitiallyRendered = false; + self.handleURLChangeOnRender = false; + self.receiveIframeMessage = self.receiveIframeMessage.bind(self); + self.useShadow = false; + return self; + } + + connected() { + this.isOpenClass = 'pl-is-active'; + const self = this; + const state = store.getState(); + this.layoutMode = state.app.layoutMode || ''; + this.currentPattern = state.app.currentPattern || ''; + this.elem = this; + this.previousActiveLinks = []; + this.iframeElem = document.querySelector('pl-iframe'); + window.addEventListener('message', this.receiveIframeMessage, false); + + document.body.addEventListener('click', function(e) { + if ( + e.target.closest('pl-header') === null && + e.target.closest('svg') === null + ) { + self.cleanupActiveNav(); + } + }); + } + + _stateChanged(state) { + this.layoutMode = state.app.layoutMode || ''; + + if (this.currentPattern !== state.app.currentPattern) { + this.currentPattern = state.app.currentPattern; + } + + this.handleURLChange(); // so the nav logic is always correct (ex. layout changes) + } + + receiveIframeMessage(event) { + const self = this; + + // does the origin sending the message match the current host? if not dev/null the request + if ( + window.location.protocol !== 'file:' && + event.origin !== window.location.protocol + '//' + window.location.host + ) { + return; + } + + let data = {}; + try { + data = + typeof event.data !== 'string' ? event.data : JSON.parse(event.data); + } catch (e) { + // @todo: how do we want to handle exceptions here? + } + + if (data.event !== undefined && data.event === 'patternLab.pageClick') { + try { + if ( + window.matchMedia('(min-width: calc(42em))').matches && + self.layoutMode !== 'vertical' + ) { + self.cleanupActiveNav(); + } + } catch (error) { + console.log(error); + } + } + } + + cleanupActiveNav(topLevelOnly) { + this.navContainer = document.querySelector('.pl-js-nav-container'); + this.navAccordionTriggers = document.querySelectorAll('.pl-js-acc-handle'); + this.navAccordionPanels = document.querySelectorAll('.pl-js-acc-panel'); + this.topLevelTriggers = document.querySelectorAll( + '.pl-c-nav__link--title.pl-is-active' + ); + + if (topLevelOnly === true) { + this.navContainer.classList.remove('pl-is-active'); + this.topLevelTriggers.forEach(trigger => { + trigger.classList.remove('pl-is-active'); + }); + } else { + if ( + window.matchMedia('(max-width: calc(42em - 1px))').matches || + this.layoutMode !== 'vertical' + ) { + this.navContainer.classList.remove('pl-is-active'); + this.navAccordionTriggers.forEach(trigger => { + trigger.classList.remove('pl-is-active'); + }); + this.navAccordionPanels.forEach(panel => { + panel.classList.remove('pl-is-active'); + }); + } else { + this.navContainer.classList.remove('pl-is-active'); + } + } + } + + handleClick(event, pattern) { + event.preventDefault(); + this.iframeElem.navigateTo(pattern); + this.cleanupActiveNav(); + } + + handleURLChange() { + if (!this._hasInitiallyRendered) { + this.handleURLChangeOnRender = true; + return; + } + + const shouldAutoOpenNav = + window.matchMedia('(min-width: calc(42em))').matches && + this.layoutMode === 'vertical'; + + const currentPattern = this.currentPattern; + const activeLink = document.querySelector( + `[data-patternpartial="${currentPattern}"]` + ); + const self = this; + + if (this.previousActiveLinks) { + this.previousActiveLinks.forEach(function(link, index) { + self.previousActiveLinks[index].classList.remove('pl-is-active'); + }); + } + this.previousActiveLinks = []; + + if (activeLink) { + activeLink.classList.add('pl-is-active'); + this.previousActiveLinks.push(activeLink); + + // handle overview links vs nested links + if (activeLink.classList.contains('pl-js-link-overview')) { + const childDropdownTrigger = activeLink.nextSibling; + const childDropdown = activeLink.parentNode.nextSibling; + + if (childDropdown && shouldAutoOpenNav) { + if (childDropdown.tagName) { + childDropdown.classList.add('pl-is-active'); + this.previousActiveLinks.push(childDropdown); + } + } + + if (childDropdownTrigger && shouldAutoOpenNav) { + if (childDropdownTrigger.tagName) { + childDropdownTrigger.classList.add('pl-is-active'); + this.previousActiveLinks.push(childDropdownTrigger); + } + } + } + + const parentDropdown = activeLink.closest('.pl-js-acc-panel'); + let parentDropdownTrigger; + + if (parentDropdown) { + if (parentDropdown.previousSibling) { + parentDropdownTrigger = parentDropdown.previousSibling; + + if ( + parentDropdown.previousSibling.classList.contains( + 'pl-c-nav__link--overview-wrapper' + ) && + shouldAutoOpenNav + ) { + this.previousActiveLinks.push(parentDropdown.previousSibling); + parentDropdown.previousSibling.classList.add('pl-is-active'); + parentDropdownTrigger = parentDropdown.previousSibling.querySelector( + '.pl-js-acc-handle' + ); + } + + const grandparentDropdown = parentDropdown.closest( + '.pl-c-nav__sublist--dropdown' + ); + const grandparentDropdownTrigger = + grandparentDropdown.previousSibling; + + if (parentDropdown && shouldAutoOpenNav) { + parentDropdown.classList.add('pl-is-active'); + this.previousActiveLinks.push(parentDropdown); + } + + // don't auto-open + if (parentDropdownTrigger) { + if ( + shouldAutoOpenNav === true || + parentDropdownTrigger.classList.contains( + 'pl-c-nav__link--title' + ) === false + ) { + parentDropdownTrigger.classList.add('pl-is-active'); + this.previousActiveLinks.push(parentDropdownTrigger); + } + } + + if (grandparentDropdown && shouldAutoOpenNav) { + if (shouldAutoOpenNav) { + grandparentDropdown.classList.add('pl-is-active'); + } + this.previousActiveLinks.push(grandparentDropdown); + } + + if (grandparentDropdownTrigger && shouldAutoOpenNav) { + if (shouldAutoOpenNav) { + grandparentDropdownTrigger.classList.add('pl-is-active'); + } + this.previousActiveLinks.push(grandparentDropdownTrigger); + } + } + } + } else { + this.cleanupActiveNav(); + } + } + + static props = { + autoClose: { + ...props.boolean, + ...{ default: true }, + }, + layoutMode: props.string, + collapsedByDefault: { + ...props.boolean, + ...{ default: true }, + }, + }; + + toggleSpecialNavPanel(e) { + const target = e.target; + const panel = target.parentNode.nextSibling; + const subnav = panel.parentNode.parentNode.classList.contains( + 'pl-js-acc-panel' + ); + + if (!subnav) { + const navTriggers = document.querySelectorAll( + `.pl-js-acc-handle.pl-is-active` + ); + const navPanels = document.querySelectorAll( + `.pl-js-acc-panel.pl-is-active` + ); + + navTriggers.forEach(navTrigger => { + if (navTrigger !== target) { + navTrigger.classList.remove('pl-is-active'); + } + }); + + navPanels.forEach(navPanel => { + if (navPanel !== target) { + navPanel.classList.remove('pl-is-active'); + } + }); + } + + if (target.classList.contains('pl-is-active')) { + target.classList.remove('pl-is-active'); + panel.classList.remove('pl-is-active'); + } else { + target.classList.add('pl-is-active'); + panel.classList.add('pl-is-active'); + } + } + + toggleNavPanel(e) { + const target = e.target; + const panel = target.nextSibling; + const subnav = target.parentNode.parentNode.classList.contains( + 'pl-js-acc-panel' + ); + + if (!subnav) { + const navTriggers = document.querySelectorAll('.pl-js-acc-handle'); + const navPanels = document.querySelectorAll('.pl-js-acc-panel'); + + navTriggers.forEach(navTrigger => { + if (navTrigger !== target) { + navTrigger.classList.remove('pl-is-active'); + } + }); + + navPanels.forEach(navPanel => { + if (navPanel !== target) { + navPanel.classList.remove('pl-is-active'); + } + }); + } + + if (target.classList.contains('pl-is-active')) { + target.classList.remove('pl-is-active'); + panel.classList.remove('pl-is-active'); + } else { + target.classList.add('pl-is-active'); + panel.classList.add('pl-is-active'); + } + } + + rendered() { + if (this._hasInitiallyRendered === false) { + this._hasInitiallyRendered = true; + } + + if (this.handleURLChangeOnRender === true) { + this.handleURLChangeOnRender = false; + this.handleURLChange(); + } + } + + render({ layoutMode }) { + const patternTypes = window.navItems.patternTypes; + + return ( +
      + {patternTypes.map((item, i) => { + const classes = classNames({ + [`pl-c-nav__item pl-c-nav__item--${item.patternTypeLC}`]: true, + }); + + const patternItems = item.patternItems; + + return ( +
    1. + + {item.patternTypeUC} + + +
        + {item.patternTypeItems.map((patternSubtype, i) => { + return ( + + {patternSubtype.patternSubtypeItems} + + ); + })} + + {patternItems && + patternItems.map((patternItem, i) => { + return ( +
      1. + + this.handleClick(e, patternItem.patternPartial) + } + data-patternpartial={patternItem.patternPartial} + tabindex="0" + > + {patternItem.patternName === 'View All' + ? patternItem.patternName + ' ' + item.patternTypeUC + : patternItem.patternName} + {patternItem.patternState && ( + + )} + +
      2. + ); + })} +
      +
    2. + ); + })} + + {/*
    3. + + All + +
    4. */} +
    + ); + } +} + +export { Nav }; diff --git a/packages/uikit-workshop/src/scripts/components/pl-nav/pl-nav.scss b/packages/uikit-workshop/src/scripts/components/pl-nav/pl-nav.scss new file mode 100755 index 000000000..3a01836f5 --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-nav/pl-nav.scss @@ -0,0 +1,503 @@ +/*------------------------------------*\ + #NAVIGATION +\*------------------------------------*/ + +pl-nav { + background-color: inherit; // so the inside of dropdowns inherits the correct color + display: block; // vertically align children + flex-grow: 1; + align-items: center; + + @media all and (min-width: $pl-bp-med) { + padding: 0; + display: flex; // vertically align children + } + + @media all and (min-width: $pl-bp-med) { + .pl-c-body--theme-sidebar & { + display: block; + } + } +} + + +/** + * Navigation container + * 1) Collapse height on small screens. Menu trigger button + * activates nav + */ +.pl-c-nav { + @include accordionPanel; + background-color: inherit; // allows the nav's children inherit from the parent header + position: absolute; + left: 0; // IE 11 layout broken + top: 100%; + width: 100%; + display: flex; + flex-direction: column; + transition: max-height $pl-animate-quick ease-out; + flex-shrink: 0; + padding-left: 0.25rem; + padding-right: 0.25rem; + + @media all and (min-width: $pl-bp-med) { + .pl-c-body--theme-sidebar & { + padding-bottom: 0.5rem; + display: block; + overflow: auto; + -webkit-overflow-scrolling: touch; + flex-shrink: 1; + } + } + + // if nav was opened on smaller screen and screen is resized, it'll be cut off otherwise + @media all and (min-width: $pl-bp-med) { + overflow: visible; + max-height: none; + + &.pl-is-active { + overflow: visible; + } + } + + /** + * Active navigaiton + * 1) Slide + * 2) Set the height to the vierport height minus the height + * of the header + */ + &.pl-is-active { + @media all and (max-width: $pl-bp-med - 1) { + box-shadow: 0 1px 1px $pl-color-black; + + .pl-c-body--theme-light & { + box-shadow: 0 1px 1px darken($pl-color-gray-20, 15%); + } + } + + + + + // if nav was opened on smaller screen and screen is resized, it'll be cut off otherwise + @media all and (min-width: $pl-bp-med) { + // overflow: visible; + // overflow: auto; + max-height: none; + } + } + + @media all and (min-width: $pl-bp-med) { + flex-direction: row; + position: relative; + top: auto; + width: auto; + box-shadow: none; + } +} + +/** + * Nav list + * 1) appears as an
      + * 2) display as a horizontal list on larger screens + * 3) On small screens, move the nav list after the typeahead form field + */ +.pl-c-nav__list { + z-index: 1; + margin: 0; + padding: 0; + list-style: none; + flex-shrink: 0; // helps prevent top-level nav items from occasionally wrapping to multiple lines + flex-grow: 1; // auto-fill extra space available + max-width: 100%; // so content doesn't won't spill out horizontally + order: 2; + background-color: inherit; // allows the nav's children inherit from the parent header + + @media all and (min-width: $pl-bp-med) { + display: flex; /* 2 */ + order: 1; + + // workaround to Firefox-specific flexbox quirk + .pl-c-body--theme-sidebar & { + display: block; + // display: flex; + } + } +} + +/** + * Nav list item + */ +.pl-c-nav__item { + background-color: inherit; // allows the nav's children inherit from the parent header + cursor: pointer; + position: relative; + display: flex; + flex-direction: column; + justify-content: center; // vertically align nav items + + .pl-c-body--theme-sidebar & { + display: block; + } +} + +.pl-c-nav__item-inner { + position: relative; +} + +/** + * Nav link + */ +.pl-c-nav__link { + @include linkStyle; + color: inherit; + line-height: 1.5; + display: flex; + align-items: center; + margin: 0; // remove default button margin in Safari + color: inherit; + padding: 0.7rem 0.5rem; + + // makes link layout / size more consistent in the sidebar layout, especially when display: flex styles are removed for more consistent IE 11 rendering + .pl-c-body--theme-sidebar & { + width: 100%; + } +} + +.pl-c-nav__link, +.pl-c-nav__link--section-dropdown, +.pl-c-nav__link--sublink, +.pl-c-nav__link--overview { + @include linkStyle; + position: relative; + color: inherit; + + &:after { + content: ''; + pointer-events: none; + opacity: 0; + background-color: currentColor; + transition: opacity $pl-animate-quick ease-out; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + display: block; + } + + &:hover:after { + opacity: 0.1; + } + + // &.pl-is-active:after, + &:focus:after { + opacity: 0.1; + } +} + +/** + * Nav sublink + * 1) Visually differentiate sub-item links from + * the other links. Creates better hierarchy. + */ +.pl-c-nav__link--sublink { + text-transform: none; + font-size: 0.8rem; + line-height: 1.45; + padding-left: $pl-space + ($pl-space / 2); + padding-right: $pl-space + ($pl-space / 2); + + &.pl-is-active { + box-shadow: inset 4px 0 0 #6c79d9; + font-weight: bold; + } +} + +/** + * Nav link + */ +.pl-c-nav__link--dropdown { + -webkit-appearance: none; // remove default button styling + flex-grow: 1; // fill up extra space in parent nav item, if available +} + +.pl-c-nav__link--pattern { + padding-left: 0.75rem; + padding-right: 0.75rem; + flex-grow: 1; +} + +.pl-c-nav__link-text { + flex-grow: 1; + pointer-events: none; +} + +.pl-c-nav__link-icon { + pointer-events: none; + color: currentColor; + display: inline; + transition: all $pl-animate-quick ease-out; + transform: rotate(-90deg); + flex-grow: 0; + line-height: 1; +} + +.pl-c-nav__link--overview-wrapper.pl-is-active > .pl-c-nav__link--section-dropdown > .pl-c-nav__link-icon, +.pl-is-active > .pl-c-nav__link-icon { + transform: rotate(0); +} + +/** + * Nav sublist + * 1) On larger screens, display as dropdowns that + * hang over the header + */ +.pl-c-nav__sublist { + background-color: inherit; // allows the nav's children inherit from the parent header + @include listReset(); + + @media all and (min-width: $pl-bp-med) { + position: absolute; + top: 100%; /* 1 */ + left: 0; + min-width: 12rem; + border-bottom-left-radius: $pl-border-radius-med; + border-bottom-right-radius: $pl-border-radius-med; + } +} + +/** + * Dropdown sublist + */ +.pl-c-nav__sublist--dropdown, +.pl-c-nav__subsublist--dropdown { + @include listReset(); + @include accordionPanel(); + visibility: hidden; + + @media all and (min-width: $pl-bp-med) { + .pl-c-body--theme-sidebar & { + position: relative; + } + } + + .pl-c-nav__link { + padding-left: 1.5rem; + } + + .pl-c-nav__link--sublink { + padding-left: 1.5rem + .75rem; + } + + @media all and (max-width: $pl-bp-med - 1) { + .pl-c-nav__link { + padding-left: 1.5rem; + } + + .pl-c-nav__link--sublink { + padding-left: 1.5rem + .75rem; + } + } +} + +/** + * Dropdown sublist + * 1) Set the height to the viewport height minus the height of the header + */ +.pl-c-nav__sublist--dropdown.pl-is-active, +.pl-c-nav__subsublist--dropdown.pl-is-active { + visibility: visible; + max-height: none; + + @media all and (min-width: $pl-bp-med) { + height: auto; + max-height: calc(100vh - #{$offset-top} - 2rem); /* 1 */ + } + + .pl-c-body--theme-sidebar & { + max-height: none; + } +} + +.pl-c-nav__sublist--dropdown.pl-is-active { + @media all and (min-width: $pl-bp-med) { + box-shadow: 0 1px 3px rgba(0, 0, 0, .1); + border-left: 1px solid $pl-color-gray-87; + border-right: 1px solid $pl-color-gray-87; + + border-left-color: $pl-color-gray-87; + border-right-color: $pl-color-gray-87; + border-left-color: rgba(var(--theme-text-rgb), 0.1); + border-right-color: rgba(var(--theme-text-rgb), 0.1); + } + + .pl-c-body--theme-sidebar & { + box-shadow: none; + border: none; + } +} + + +.pl-c-nav__link--overview.pl-is-active { + &:hover:before { + opacity: 0.1; + } +} +.pl-c-nav__link--overview-wrapper, +.pl-c-nav__subsublist--dropdown, +.pl-c-nav__link--overview { + &:before { + content: ''; + position: absolute; + left: 0; + right: 0; + transition: opacity $pl-animate-quick ease-out; + opacity: 0; + top: 0; + bottom: 0; + background-color: currentColor; + z-index: 1; + pointer-events: none; + } + + &:after { + content: ''; + position: absolute; + left: 0; + right: 0; + transition: opacity $pl-animate-quick ease-out; + opacity: 0; + top: 0; + bottom: 0; + border-top: 1px solid rgba(0, 0, 0, .1); + border-bottom: 1px solid rgba(0, 0, 0, .1); + z-index: 1; + pointer-events: none; + } + + &.pl-is-active { + &:before, + &:after { + opacity: 0.025; + } + } + + .pl-c-body--theme-dark & { + &:before { + // background-color: rgba(255, 255, 255, .1); + } + + &:after { + border-bottom: 1px solid rgba(255, 255, 255, .1); + } + } +} + +/** + * Sub-navigation + * 1) Third-level links are stylistically different + * than first and second nav links. + */ +.pl-c-nav__subsublist { + @include listReset(); +} + +.pl-c-nav__link--overview.pl-c-nav__link--overview.pl-c-nav__link--overview { + font-size: 0.9rem; + padding-right: 0.5rem; + padding-left: 1.5rem; + position: relative; + flex-grow: 1; + + &:not(:only-child) { + margin-right: 2.5rem; + } +} + +.pl-c-nav__link--title { + font-size: 0.9rem; + color: $pl-color-gray-20; + color: var(--theme-text, $pl-color-gray-20); + + &.pl-is-active { + font-weight: 700; + } + + .pl-c-body--theme-light & { + color: $pl-color-black; + color: var(--theme-text); + } +} + +.pl-c-nav__list > .pl-c-nav__item:not(:last-child) { + @media all and (min-width: $pl-bp-med) { + .pl-c-body--theme-sidebar & { + margin-bottom: 0.5rem; + margin-top: 0.5rem; + + } + } +} + +.pl-c-nav__link--section-dropdown { + width: 2.5rem !important; + height: 2.5rem !important; + padding: 0 !important; + display: flex; + justify-content: center; + font-size: 0; + position: absolute; + right: 0; + top: 50%; + border: 2px solid transparent !important; + transform: translateY(-50%); + justify-content: center; + align-items: center; + color: currentColor; + + // border to indicate which nav links have two specific actions + &:before { + opacity: 0.1; + right: 2.4rem; + width: 1px; + left: auto; + transform: translateY(-50%); + } + + &:after { + opacity: 0; + width: 2.5rem; + left: 50%; + transform: translateY(-50%) translateX(-50%); + } + + &:before, + &:after { + height: 2.5rem; + transition: opacity $pl-animate-quick ease-out; + content: ''; + display: block; + position: absolute; + top: 50%; + background-color: currentColor; + } + + &:hover { + // background-color: transparent !important; + + &:after, + &:focus:after { + opacity: 0.1; + } + } + + &:active:not(:hover):after, + &:focus:not(:hover):after { + opacity: 0; + } +} + +.pl-c-nav__link--overview-wrapper { + position: relative; + display: flex; +} diff --git a/packages/uikit-workshop/src/scripts/components/pl-search/pl-search.js b/packages/uikit-workshop/src/scripts/components/pl-search/pl-search.js old mode 100644 new mode 100755 index c27480a44..90eb90e0c --- a/packages/uikit-workshop/src/scripts/components/pl-search/pl-search.js +++ b/packages/uikit-workshop/src/scripts/components/pl-search/pl-search.js @@ -1,10 +1,11 @@ import { define, props } from 'skatejs'; import { h } from 'preact'; +import { store } from '../../store.js'; // connect to redux + import Fuse from 'fuse.js'; import ReactHtmlParser from 'react-html-parser'; import classNames from 'classnames'; import Mousetrap from 'mousetrap'; - import VisuallyHidden from '@reach/visually-hidden'; import Autosuggest from 'react-autosuggest'; @@ -17,26 +18,31 @@ class Search extends BaseComponent { constructor(self) { self = super(self); - this.useShadow = false; - this.defaultMaxResults = 10; + self.useShadow = false; + self.defaultMaxResults = 10; // Autosuggest is a controlled component. // This means that you need to provide an input value // and an onChange handler that updates this value (see below). // Suggestions also need to be provided to the Autosuggest, // and they are initially empty because the Autosuggest is closed. - this.state = { + self.state = { value: '', suggestions: [], + isFocused: false, }; - this.receiveIframeMessage = this.receiveIframeMessage.bind(this); - this.onChange = this.onChange.bind(this); - this.toggleSearch = this.toggleSearch.bind(this); - // this.clearSearch = this.clearSearch.bind(this); - this.closeSearch = this.closeSearch.bind(this); - this.renderInputComponent = this.renderInputComponent.bind(this); - this.openSearch = this.openSearch.bind(this); + self.receiveIframeMessage = self.receiveIframeMessage.bind(self); + self.onChange = self.onChange.bind(self); + self.toggleSearch = self.toggleSearch.bind(self); + self.closeSearch = self.closeSearch.bind(self); + self.renderInputComponent = self.renderInputComponent.bind(self); + self.openSearch = self.openSearch.bind(self); + return self; + } + + connecting() { + super.connecting && super.connecting(); this.items = []; for (const patternType in window.patternPaths) { @@ -51,8 +57,6 @@ class Search extends BaseComponent { } } } - - return self; } connected() { @@ -64,6 +68,11 @@ class Search extends BaseComponent { window.addEventListener('message', this.receiveIframeMessage, false); } + _stateChanged(state) { + // throw new Error('_stateChanged() not implemented', this); + this.triggerUpdate(); + } + rendered() { this.inputElement = this.querySelector('.js-c-typeahead__input'); } @@ -85,9 +94,6 @@ class Search extends BaseComponent { this.onSuggestionsFetchRequested({ value }); // re-render search results immediately based on latest input value }; - // External Redux store not yet in use - _stateChanged(state) {} - toggleSearch() { if (!this.state.isOpen) { this.openSearch(); @@ -215,14 +221,7 @@ class Search extends BaseComponent { const patternName = urlHandler.getFileName(newValue); if (patternName) { - const obj = JSON.stringify({ - event: 'patternLab.updatePath', - path: patternName, - }); - - document - .querySelector('.pl-js-iframe') - .contentWindow.postMessage(obj, urlHandler.targetOrigin); + document.querySelector('pl-iframe').navigateTo(newValue); } this.setState({ @@ -339,16 +338,18 @@ class Search extends BaseComponent { }; return ( - +
      + +
      ); } } diff --git a/packages/uikit-workshop/src/scripts/components/pl-search/pl-search.scss b/packages/uikit-workshop/src/scripts/components/pl-search/pl-search.scss old mode 100644 new mode 100755 index 94e6d3a4e..eda029dd0 --- a/packages/uikit-workshop/src/scripts/components/pl-search/pl-search.scss +++ b/packages/uikit-workshop/src/scripts/components/pl-search/pl-search.scss @@ -13,24 +13,25 @@ $pl-clear-button-size-at-med: 1.4rem; pl-search { background-color: inherit; - order: 2; // Display after nav list items top: 0; z-index: 10; flex-shrink: 0; - padding: 0.3rem 0.5rem; + padding: 0.4rem 0.5rem; display: inline-block; - + align-self: stretch; + @media screen and (min-width: $pl-bp-med) { margin-left: 1rem; flex-direction: row; flex-shrink: 1; + order: 2; // Display after nav list items on wider screens + align-self: center; .pl-c-body--theme-sidebar & { flex-direction: column; margin-left: 0; - padding-left: 0; - padding-right: 0; width: 100%; + padding-top: 1rem; } } } @@ -73,15 +74,17 @@ pl-search { .pl-c-typeahead__hint, .pl-c-typeahead__input { text-transform: capitalize; - background-color: $pl-color-gray-87; - color: $pl-color-white; - border-color: darken($pl-color-gray-87, 10%); + background-color: $pl-color-gray-87; // CSS vars fallback + color: $pl-color-white; // CSS vars fallback + background-color: rgba(var(--theme-text-rgb), 0.1); + color: rgba(var(--theme-text-rgb), 0.67); + border-color: rgba(0, 0, 0, .1); text-overflow: ellipsis; border-width: 1px; border-style: solid; transition: all 0.1s ease; max-width: 100%; - padding: 0.31rem 0.5rem; + padding: 0.4rem 0.5rem; font-size: 16px; // prevent zooming in on mobile width: 100%; outline-offset: -3px; @@ -111,16 +114,16 @@ pl-search { } @media all and (min-width: $pl-bp-med) { - .pl-c-body--theme-sidebar & { max-width: none; } } .pl-c-body--theme-light & { - background-color: $pl-color-gray-07; - color: $pl-color-gray-70 !important; - border-color: $pl-color-gray-13 !important; + background-color: $pl-color-gray-07; // CSS vars fallback + background-color: rgba(var(--theme-text-rgb), 0.1); + color: $pl-color-gray-70; // CSS vars fallback + color: rgba(var(--theme-text-rgb), 0.67); } &::-webkit-input-placeholder, @@ -132,12 +135,9 @@ pl-search { &:hover, &:focus { color: $pl-color-white; - background-color: darken($pl-color-gray-87, 2%) !important; .pl-c-body--theme-light & { - color: $pl-color-gray-87 !important; - background-color: $pl-color-gray-13 !important; - border-color: $pl-color-gray-20 !important; + color: $pl-color-gray-87 !important; // @todo: are these !importants still needed? } &::-moz-input-placeholder, @@ -154,6 +154,8 @@ pl-search { .pl-c-typeahead__menu { @include accordionPanel; background-color: $pl-color-gray-87; + background-color: var(--theme-primary); + color: var(--theme-text); text-transform: capitalize; position: absolute; min-width: 100%; @@ -229,14 +231,20 @@ pl-search { .pl-c-typeahead__result { transition: all 0.3s ease; background-color: inherit; - padding: 0.8em; + padding: 0.5rem 0.75rem; cursor: pointer; overflow: hidden; + font-size: 0.8rem; + color: inherit; &:last-child { border-bottom-right-radius: $pl-border-radius-med; border-bottom-left-radius: $pl-border-radius-med; + @media all and (max-width: $pl-bp-med - 1) { + border-radius: 0; + } + .pl-c-body--theme-sidebar & { border-radius: 0; } @@ -272,6 +280,7 @@ pl-search { .pl-c-typeahead__input-wrapper { position: relative; // used for positioning search clear button in relation to the + flex-shrink: 0; } .pl-c-typeahead__clear-button { diff --git a/packages/uikit-workshop/src/scripts/components/pl-toggle-info/pl-toggle-info.js b/packages/uikit-workshop/src/scripts/components/pl-toggle-info/pl-toggle-info.js new file mode 100755 index 000000000..ff65501ed --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-toggle-info/pl-toggle-info.js @@ -0,0 +1,52 @@ +import { define, props } from 'skatejs'; +import { h } from 'preact'; + +import ShowIcon from '../../../icons/show.svg'; +import HideIcon from '../../../icons/hide.svg'; + +import { store } from '../../store.js'; // connect to the Redux store. +import { updateDrawerState } from '../../actions/app.js'; // redux actions +import { BaseComponent } from '../base-component.js'; + +@define +class InfoToggle extends BaseComponent { + static is = 'pl-toggle-info'; + + constructor(self) { + self = super(self); + return self; + } + + static props = { + _drawerOpened: props.boolean, + }; + + _stateChanged(state) { + this._drawerOpened = state.app.drawerOpened; + this.isViewallPage = state.app.isViewallPage; + } + + render({ _drawerOpened, isViewallPage }) { + return ( + + ); + } +} + +export { InfoToggle }; diff --git a/packages/uikit-workshop/src/scripts/components/pl-toggle-info/pl-toggle-info.scss b/packages/uikit-workshop/src/scripts/components/pl-toggle-info/pl-toggle-info.scss new file mode 100644 index 000000000..25425d04a --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-toggle-info/pl-toggle-info.scss @@ -0,0 +1,16 @@ +@import '../../../sass/scss/core.scss'; + +pl-toggle-info { + display: flex; + align-self: center; + justify-content: center; + align-items: center; + z-index: 10; + width: 100%; + cursor: pointer; +} + +.pl-c-toggle-info, +.pl-c-toggle-info__action { + width: 100%; +} \ No newline at end of file diff --git a/packages/uikit-workshop/src/scripts/components/pl-toggle-layout/pl-toggle-layout.js b/packages/uikit-workshop/src/scripts/components/pl-toggle-layout/pl-toggle-layout.js old mode 100644 new mode 100755 index 5c32b282b..bcc33cd00 --- a/packages/uikit-workshop/src/scripts/components/pl-toggle-layout/pl-toggle-layout.js +++ b/packages/uikit-workshop/src/scripts/components/pl-toggle-layout/pl-toggle-layout.js @@ -5,16 +5,13 @@ import { store } from '../../store.js'; // connect to the Redux store. import { updateLayoutMode } from '../../actions/app.js'; // redux actions import { BaseComponent } from '../base-component.js'; -import './pl-toggle-layout.scss?external'; -import styles from './pl-toggle-layout.scss'; - @define class LayoutToggle extends BaseComponent { static is = 'pl-toggle-layout'; constructor(self) { self = super(self); - this.useShadow = false; + self.useShadow = false; return self; } @@ -30,17 +27,16 @@ class LayoutToggle extends BaseComponent { }; _stateChanged(state) { - if (this.layoutMode !== state.app.layoutMode) { - this.layoutMode = state.app.layoutMode; - } + this.layoutMode = state.app.layoutMode; + this.triggerUpdate(); } render({ layoutMode, text }) { const toggleLayoutMode = layoutMode !== 'vertical' ? 'vertical' : 'horizontal'; + return (
      - {this._renderStyles([styles])} + +
      + ); + } +} diff --git a/packages/uikit-workshop/src/scripts/components/pl-tools-menu/pl-tools-menu.scss b/packages/uikit-workshop/src/scripts/components/pl-tools-menu/pl-tools-menu.scss new file mode 100755 index 000000000..b152ed94d --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-tools-menu/pl-tools-menu.scss @@ -0,0 +1,163 @@ +/*------------------------------------*\ + #TOOLS +\*------------------------------------*/ + +// vertical align in container +pl-tools-menu { + display: flex; + flex-direction: column; + justify-content: center; +} + +/** + * The tools dropdown contains more utilities such as show/hide + * pattern info and pattern search, and also links to open in a + * new window and view the documentation + */ +.pl-c-tools { + position: relative; + display: flex; +} + +/** + * Tools menu button + * 1) This is the button that contains the toggle and + * triggers the tools dropdown list + */ +.pl-c-tools__toggle { + @include linkStyle(); + margin: 0; + display: inline-flex; + align-items: center; + justify-content: center; + position: relative; + min-width: 30px; +} + +/** + * Tools Toggle SVG icon + * 1) Cog icon + * 2) Set the width and height of the icon to be the same height of font + */ +.pl-c-tools__toggle-icon { + transition: inherit; // inherit transition styles from parent toggle + // pointer-events: none; +} + +/** + * Tools dropdown list + */ +.pl-c-tools__list { + @include listReset(); + @include accordionPanel(); + transform: translateY(-10px); + position: absolute; + right: 3px; + z-index: 10; // make sure context dropdown z-index is higher than nav dropdown z-index + width: 12rem; + border-radius: 6px; + top: calc(100% + 4px); + box-shadow: 0 0 5px rgba(0, 0, 0, .1); + background-color: $pl-color-gray-87; + background-color: var(--theme-primary, $pl-color-gray-87); + + .pl-c-body--theme-light & { + background-color: $pl-color-white; + background-color: var(--theme-primary, $pl-color-white); + } + + .pl-c-body--theme-sidebar & { + @media all and (min-width: $pl-bp-med) { + box-shadow: none; + top: 0; + transform: none; + border-radius: 0; + background-color: transparent; + } + } + + &.pl-is-active { + overflow: visible; + } + + &:before { + content: ''; + height: 14px; + width: 14px; + background-color: $pl-color-gray-87; + background-color: var(--theme-primary, $pl-color-gray-87); + position: absolute; + right: 0px; + top: -10px; + transform: translateY(50%) translateX(-50%) rotate(45deg); + transition: opacity 0.1s ease-out; + opacity: 0; + visibility: hidden; + box-shadow: 0 0 5px rgba(0, 0, 0, .1); + + .pl-c-body--theme-sidebar & { + @media all and (min-width: $pl-bp-med) { + display: none; + } + } + } + + &.pl-is-active:before { + opacity: 1; + visibility: visible; + } +} + +.pl-c-tools__item { + position: relative; + overflow: hidden; + + // crop list item when hover + &:first-child { + border-top-left-radius: 6px; + border-top-right-radius: 6px; + + .pl-c-body--theme-sidebar & { + @media all and (min-width: $pl-bp-med) { + border-radius: 0; + } + } + } + + &:last-child { + border-bottom-left-radius: 6px; + border-bottom-right-radius: 6px; + + .pl-c-body--theme-sidebar & { + @media all and (min-width: $pl-bp-med) { + border-radius: 0; + } + } + } +} + + +/** + * Tools dropdown actions + * 1) Links and buttons inside of the tools dropdown + */ +.pl-c-tools__action { + @include linkStyle(); + padding-top: 0.4rem; + padding-bottom: 0.4rem; + display: flex; + align-items: center; + width: 100%; + margin: 0; + flex-direction: row-reverse; + justify-content: flex-end; +} + +// Make sure the text and icon align to the opposite ends +.pl-c-tools__action-icon { + margin-right: 0.5rem; + + &:first-child:last-child { + margin-right: 0; + } +} diff --git a/packages/uikit-workshop/src/scripts/components/pl-tooltip/pl-tooltip.js b/packages/uikit-workshop/src/scripts/components/pl-tooltip/pl-tooltip.js new file mode 100755 index 000000000..f785df5b1 --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-tooltip/pl-tooltip.js @@ -0,0 +1,38 @@ +import TooltipTrigger from 'react-popper-tooltip'; +import { h } from 'preact'; +import 'react-popper-tooltip/dist/styles.css'; + +export const Tooltip = function({ tooltip, children, hideArrow, ...props }) { + return ( + ( +
      + {!hideArrow && ( +
      + )} + {tooltip} +
      + )} + > + {children} + + ); +}; diff --git a/packages/uikit-workshop/src/scripts/components/pl-tooltip/pl-tooltip.scss b/packages/uikit-workshop/src/scripts/components/pl-tooltip/pl-tooltip.scss new file mode 100755 index 000000000..b1ec2906b --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-tooltip/pl-tooltip.scss @@ -0,0 +1,5 @@ +@import '../../../sass/scss/core.scss'; + +.tooltip-container { + color: $pl-color-gray-87; +} \ No newline at end of file diff --git a/packages/uikit-workshop/src/scripts/components/pl-viewport-size-list/pl-viewport-size-list.js b/packages/uikit-workshop/src/scripts/components/pl-viewport-size-list/pl-viewport-size-list.js new file mode 100755 index 000000000..2e33e9ab2 --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-viewport-size-list/pl-viewport-size-list.js @@ -0,0 +1,289 @@ +import { h } from 'preact'; +import { define, props } from 'skatejs'; +import { BaseComponent } from '../base-component.js'; +import { store } from '../../store.js'; // connect to redux + +import { Tooltip } from '../pl-tooltip/pl-tooltip'; +import VisuallyHidden from '@reach/visually-hidden'; + +import PhoneIcon from '../../../icons/phone.svg'; +import TabletIcon from '../../../icons/tablet.svg'; +import LaptopIcon from '../../../icons/laptop.svg'; +import DesktopIcon from '../../../icons/desktop.svg'; +import DiscoIcon from '../../../icons/disco-ball.svg'; +import RandomIcon from '../../../icons/random.svg'; + +import { minViewportWidth, maxViewportWidth, getRandom } from '../../utils'; + +// @todo: re-add keyboard shortcuts to these +@define +class ViewportSizes extends BaseComponent { + static is = 'pl-viewport-sizes'; + + _stateChanged(state) { + this.triggerUpdate(); + } + + constructor(self) { + self = super(self); + self.resizeViewport = self.resizeViewport.bind(self); + self.useShadow = false; + return self; + } + + connecting() { + const state = store.getState(); + const { ishControlsHide } = window.ishControls; + this.ishControlsHide = ishControlsHide; + } + + shouldUpdate(prevProps, prevState) { + return true; + } + + resizeViewport(size) { + if (this.iframe) { + switch (size) { + case 'small': + this.iframe.fullMode = false; + this.iframe.sizeiframe( + getRandom( + minViewportWidth, + window.config.ishViewportRange !== undefined + ? parseInt(window.config.ishViewportRange.s[1], 10) + : 500 + ), + true + ); + break; + case 'medium': + this.iframe.fullMode = false; + this.iframe.sizeiframe( + getRandom( + window.config.ishViewportRange !== undefined + ? parseInt(window.config.ishViewportRange.m[0], 10) + : 500, + window.config.ishViewportRange !== undefined + ? parseInt(window.config.ishViewportRange.m[1], 10) + : 800 + ), + true + ); + break; + case 'large': + this.iframe.fullMode = false; + this.iframe.sizeiframe( + getRandom( + window.config.ishViewportRange !== undefined + ? parseInt(window.config.ishViewportRange.l[0], 10) + : 800, + maxViewportWidth + ), + true + ); + break; + case 'full': + this.iframe.fullMode = true; + this.iframe.sizeiframe(maxViewportWidth, true); + break; + } + } + } + + rendered() { + this.iframe = document.querySelector('pl-iframe'); + } + + render() { + return ( +
        + {!this.ishControlsHide.s && ( +
      • + + {({ getTriggerProps, triggerRef }) => ( + + )} + +
      • + )} + {!this.ishControlsHide.m && ( +
      • + + {({ getTriggerProps, triggerRef }) => ( + + )} + +
      • + )} + {!this.ishControlsHide.l && ( +
      • + + {({ getTriggerProps, triggerRef }) => ( + + )} + +
      • + )} + {!this.ishControlsHide.full && ( +
      • + + {({ getTriggerProps, triggerRef }) => ( + + )} + +
      • + )} + {/* need to add random resize handler before re-enabling */} + {/* {!this.ishControlsHide.random && ( +
      • + + {({ getTriggerProps, triggerRef }) => ( + + )} + +
      • + )} */} + {/* need to add disco handler to resize logic before re-enabling */} + {/* {!this.ishControlsHide.disco && ( +
      • + + {({ getTriggerProps, triggerRef }) => ( + + )} + +
      • + )} */} + {!this.ishControlsHide.hay && ( +
      • + +
      • + )} +
      + ); + } +} diff --git a/packages/uikit-workshop/src/scripts/components/pl-viewport-size-list/pl-viewport-size-list.scss b/packages/uikit-workshop/src/scripts/components/pl-viewport-size-list/pl-viewport-size-list.scss new file mode 100755 index 000000000..e3020046d --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-viewport-size-list/pl-viewport-size-list.scss @@ -0,0 +1,50 @@ +/** + * Size options + * 1) This holds the S, M, L, Rand, Disco links + * 2) Depending on the config, these number of options may be + * larger or smaller. + */ +.pl-c-size-list { + display: none; + list-style: none; + margin: 0; + padding: 0; + overflow-x: auto; + padding: 0 0.25rem; + + .pl-c-body--theme-sidebar & { + @media all and (min-width: $pl-bp-med) { + padding-bottom: 0.5rem; + } + } + + @media all and (min-width: $pl-bp-med) { + align-items: center; + -webkit-overflow-scrolling: touch; + + } + + @media all and (min-width: $pl-bp-med) { + display: block; + display: flex; + } +} + +/** + * Size actions + * 1) These are the buttons that control the viewport resizing + */ +.pl-c-size-list__action { + @include linkStyle(); + padding-left: 0.3rem; + padding-right: 0.3rem; +} + +// Force list items to center align if not overflow scrolling +.pl-c-size-list__item:first-child { + margin-left: auto; +} + +.pl-c-size-list__item:last-child { + margin-right: auto; +} \ No newline at end of file diff --git a/packages/uikit-workshop/src/scripts/components/pl-viewport-size/pl-viewport-size.js b/packages/uikit-workshop/src/scripts/components/pl-viewport-size/pl-viewport-size.js new file mode 100755 index 000000000..bfc305038 --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-viewport-size/pl-viewport-size.js @@ -0,0 +1,28 @@ +import { h } from 'preact'; + +export const ViewportSize = props => { + return ( +
      + + + + +
      + ); +}; diff --git a/packages/uikit-workshop/src/scripts/components/pl-viewport-size/pl-viewport-size.scss b/packages/uikit-workshop/src/scripts/components/pl-viewport-size/pl-viewport-size.scss new file mode 100755 index 000000000..6671035b9 --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-viewport-size/pl-viewport-size.scss @@ -0,0 +1,66 @@ +/*------------------------------------*\ + #ISH SIZING +\*------------------------------------*/ + +/** + * Viewport size form + * 1) This is the form for the form that houses the current + * viewport size in px and em + */ +.pl-c-viewport-size { + margin: 0; + border: 0; + padding: 0.3rem 0.5rem 0.4rem; + line-height: 1; + display: flex; + align-items: center; + flex-shrink: 0; + justify-content: center; +} + +/** + * Size input fields + */ +.pl-c-viewport-size__input { + padding: 0.1rem; + margin: 0; + border: 0; + border-radius: $pl-border-radius; + background-color: transparent; + font-size: 0.8rem; + color: inherit; + width: 2.4rem; + text-align: right; + transition: all $pl-animate-quick ease-out; + pointer-events: none; + + &::-moz-focus-inner { + padding: 0; + border: 0; + } + + &:hover { + color: $pl-color-white; + background-color: $pl-color-gray-87; + } + + &:active, + &:focus { + color: $pl-color-white; + background-color: $pl-color-gray-87; + outline: 1px dotted $pl-color-gray-50; + outline-offset: -1px; + } +} + +/** + * Size input labels + */ +.pl-c-viewport-size__label { + display: block; + margin: 0; + padding: 0; + font-size: 0.7rem; + pointer-events: none; +} + diff --git a/packages/uikit-workshop/src/scripts/components/pl-viewport/pl-viewport.js b/packages/uikit-workshop/src/scripts/components/pl-viewport/pl-viewport.js new file mode 100755 index 000000000..ce1996e03 --- /dev/null +++ b/packages/uikit-workshop/src/scripts/components/pl-viewport/pl-viewport.js @@ -0,0 +1,488 @@ +import { define, props } from 'skatejs'; +import { h } from 'preact'; +import URLSearchParams from '@ungap/url-search-params'; // URLSearchParams poly for older browsers +import render from 'preact-render-to-string'; + +import { store } from '../../store.js'; // connect to redux +import { updateCurrentPattern, updateCurrentUrl } from '../../actions/app.js'; // redux actions +import { updateViewportPx, updateViewportEm } from '../../actions/app.js'; // redux actions needed +import { minViewportWidth, maxViewportWidth } from '../../utils'; +import { BaseComponent } from '../base-component.js'; +import { urlHandler, patternName } from '../../utils'; + +import styles from '../../../sass/pattern-lab--iframe-loader.scss'; + +let trackingPageChange = false; + +@define +class IFrame extends BaseComponent { + static is = 'pl-iframe'; + + constructor(self) { + self = super(self); + self.useShadow = false; + self.usingBrowserNav = true; + self._hasInitiallyRendered = false; + self.fullMode = true; + self.viewportResizeHandleWidth = 14; //Width of the viewport drag-to-resize handle + self.bodySize = + window.config.ishFontSize !== undefined + ? parseInt(window.config.ishFontSize, 10) + : parseInt( + window + .getComputedStyle(document.body, null) + .getPropertyValue('font-size'), + 10 + ); //Body size of the document + self.handlePageChange = self.handlePageChange.bind(self); + self.handlePageLoad = self.handlePageLoad.bind(self); + // self.receiveIframeMessage = self.receiveIframeMessage.bind(self); + self.handleResize = self.handleResize.bind(self); + self.handleMouseDown = self.handleMouseDown.bind(self); + self.handleIframeLoaded = self.handleIframeLoaded.bind(self); + //set up the default for the + self.baseIframePath = + window.location.protocol + + '//' + + window.location.host + + window.location.pathname.replace('index.html', ''); + self.defaultIframePath = self.baseIframePath + '?p=components-overview'; + return self; + } + + // update the currently active nav + add / update the page's query string + handlePageLoad(e) { + var queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + let patternParam = urlParams.get('p'); + + if (e.detail.pattern) { + document.title = 'Pattern Lab - ' + e.detail.pattern; + + const addressReplacement = + window.location.protocol === 'file:' + ? null + : window.location.protocol + + '//' + + window.location.host + + window.location.pathname.replace('index.html', '') + + '?p=' + + e.detail.pattern; + + // first time hitting a PL page -- no query string on the current page + if (patternParam === null) { + window.history.replaceState( + { + currentPattern: e.detail.pattern, + }, + null, + addressReplacement + ); + } else { + window.history.replaceState( + { + currentPattern: e.detail.pattern, + }, + null, + addressReplacement + ); + } + + const currentUrl = urlHandler.getFileName(e.detail.pattern); + + // don't update state or upddate the URL for non-existent patterns + if (currentUrl) { + store.dispatch(updateCurrentPattern(e.detail.pattern)); + store.dispatch(updateCurrentUrl(currentUrl)); + } + } + } + + // navigate to the new PL page (based on the query string) when the page's pop state changes + handlePageChange(e) { + var queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + let patternParam = urlParams.get('p'); + + if (patternParam) { + this.navigateTo(patternParam); + } + } + + connected() { + const self = this; + + if (trackingPageChange === false) { + trackingPageChange = true; + document.addEventListener('patternPartial', self.handlePageLoad); + window.addEventListener('popstate', self.handlePageChange); + } + + const state = store.getState(); + this.themeMode = state.app.themeMode || 'dark'; + this.isViewallPage = state.app.isViewallPage || false; + this.currentPattern = state.app.currentPattern || ''; + + if (state.app.viewportPx) { + this.sizeiframe(state.app.viewportPx, false); + } + + // window.addEventListener('message', this.receiveIframeMessage, false); + window.addEventListener('resize', this.handleResize); + this.handleOrientationChange(); + } + + //Resize the viewport + //'size' is the target size of the viewport + //'animate' is a boolean for switching the CSS animation on or off. 'animate' is true by default, but can be set to false for things like nudging and dragging + sizeiframe(size, animate) { + let theSize; + const self = this; + + // @todo: refactor to better handle the iframe async rendering + if (this.iframe) { + if (animate === true) { + this.iframeContainer.classList.add('vp-animate'); + this.iframe.classList.add('vp-animate'); + } + + if (size > maxViewportWidth) { + //If the entered size is larger than the max allowed viewport size, cap value at max vp size + theSize = maxViewportWidth; + } else if (size < minViewportWidth) { + //If the entered size is less than the minimum allowed viewport size, cap value at min vp size + theSize = minViewportWidth; + } else { + theSize = size; + } + + // resize viewport wrapper to desired size + size of drag resize handler + this.iframeContainer.style.width = + theSize + this.viewportResizeHandleWidth + 'px'; + // this.iframe.style.width = theSize + 'px'; // resize viewport to desired size + + // auto-remove transition classes if not the animate param isn't set to true + setTimeout(function() { + if (animate === true) { + self.iframeContainer.classList.remove('vp-animate'); + self.iframe.classList.remove('vp-animate'); + } + }, 800); + + const targetOrigin = + window.location.protocol === 'file:' + ? '*' + : window.location.protocol + '//' + window.location.host; + + const obj = JSON.stringify({ + event: 'patternLab.resize', + resize: 'true', + }); + + // only tell the iframe to resize when it's ready + if (this._hasInitiallyRendered) { + this.iframe.contentWindow.postMessage(obj, targetOrigin); + } + + this.updateSizeReading(theSize); // update the displayed values in the toolbar + } + } + + handleOrientationChange() { + // Listen for resize changes + const self = this; + if (window.orientation !== undefined) { + this.origOrientation = window.orientation; + window.addEventListener( + 'orientationchange', + function() { + if (window.orientation !== this.origOrientation) { + let newWidth = window.innerWidth; + self.iframeContainer.style.width = newWidth; + self.iframe.style.width = newWidth; + self.updateSizeReading(newWidth); + this.origOrientation = window.orientation; + } + }, + false + ); + } + } + + handleResize() { + this.updateSizeReading(this.iframe.clientWidth); + } + + // Update Pixel and Em inputs + // 'size' is the input number + // 'unit' is the type of unit: either px or em. Default is px. + // Accepted values are 'px' and 'em' + // 'target' is what inputs to update. Defaults to both + updateSizeReading(size, unit, target) { + let emSize, pxSize; + + if (unit === 'em') { + // if size value is in em units + emSize = size; + pxSize = Math.floor(size * this.bodySize); + } else { + // if value is px or absent + pxSize = size; + emSize = size / this.bodySize; + } + + if (target === 'updatePxInput') { + store.dispatch(updateViewportPx(pxSize)); + } else if (target === 'updateEmInput') { + store.dispatch(updateViewportEm(emSize.toFixed(2))); + } else { + store.dispatch(updateViewportPx(pxSize)); + store.dispatch(updateViewportEm(emSize.toFixed(2))); + } + } + + _stateChanged(state) { + if (this._hasInitiallyRendered) { + if (state.app.viewportPx) { + this.sizeiframe(state.app.viewportPx, false); + } else { + this.sizeiframe(this.iframe.clientWidth, false); + } + } + } + + navigateTo(pattern = patternName, rewrite = false) { + this.usingBrowserNav = false; + const patternPath = urlHandler.getFileName(pattern); + + document.title = 'Pattern Lab - ' + pattern; + + this.iFramePath = + patternPath !== '' + ? this.baseIframePath + patternPath + '?' + Date.now() + : this.defaultIframePath; + + if (rewrite === true) { + window.history.replaceState( + { + pattern, + }, + 'Pattern Lab - ' + pattern, + null + ); + urlHandler.skipBack = false; + } + document + .querySelector('.pl-js-iframe') + .contentWindow.location.replace(this.iFramePath); + this.handleUpdatingCurrentPattern(pattern, false); + } + + handleUpdatingCurrentPattern(currentPattern, usingBrowserNav = true) { + const currentUrl = urlHandler.getFileName(currentPattern); + const previousPattern = this.currentPattern; + + if ( + window.history.state === undefined || + window.history.state === null || + window.history.state.currentPattern !== currentPattern + ) { + const data = { + currentPattern, + }; + + // add to the history + const addressReplacement = + window.location.protocol === 'file:' + ? null + : window.location.protocol + + '//' + + window.location.host + + window.location.pathname.replace('index.html', '') + + '?p=' + + currentPattern; + + if (this.currentPattern !== currentPattern) { + if (window.history.pushState !== undefined) { + window.history.pushState(data, null, addressReplacement); + } + + urlHandler.pushPattern(currentPattern, currentUrl); + + this.currentPattern = currentPattern; + } + + if (usingBrowserNav) { + this.usingBrowserNav = true; + } + } + + store.dispatch(updateCurrentPattern(currentPattern)); + store.dispatch(updateCurrentUrl(currentUrl)); + } + + rendered() { + super.rendered && super.rendered(); + this.iframe = this.querySelector('.pl-js-iframe'); + this.iframeContainer = this.querySelector('.pl-js-vp-iframe-container'); + this.iframeCover = this.querySelector('.pl-js-viewport-cover'); + } + + handleIframeLoaded() { + const self = this; + if (!this._hasInitiallyRendered) { + this._hasInitiallyRendered = true; + this.navigateTo(patternName, true); + } + } + + render() { + // use either the page's query string or the patternPartial data to auto-update the URL + var queryString = window.location.search; + const urlParams = new URLSearchParams(queryString); + let patternParam = urlParams.get('p'); + + if (!patternParam) { + if (window.patternData) { + patternParam = window.patternData.patternPartial; + } else { + patternParam = 'components-overview'; + } + } + + const url = urlHandler.getFileName(patternParam); + + const IframeInner = () => { + return ( +
      + +
      +
      +
      Loading Pattern Lab
      +
      + + + + + +
      +
      +
      +
      + ); + }; + + const initialWidth = store.getState().app.viewportPx + ? store.getState().app.viewportPx + 'px;' + : '100%;'; + + return ( +
      +
      +
      +