commit 9a13ccbd1753679f6b4b817afe11e1b238eaae71 Author: Elex Date: Sun Feb 26 01:30:37 2023 +0900 2023-02-26 01:30 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2a05e88 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/node_modules/ +/**/node_modules/ +/build/ +/**/build/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9b6b2a4 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# JS Examples \ No newline at end of file diff --git a/console-io/console-io.js b/console-io/console-io.js new file mode 100644 index 0000000..4133e11 --- /dev/null +++ b/console-io/console-io.js @@ -0,0 +1,12 @@ + +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}); + +readline.question('What do you think of Node.js? ', (answer) => { + // TODO: Log the answer in a database + console.log(`Thank you for your valuable feedback: ${answer}`); + + readline.close(); +}); \ No newline at end of file diff --git a/console-io/package.json b/console-io/package.json new file mode 100644 index 0000000..2c0a364 --- /dev/null +++ b/console-io/package.json @@ -0,0 +1,11 @@ +{ + "name": "console-io", + "version": "1.0.0", + "description": "", + "main": "console-io.js", + "scripts": { + "exec": "node console-io.js" + }, + "author": "", + "license": "ISC" +} \ No newline at end of file diff --git a/gepetto/.gitignore b/gepetto/.gitignore new file mode 100644 index 0000000..30bc162 --- /dev/null +++ b/gepetto/.gitignore @@ -0,0 +1 @@ +/node_modules \ No newline at end of file diff --git a/gepetto/index.html b/gepetto/index.html new file mode 100644 index 0000000..0fe65f2 --- /dev/null +++ b/gepetto/index.html @@ -0,0 +1,30 @@ + + + + + + + Test + + + + + + +
+ Hehehe +
+

jkjk

+
+ + + + \ No newline at end of file diff --git a/gepetto/main.js b/gepetto/main.js new file mode 100644 index 0000000..0654fd6 --- /dev/null +++ b/gepetto/main.js @@ -0,0 +1,56 @@ +const { app, BrowserWindow, Menu, MenuItem } = require('electron'); + +function createWindow() { + let win = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + nodeIntegration: true + } + }); + + createMenu(); + + win.loadFile('index.html'); + + win.webContents.openDevTools(); + +} + +function createMenu() { + const menu = [ + { + label: 'File', + submenu: [ + { label: 'Exit', role: 'quit' } + ] + }, + { + label: 'Edit', + submenu: [ + { label: 'Copy', role: 'copy' }, + { label: 'Cut', role: 'cut' }, + { label: 'Paste', role: 'paste' }, + { type: 'separator' }, + { label: 'Undo', role: 'undo' }, + { label: 'Redo', role: 'redo' }, + ] + } + ]; + + Menu.setApplicationMenu(Menu.buildFromTemplate(menu)); +} + +app.whenReady().then(createWindow); + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit(); + } +}); + +app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow(); + } +}); \ No newline at end of file diff --git a/gepetto/package.json b/gepetto/package.json new file mode 100644 index 0000000..e7d9e05 --- /dev/null +++ b/gepetto/package.json @@ -0,0 +1,30 @@ +{ + "name": "gepetto", + "version": "1.0.0", + "description": "", + "main": "main.js", + "scripts": { + "start": "electron .", + "clean": "rm -r ./build/*", + "build": "webpack", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "Elex", + "license": "ELEX", + "devDependencies": { + "@babel/core": "^7.9.0", + "@babel/plugin-proposal-class-properties": "^7.8.3", + "@babel/plugin-proposal-decorators": "^7.8.3", + "@babel/preset-env": "^7.9.5", + "@babel/preset-typescript": "^7.9.0", + "babel-loader": "^8.1.0", + "electron": "^8.2.3", + "webpack": "^4.43.0", + "webpack-cli": "^3.3.11" + }, + "dependencies": { + "electron": "^8.2.3", + "lit-element": "^2.3.1" + } +} \ No newline at end of file diff --git a/gepetto/src/App.ts b/gepetto/src/App.ts new file mode 100644 index 0000000..03fed8c --- /dev/null +++ b/gepetto/src/App.ts @@ -0,0 +1,6 @@ +const Toolbar = require('./Toolbar.ts') +const AppLayout = require('./AppLayout.ts') + +module.exports = { + Toolbar, AppLayout +}; diff --git a/gepetto/src/AppLayout.ts b/gepetto/src/AppLayout.ts new file mode 100644 index 0000000..c7c3a44 --- /dev/null +++ b/gepetto/src/AppLayout.ts @@ -0,0 +1,30 @@ +import { LitElement, html, css } from 'lit-element'; + +export class AppLayout extends LitElement { + + static get styles() { + return css` + #layout { + display: grid; width:100%; height:100%;overflow:hidden; + grid-template-rows: fitContent(64) 1fr fitContent(24); + grid-template-columns: fitContent(180) 1fr fitContent(180); + } + .north {grid-row-start:1; grid-row-end: span 1; background-color: red; + grid-column-start:1; grid-column-end: span 3;} + `; + } + + render() { + return html` +
+
+
+
+
+
+
+ `; + } +} + +customElements.define('elex-layout', AppLayout); \ No newline at end of file diff --git a/gepetto/src/Toolbar.ts b/gepetto/src/Toolbar.ts new file mode 100644 index 0000000..36c1da2 --- /dev/null +++ b/gepetto/src/Toolbar.ts @@ -0,0 +1,23 @@ +import { LitElement, html, css } from 'lit-element'; + +export class Toolbar extends LitElement { + + static get properties() { + return { + title: { type: String } + }; + } + static get styles() { + return css` + div {min-height: 64px;} + h1 {margin:0;padding:0;font-size:2.4rem;} + `; + } + render() { + return html` +

${this.title}

+ `; + } +} + +customElements.define('elex-toolbar', Toolbar); \ No newline at end of file diff --git a/gepetto/tsconfig.json b/gepetto/tsconfig.json new file mode 100644 index 0000000..9de1038 --- /dev/null +++ b/gepetto/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "es2015", + "moduleResolution": "node", + "lib": [ + "es2017", + "dom" + ], + "experimentalDecorators": true + } +} \ No newline at end of file diff --git a/gepetto/webpack.config.js b/gepetto/webpack.config.js new file mode 100644 index 0000000..334b4e8 --- /dev/null +++ b/gepetto/webpack.config.js @@ -0,0 +1,37 @@ +const path = require('path'); +module.exports = { + target: 'electron-renderer', + entry: { + app: './src/App.ts', + }, + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'build') + }, + module: { + rules: [ + { + test: /\.ts$/, + include: '/src', + //exclude: '/node_modules/', + use: { + loader: 'babel-loader', + options: { + presets: ['@babel/preset-typescript'], + plugins: [ + '@babel/plugin-proposal-class-properties', + ['@babel/plugin-proposal-decorators', + { decoratorsBeforeExport: true }], + ] + } + } + } + ] + }, + mode: 'development', + watch: true, + optimization: { + minimize: true, + concatenateModules: true + }, +} \ No newline at end of file diff --git a/getting-chartjs/01_first.html b/getting-chartjs/01_first.html new file mode 100644 index 0000000..11636a2 --- /dev/null +++ b/getting-chartjs/01_first.html @@ -0,0 +1,57 @@ + + + + + + + +
+ +
+ + + + \ No newline at end of file diff --git a/getting-chartjs/package.json b/getting-chartjs/package.json new file mode 100644 index 0000000..151dc3e --- /dev/null +++ b/getting-chartjs/package.json @@ -0,0 +1,16 @@ +{ + "name": "getting-chartjs", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "private": true, + "keywords": [], + "author": "Elex", + "license": "ELEX", + "dependencies": { + "chart.js": "^2.9.3" + } +} \ No newline at end of file diff --git a/getting-lit-element/.eslintrc.json b/getting-lit-element/.eslintrc.json new file mode 100644 index 0000000..99885e0 --- /dev/null +++ b/getting-lit-element/.eslintrc.json @@ -0,0 +1,26 @@ +{ + "env": { + "browser": true, + "commonjs": true, + "es6": true, + "node": true, + "shared-node-browser": true + }, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended" + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2015, + "sourceType": "module" + }, + "plugins": [ + "@typescript-eslint" + ], + "rules": {} +} \ No newline at end of file diff --git a/getting-lit-element/.gitignore b/getting-lit-element/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/getting-lit-element/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/getting-lit-element/dist/bundle.js b/getting-lit-element/dist/bundle.js new file mode 100644 index 0000000..4978de0 --- /dev/null +++ b/getting-lit-element/dist/bundle.js @@ -0,0 +1,20 @@ +!function(e){var t={};function n(r){if(t[r])return t[r].exports;var s=t[r]={i:r,l:!1,exports:{}};return e[r].call(s.exports,s,s.exports,n),s.l=!0,s.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)n.d(r,s,function(t){return e[t]}.bind(null,s));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s="./src/index.ts")}({"./node_modules/lit-element/lit-element.js": +/*!**************************************************************!*\ + !*** ./node_modules/lit-element/lit-element.js + 16 modules ***! + \**************************************************************/ +/*! exports provided: defaultConverter, notEqual, UpdatingElement, customElement, property, internalProperty, query, queryAsync, queryAll, eventOptions, queryAssignedNodes, html, svg, TemplateResult, SVGTemplateResult, supportsAdoptingStyleSheets, CSSResult, unsafeCSS, css, LitElement */function(module,__webpack_exports__,__webpack_require__){"use strict";eval("// ESM COMPAT FLAG\n__webpack_require__.r(__webpack_exports__);\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, \"defaultConverter\", function() { return /* reexport */ defaultConverter; });\n__webpack_require__.d(__webpack_exports__, \"notEqual\", function() { return /* reexport */ notEqual; });\n__webpack_require__.d(__webpack_exports__, \"UpdatingElement\", function() { return /* reexport */ UpdatingElement; });\n__webpack_require__.d(__webpack_exports__, \"customElement\", function() { return /* reexport */ customElement; });\n__webpack_require__.d(__webpack_exports__, \"property\", function() { return /* reexport */ property; });\n__webpack_require__.d(__webpack_exports__, \"internalProperty\", function() { return /* reexport */ internalProperty; });\n__webpack_require__.d(__webpack_exports__, \"query\", function() { return /* reexport */ query; });\n__webpack_require__.d(__webpack_exports__, \"queryAsync\", function() { return /* reexport */ queryAsync; });\n__webpack_require__.d(__webpack_exports__, \"queryAll\", function() { return /* reexport */ queryAll; });\n__webpack_require__.d(__webpack_exports__, \"eventOptions\", function() { return /* reexport */ eventOptions; });\n__webpack_require__.d(__webpack_exports__, \"queryAssignedNodes\", function() { return /* reexport */ queryAssignedNodes; });\n__webpack_require__.d(__webpack_exports__, \"html\", function() { return /* reexport */ lit_html_html; });\n__webpack_require__.d(__webpack_exports__, \"svg\", function() { return /* reexport */ svg; });\n__webpack_require__.d(__webpack_exports__, \"TemplateResult\", function() { return /* reexport */ template_result_TemplateResult; });\n__webpack_require__.d(__webpack_exports__, \"SVGTemplateResult\", function() { return /* reexport */ template_result_SVGTemplateResult; });\n__webpack_require__.d(__webpack_exports__, \"supportsAdoptingStyleSheets\", function() { return /* reexport */ supportsAdoptingStyleSheets; });\n__webpack_require__.d(__webpack_exports__, \"CSSResult\", function() { return /* reexport */ CSSResult; });\n__webpack_require__.d(__webpack_exports__, \"unsafeCSS\", function() { return /* reexport */ unsafeCSS; });\n__webpack_require__.d(__webpack_exports__, \"css\", function() { return /* reexport */ css; });\n__webpack_require__.d(__webpack_exports__, \"LitElement\", function() { return /* binding */ lit_element_LitElement; });\n\n// CONCATENATED MODULE: ./node_modules/lit-html/lib/dom.js\n/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * True if the custom elements polyfill is in use.\n */\nconst isCEPolyfill = typeof window !== 'undefined' &&\n window.customElements != null &&\n window.customElements.polyfillWrapFlushCallback !==\n undefined;\n/**\n * Reparents nodes, starting from `start` (inclusive) to `end` (exclusive),\n * into another container (could be the same container), before `before`. If\n * `before` is null, it appends the nodes to the container.\n */\nconst reparentNodes = (container, start, end = null, before = null) => {\n while (start !== end) {\n const n = start.nextSibling;\n container.insertBefore(start, before);\n start = n;\n }\n};\n/**\n * Removes nodes, starting from `start` (inclusive) to `end` (exclusive), from\n * `container`.\n */\nconst removeNodes = (container, start, end = null) => {\n while (start !== end) {\n const n = start.nextSibling;\n container.removeChild(start);\n start = n;\n }\n};\n//# sourceMappingURL=dom.js.map\n// CONCATENATED MODULE: ./node_modules/lit-html/lib/template.js\n/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * An expression marker with embedded unique key to avoid collision with\n * possible text in templates.\n */\nconst marker = `{{lit-${String(Math.random()).slice(2)}}}`;\n/**\n * An expression marker used text-positions, multi-binding attributes, and\n * attributes with markup-like text values.\n */\nconst nodeMarker = `\x3c!--${marker}--\x3e`;\nconst markerRegex = new RegExp(`${marker}|${nodeMarker}`);\n/**\n * Suffix appended to all bound attribute names.\n */\nconst boundAttributeSuffix = '$lit$';\n/**\n * An updatable Template that tracks the location of dynamic parts.\n */\nclass Template {\n constructor(result, element) {\n this.parts = [];\n this.element = element;\n const nodesToRemove = [];\n const stack = [];\n // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null\n const walker = document.createTreeWalker(element.content, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false);\n // Keeps track of the last index associated with a part. We try to delete\n // unnecessary nodes, but we never want to associate two different parts\n // to the same index. They must have a constant node between.\n let lastPartIndex = 0;\n let index = -1;\n let partIndex = 0;\n const { strings, values: { length } } = result;\n while (partIndex < length) {\n const node = walker.nextNode();\n if (node === null) {\n // We've exhausted the content inside a nested template element.\n // Because we still have parts (the outer for-loop), we know:\n // - There is a template in the stack\n // - The walker will find a nextNode outside the template\n walker.currentNode = stack.pop();\n continue;\n }\n index++;\n if (node.nodeType === 1 /* Node.ELEMENT_NODE */) {\n if (node.hasAttributes()) {\n const attributes = node.attributes;\n const { length } = attributes;\n // Per\n // https://developer.mozilla.org/en-US/docs/Web/API/NamedNodeMap,\n // attributes are not guaranteed to be returned in document order.\n // In particular, Edge/IE can return them out of order, so we cannot\n // assume a correspondence between part index and attribute index.\n let count = 0;\n for (let i = 0; i < length; i++) {\n if (endsWith(attributes[i].name, boundAttributeSuffix)) {\n count++;\n }\n }\n while (count-- > 0) {\n // Get the template literal section leading up to the first\n // expression in this attribute\n const stringForPart = strings[partIndex];\n // Find the attribute name\n const name = lastAttributeNameRegex.exec(stringForPart)[2];\n // Find the corresponding attribute\n // All bound attributes have had a suffix added in\n // TemplateResult#getHTML to opt out of special attribute\n // handling. To look up the attribute value we also need to add\n // the suffix.\n const attributeLookupName = name.toLowerCase() + boundAttributeSuffix;\n const attributeValue = node.getAttribute(attributeLookupName);\n node.removeAttribute(attributeLookupName);\n const statics = attributeValue.split(markerRegex);\n this.parts.push({ type: 'attribute', index, name, strings: statics });\n partIndex += statics.length - 1;\n }\n }\n if (node.tagName === 'TEMPLATE') {\n stack.push(node);\n walker.currentNode = node.content;\n }\n }\n else if (node.nodeType === 3 /* Node.TEXT_NODE */) {\n const data = node.data;\n if (data.indexOf(marker) >= 0) {\n const parent = node.parentNode;\n const strings = data.split(markerRegex);\n const lastIndex = strings.length - 1;\n // Generate a new text node for each literal section\n // These nodes are also used as the markers for node parts\n for (let i = 0; i < lastIndex; i++) {\n let insert;\n let s = strings[i];\n if (s === '') {\n insert = createMarker();\n }\n else {\n const match = lastAttributeNameRegex.exec(s);\n if (match !== null && endsWith(match[2], boundAttributeSuffix)) {\n s = s.slice(0, match.index) + match[1] +\n match[2].slice(0, -boundAttributeSuffix.length) + match[3];\n }\n insert = document.createTextNode(s);\n }\n parent.insertBefore(insert, node);\n this.parts.push({ type: 'node', index: ++index });\n }\n // If there's no text, we must insert a comment to mark our place.\n // Else, we can trust it will stick around after cloning.\n if (strings[lastIndex] === '') {\n parent.insertBefore(createMarker(), node);\n nodesToRemove.push(node);\n }\n else {\n node.data = strings[lastIndex];\n }\n // We have a part for each match found\n partIndex += lastIndex;\n }\n }\n else if (node.nodeType === 8 /* Node.COMMENT_NODE */) {\n if (node.data === marker) {\n const parent = node.parentNode;\n // Add a new marker node to be the startNode of the Part if any of\n // the following are true:\n // * We don't have a previousSibling\n // * The previousSibling is already the start of a previous part\n if (node.previousSibling === null || index === lastPartIndex) {\n index++;\n parent.insertBefore(createMarker(), node);\n }\n lastPartIndex = index;\n this.parts.push({ type: 'node', index });\n // If we don't have a nextSibling, keep this node so we have an end.\n // Else, we can remove it to save future costs.\n if (node.nextSibling === null) {\n node.data = '';\n }\n else {\n nodesToRemove.push(node);\n index--;\n }\n partIndex++;\n }\n else {\n let i = -1;\n while ((i = node.data.indexOf(marker, i + 1)) !== -1) {\n // Comment node has a binding marker inside, make an inactive part\n // The binding won't work, but subsequent bindings will\n // TODO (justinfagnani): consider whether it's even worth it to\n // make bindings in comments work\n this.parts.push({ type: 'node', index: -1 });\n partIndex++;\n }\n }\n }\n }\n // Remove text binding nodes after the walk to not disturb the TreeWalker\n for (const n of nodesToRemove) {\n n.parentNode.removeChild(n);\n }\n }\n}\nconst endsWith = (str, suffix) => {\n const index = str.length - suffix.length;\n return index >= 0 && str.slice(index) === suffix;\n};\nconst isTemplatePartActive = (part) => part.index !== -1;\n// Allows `document.createComment('')` to be renamed for a\n// small manual size-savings.\nconst createMarker = () => document.createComment('');\n/**\n * This regex extracts the attribute name preceding an attribute-position\n * expression. It does this by matching the syntax allowed for attributes\n * against the string literal directly preceding the expression, assuming that\n * the expression is in an attribute-value position.\n *\n * See attributes in the HTML spec:\n * https://www.w3.org/TR/html5/syntax.html#elements-attributes\n *\n * \" \\x09\\x0a\\x0c\\x0d\" are HTML space characters:\n * https://www.w3.org/TR/html5/infrastructure.html#space-characters\n *\n * \"\\0-\\x1F\\x7F-\\x9F\" are Unicode control characters, which includes every\n * space character except \" \".\n *\n * So an attribute is:\n * * The name: any character except a control character, space character, ('),\n * (\"), \">\", \"=\", or \"/\"\n * * Followed by zero or more space characters\n * * Followed by \"=\"\n * * Followed by zero or more space characters\n * * Followed by:\n * * Any character except space, ('), (\"), \"<\", \">\", \"=\", (`), or\n * * (\") then any non-(\"), or\n * * (') then any non-(')\n */\nconst lastAttributeNameRegex = \n// eslint-disable-next-line no-control-regex\n/([ \\x09\\x0a\\x0c\\x0d])([^\\0-\\x1F\\x7F-\\x9F \"'>=/]+)([ \\x09\\x0a\\x0c\\x0d]*=[ \\x09\\x0a\\x0c\\x0d]*(?:[^ \\x09\\x0a\\x0c\\x0d\"'`<>=]*|\"[^\"]*|'[^']*))$/;\n//# sourceMappingURL=template.js.map\n// CONCATENATED MODULE: ./node_modules/lit-html/lib/modify-template.js\n/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * @module shady-render\n */\n\nconst walkerNodeFilter = 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */;\n/**\n * Removes the list of nodes from a Template safely. In addition to removing\n * nodes from the Template, the Template part indices are updated to match\n * the mutated Template DOM.\n *\n * As the template is walked the removal state is tracked and\n * part indices are adjusted as needed.\n *\n * div\n * div#1 (remove) <-- start removing (removing node is div#1)\n * div\n * div#2 (remove) <-- continue removing (removing node is still div#1)\n * div\n * div <-- stop removing since previous sibling is the removing node (div#1,\n * removed 4 nodes)\n */\nfunction removeNodesFromTemplate(template, nodesToRemove) {\n const { element: { content }, parts } = template;\n const walker = document.createTreeWalker(content, walkerNodeFilter, null, false);\n let partIndex = nextActiveIndexInTemplateParts(parts);\n let part = parts[partIndex];\n let nodeIndex = -1;\n let removeCount = 0;\n const nodesToRemoveInTemplate = [];\n let currentRemovingNode = null;\n while (walker.nextNode()) {\n nodeIndex++;\n const node = walker.currentNode;\n // End removal if stepped past the removing node\n if (node.previousSibling === currentRemovingNode) {\n currentRemovingNode = null;\n }\n // A node to remove was found in the template\n if (nodesToRemove.has(node)) {\n nodesToRemoveInTemplate.push(node);\n // Track node we're removing\n if (currentRemovingNode === null) {\n currentRemovingNode = node;\n }\n }\n // When removing, increment count by which to adjust subsequent part indices\n if (currentRemovingNode !== null) {\n removeCount++;\n }\n while (part !== undefined && part.index === nodeIndex) {\n // If part is in a removed node deactivate it by setting index to -1 or\n // adjust the index as needed.\n part.index = currentRemovingNode !== null ? -1 : part.index - removeCount;\n // go to the next active part.\n partIndex = nextActiveIndexInTemplateParts(parts, partIndex);\n part = parts[partIndex];\n }\n }\n nodesToRemoveInTemplate.forEach((n) => n.parentNode.removeChild(n));\n}\nconst countNodes = (node) => {\n let count = (node.nodeType === 11 /* Node.DOCUMENT_FRAGMENT_NODE */) ? 0 : 1;\n const walker = document.createTreeWalker(node, walkerNodeFilter, null, false);\n while (walker.nextNode()) {\n count++;\n }\n return count;\n};\nconst nextActiveIndexInTemplateParts = (parts, startIndex = -1) => {\n for (let i = startIndex + 1; i < parts.length; i++) {\n const part = parts[i];\n if (isTemplatePartActive(part)) {\n return i;\n }\n }\n return -1;\n};\n/**\n * Inserts the given node into the Template, optionally before the given\n * refNode. In addition to inserting the node into the Template, the Template\n * part indices are updated to match the mutated Template DOM.\n */\nfunction insertNodeIntoTemplate(template, node, refNode = null) {\n const { element: { content }, parts } = template;\n // If there's no refNode, then put node at end of template.\n // No part indices need to be shifted in this case.\n if (refNode === null || refNode === undefined) {\n content.appendChild(node);\n return;\n }\n const walker = document.createTreeWalker(content, walkerNodeFilter, null, false);\n let partIndex = nextActiveIndexInTemplateParts(parts);\n let insertCount = 0;\n let walkerIndex = -1;\n while (walker.nextNode()) {\n walkerIndex++;\n const walkerNode = walker.currentNode;\n if (walkerNode === refNode) {\n insertCount = countNodes(node);\n refNode.parentNode.insertBefore(node, refNode);\n }\n while (partIndex !== -1 && parts[partIndex].index === walkerIndex) {\n // If we've inserted the node, simply adjust all subsequent parts\n if (insertCount > 0) {\n while (partIndex !== -1) {\n parts[partIndex].index += insertCount;\n partIndex = nextActiveIndexInTemplateParts(parts, partIndex);\n }\n return;\n }\n partIndex = nextActiveIndexInTemplateParts(parts, partIndex);\n }\n }\n}\n//# sourceMappingURL=modify-template.js.map\n// CONCATENATED MODULE: ./node_modules/lit-html/lib/directive.js\n/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\nconst directives = new WeakMap();\n/**\n * Brands a function as a directive factory function so that lit-html will call\n * the function during template rendering, rather than passing as a value.\n *\n * A _directive_ is a function that takes a Part as an argument. It has the\n * signature: `(part: Part) => void`.\n *\n * A directive _factory_ is a function that takes arguments for data and\n * configuration and returns a directive. Users of directive usually refer to\n * the directive factory as the directive. For example, \"The repeat directive\".\n *\n * Usually a template author will invoke a directive factory in their template\n * with relevant arguments, which will then return a directive function.\n *\n * Here's an example of using the `repeat()` directive factory that takes an\n * array and a function to render an item:\n *\n * ```js\n * html``\n * ```\n *\n * When `repeat` is invoked, it returns a directive function that closes over\n * `items` and the template function. When the outer template is rendered, the\n * return directive function is called with the Part for the expression.\n * `repeat` then performs it's custom logic to render multiple items.\n *\n * @param f The directive factory function. Must be a function that returns a\n * function of the signature `(part: Part) => void`. The returned function will\n * be called with the part object.\n *\n * @example\n *\n * import {directive, html} from 'lit-html';\n *\n * const immutable = directive((v) => (part) => {\n * if (part.value !== v) {\n * part.setValue(v)\n * }\n * });\n */\nconst directive_directive = (f) => ((...args) => {\n const d = f(...args);\n directives.set(d, true);\n return d;\n});\nconst isDirective = (o) => {\n return typeof o === 'function' && directives.has(o);\n};\n//# sourceMappingURL=directive.js.map\n// CONCATENATED MODULE: ./node_modules/lit-html/lib/part.js\n/**\n * @license\n * Copyright (c) 2018 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * A sentinel value that signals that a value was handled by a directive and\n * should not be written to the DOM.\n */\nconst noChange = {};\n/**\n * A sentinel value that signals a NodePart to fully clear its content.\n */\nconst nothing = {};\n//# sourceMappingURL=part.js.map\n// CONCATENATED MODULE: ./node_modules/lit-html/lib/template-instance.js\n/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * @module lit-html\n */\n\n\n/**\n * An instance of a `Template` that can be attached to the DOM and updated\n * with new values.\n */\nclass template_instance_TemplateInstance {\n constructor(template, processor, options) {\n this.__parts = [];\n this.template = template;\n this.processor = processor;\n this.options = options;\n }\n update(values) {\n let i = 0;\n for (const part of this.__parts) {\n if (part !== undefined) {\n part.setValue(values[i]);\n }\n i++;\n }\n for (const part of this.__parts) {\n if (part !== undefined) {\n part.commit();\n }\n }\n }\n _clone() {\n // There are a number of steps in the lifecycle of a template instance's\n // DOM fragment:\n // 1. Clone - create the instance fragment\n // 2. Adopt - adopt into the main document\n // 3. Process - find part markers and create parts\n // 4. Upgrade - upgrade custom elements\n // 5. Update - set node, attribute, property, etc., values\n // 6. Connect - connect to the document. Optional and outside of this\n // method.\n //\n // We have a few constraints on the ordering of these steps:\n // * We need to upgrade before updating, so that property values will pass\n // through any property setters.\n // * We would like to process before upgrading so that we're sure that the\n // cloned fragment is inert and not disturbed by self-modifying DOM.\n // * We want custom elements to upgrade even in disconnected fragments.\n //\n // Given these constraints, with full custom elements support we would\n // prefer the order: Clone, Process, Adopt, Upgrade, Update, Connect\n //\n // But Safari does not implement CustomElementRegistry#upgrade, so we\n // can not implement that order and still have upgrade-before-update and\n // upgrade disconnected fragments. So we instead sacrifice the\n // process-before-upgrade constraint, since in Custom Elements v1 elements\n // must not modify their light DOM in the constructor. We still have issues\n // when co-existing with CEv0 elements like Polymer 1, and with polyfills\n // that don't strictly adhere to the no-modification rule because shadow\n // DOM, which may be created in the constructor, is emulated by being placed\n // in the light DOM.\n //\n // The resulting order is on native is: Clone, Adopt, Upgrade, Process,\n // Update, Connect. document.importNode() performs Clone, Adopt, and Upgrade\n // in one step.\n //\n // The Custom Elements v1 polyfill supports upgrade(), so the order when\n // polyfilled is the more ideal: Clone, Process, Adopt, Upgrade, Update,\n // Connect.\n const fragment = isCEPolyfill ?\n this.template.element.content.cloneNode(true) :\n document.importNode(this.template.element.content, true);\n const stack = [];\n const parts = this.template.parts;\n // Edge needs all 4 parameters present; IE11 needs 3rd parameter to be null\n const walker = document.createTreeWalker(fragment, 133 /* NodeFilter.SHOW_{ELEMENT|COMMENT|TEXT} */, null, false);\n let partIndex = 0;\n let nodeIndex = 0;\n let part;\n let node = walker.nextNode();\n // Loop through all the nodes and parts of a template\n while (partIndex < parts.length) {\n part = parts[partIndex];\n if (!isTemplatePartActive(part)) {\n this.__parts.push(undefined);\n partIndex++;\n continue;\n }\n // Progress the tree walker until we find our next part's node.\n // Note that multiple parts may share the same node (attribute parts\n // on a single element), so this loop may not run at all.\n while (nodeIndex < part.index) {\n nodeIndex++;\n if (node.nodeName === 'TEMPLATE') {\n stack.push(node);\n walker.currentNode = node.content;\n }\n if ((node = walker.nextNode()) === null) {\n // We've exhausted the content inside a nested template element.\n // Because we still have parts (the outer for-loop), we know:\n // - There is a template in the stack\n // - The walker will find a nextNode outside the template\n walker.currentNode = stack.pop();\n node = walker.nextNode();\n }\n }\n // We've arrived at our part's node.\n if (part.type === 'node') {\n const part = this.processor.handleTextExpression(this.options);\n part.insertAfterNode(node.previousSibling);\n this.__parts.push(part);\n }\n else {\n this.__parts.push(...this.processor.handleAttributeExpressions(node, part.name, part.strings, this.options));\n }\n partIndex++;\n }\n if (isCEPolyfill) {\n document.adoptNode(fragment);\n customElements.upgrade(fragment);\n }\n return fragment;\n }\n}\n//# sourceMappingURL=template-instance.js.map\n// CONCATENATED MODULE: ./node_modules/lit-html/lib/template-result.js\n/**\n * @license\n * Copyright (c) 2017 The Polymer Project Authors. All rights reserved.\n * This code may only be used under the BSD style license found at\n * http://polymer.github.io/LICENSE.txt\n * The complete set of authors may be found at\n * http://polymer.github.io/AUTHORS.txt\n * The complete set of contributors may be found at\n * http://polymer.github.io/CONTRIBUTORS.txt\n * Code distributed by Google as part of the polymer project is also\n * subject to an additional IP rights grant found at\n * http://polymer.github.io/PATENTS.txt\n */\n/**\n * @module lit-html\n */\n\n\nconst commentMarker = ` ${marker} `;\n/**\n * The return type of `html`, which holds a Template and the values from\n * interpolated expressions.\n */\nclass template_result_TemplateResult {\n constructor(strings, values, type, processor) {\n this.strings = strings;\n this.values = values;\n this.type = type;\n this.processor = processor;\n }\n /**\n * Returns a string of HTML used to create a `